PDA

Ver la Versión Completa : Como puedo obtener el numero de meses entre 2 fechas en firebird


ElGatitoTapatio
08-01-2007, 19:53:08
Hola a todos, son nuevo en esto de los foros y tambien algo nuevo en firebird, necesito obtener el numero de meses que hay entre dos fecha con un Query y la verdad es que no tengo idea de como hacerlo, alguien me podria ayudar? muchas gracias...

Caral
08-01-2007, 20:45:25
Hola ElGatitoTapatio
La verdad no se con meses, pero asi se pueden calcular los dias entre dos fechas, este lo facilito Al Gonzalez:

procedure TForm1.Button1Click(Sender: TObject);
Var
FechHora1 :TDateTime;
FechHora2 :TDateTime;
Dias :Integer;
begin
FechHora1:= DateTimePicker1.DateTime;
FechHora2:= DateTimePicker2.DateTime;
Dias := Trunc (FechHora2) - Trunc (FechHora1);
Edit1.Text:= IntToStr(Dias);
end;

Tal vez te de una idea.
Saludos

Onti
08-01-2007, 20:50:11
Probaste la función MonthsBetween

ArdiIIa
08-01-2007, 21:31:06
Creo que esta función podría ayudarte


function Get_Meses(DataFim, DataIni: TDate):Integer;
var
DiaF, MesF, AnoF, DiaI, MesI, AnoI: Word;
Dias, Meses, Anos: integer;
begin
DecodeDate( DataIni, AnoI, MesI, DiaI);
DecodeDate( DataFim, AnoF, MesF, DiaF);
Dias:=DiaF - DiaI;
Meses:=MesF - MesI;
Anos:=AnoF - AnoI;
if Dias < 0 then
Dec(Meses);

Result := Meses + (Anos * 12);
end;



La podría implementar utilizando un campo autocalculado, pasándole los valores de las dos fechas.
Otra opción sería implementarla en una UDF...

NOTA: El código de la función no es mio la autoría se puede encontrar aquí (http://www.forumweb.com.br/foruns/index.php?showtopic=47423&pid=198207&mode=threaded&start=#entry198207);

Tú mismo.:D

ContraVeneno
08-01-2007, 23:33:54
http://www.clubdelphi.com/foros/showthread.php?t=39009

rastafarey
09-01-2007, 17:38:00
Con una sentencia sql lo puedes sacar lee la funcion extract y aplicale un poco de logica.

ElGatitoTapatio
09-01-2007, 19:06:16
El problema es hacerlo por medio de SQL, el error lo cometi yo ya que no me explique bien :( , ahi va mi bronca, tengo una tabla donde guardo informacion de muchas personas entre los datos se encuentra la fecha de ingreso. Ahora a partir de esa tabla y otras, genero una nueva donde debe de contener el numero de quincenas que han pasado desde que ingreso al sistema. Esto lo estoy haciendo por medio de un UPDATE y una subconsula a la tabla antes mencionada, pero hasta el momento solo para obtener algunos otros datos (ya que no se como sacar el no. de quincenas por medio de sql). Entoces ya que tengo los datos en la nueva tabla tengo que recorrer uno por uno hacer el calculo de las quincenas por fuera (en delphi) y hacer un update a cada uno para agregarle su no. de quincenas.
Como podran imaginarse tarda un tiempo considerable ya que estoy hablado de cerca de 2000 mil consultas, entonces la pregunta es si hay alguna manera de hacerlo a todos los datos desde un solo query. Chale escribi como cantinflas pero haber si me entienden. :D Agradesco mucho su ayuda.

rastafarey
12-01-2007, 08:03:11
Tomemos estas dos fecha
1ra=01/03/2005
2da=01/01/2007
como la fechas para hacer el calculo(Si te das cuenta estan en formato europeo dia/mes/año)
interbase trata las fecha en otro formato(mes/dia/año)
lo que nos quedaria
1ra=03/01/2005
2da=01/01/2007
y como todos sabes el año tiene 365 dias o 366 si en biciesto
si dividimos 365/12 = 30,416666666666666666666666666667
Pero por precicion no se puede usar con todos esos decimales
entonces usamos 30.41666666666666667
y la instruccion sql quedaria asi


Select cast( (cast( (cast('01/01/2007' As Date) - cast('03/01/2005' As Date)) as Double Precision) / 30.41666666666666667) As integer)
From rdb$database

cast('01/01/2007' As Date) - cast('03/01/2005' As Date))
Esto no es necesario si no usas las fechas como cadenas usalas
cast('01/01/2007' As Date) = 2dafecha
cast('03/01/2005' As Date) = 1rafecha


Por lo del formato de las fechas no debes preocurte amnos que estes pasando las fechas como cadena.
Ya que si la lees de la bse de ya esta como la quieres.

Espero te sirva de ayuda.

Nota: Y por favor si te sirvio responde diciendo que te sirvio.

ElGatitoTapatio
12-01-2007, 16:29:39
gracias por la respuesta, fijate que practicamente no me sirvio el metodo ya que me acabo de dar cuenta que las fechas que esta almacenadas en la base de datos estan de tipo integer, pero con el siguiente formato yyyymmdd (ejemplo, hoy = 20,070,112), es por eso que no pude implementar tu metodo, sin embargo me dio una idea para otra funcion que necesitaba, muchas gracias.

... por cierto alguna idea para la opcion yyyymmdd?? la verdad es que ya lo deje por la paz, pero por si sale alguna otra opcion pues podria sacar una mejora del metodo....

ContraVeneno
12-01-2007, 16:50:42
¿Fechas grabadas como tipo integer? :eek::eek::eek:

Hay muchas formas de manejar las fechas con formato 'yyyymmdd' pero como tipo cadena.... pero como enteros.... :eek::eek:

ElGatitoTapatio
15-01-2007, 17:51:08
Si lamentablemente estoy rediseñando un sistema con una base de datos ya definida y me encontre con esa bronca, pero bueno si veo que va a estar dificil solucionarlo asi que por el momento lo voy a hacer como les habia comentado anteriormente por medio de la interface de delphi y si mas delante consigo alguna forma mejor pues se los informo, muchas gracias. :)

rastafarey
19-01-2007, 19:37:55
Si lo puedes implementar pero al parecer no quieren aprender a preguntar asi que limitare a responder algunas preguntas.

jwmoreira
19-01-2007, 19:38:09
Hola, espero te sirva esto:
Creas un procedimiento al que le envias las dos fechas numericas:

CREATE PROCEDURE SP_RESTA_FECHAS (
AN_FECHA1 INTEGER,
AN_FECHA2 INTEGER)
RETURNS (
NUM_DIAS INTEGER)
AS
declare variable vs_fecha1 varchar(10);
declare variable vs_fecha2 varchar(10);
BEGIN
vs_fecha1 = substring( cast(an_fecha1 as varchar(8)) from 5 for 2) || '/'||
substring( cast(an_fecha1 as varchar(8)) from 7 for 2) || '/'||
substring( cast(an_fecha1 as varchar(8)) from 1 for 4);
vs_fecha2 = substring( cast(an_fecha2 as varchar(8)) from 5 for 2) || '/'||
substring( cast(an_fecha2 as varchar(8)) from 7 for 2) || '/'||
substring( cast(an_fecha2 as varchar(8)) from 1 for 4);
Select cast(:vs_fecha2 As Date) - cast(:vs_fecha1 As Date) From rdb$database Into :NUM_DIAS;
SUSPEND;
END

Luego en el select haces los siguiente:

Código SQL [-] (http://www.clubdelphi.com/foros/#)Select (select NUM_DIAS FROM SP_RESTA_FECHAS(fechaN1,FechaN2) ) From TablaOrigen



Saludos,
Jorge.

jwmoreira
19-01-2007, 20:03:05
Agregue un argumento mas para meses y cambie el procedimiento:
CREATE PROCEDURE SP_RESTA_FECHAS (
AN_FECHA1 INTEGER,
AN_FECHA2 INTEGER,
AV_TIPO CHAR (1) CHARACTER SET WIN1251)
RETURNS (
NUM_DIAS INTEGER)
AS
declare variable vs_fecha1 varchar(10);
declare variable vs_fecha2 varchar(10);
BEGIN
if( av_tipo = 'M' ) then
if (substring( cast(an_fecha1 as varchar(8)) from 1 for 4) =
substring( cast(an_fecha2 as varchar(8)) from 1 for 4)) then
num_dias = cast(substring( cast(an_fecha2 as varchar(8)) from 5 for 2) as integer) -
cast(substring( cast(an_fecha1 as varchar(8)) from 5 for 2) as integer) + 1;
else
num_dias = cast(substring( cast(an_fecha2 as varchar(8)) from 5 for 2) as integer) +
(( cast(substring( cast(an_fecha2 as varchar(8)) from 1 for 4) as integer) -
cast(substring( cast(an_fecha1 as varchar(8)) from 1 for 4) as integer) ) * 12);
else
begin
vs_fecha1 = substring( cast(an_fecha1 as varchar(8)) from 5 for 2) || '/'||
substring( cast(an_fecha1 as varchar(8)) from 7 for 2) || '/'||
substring( cast(an_fecha1 as varchar(8)) from 1 for 4);
vs_fecha2 = substring( cast(an_fecha2 as varchar(8)) from 5 for 2) || '/'||
substring( cast(an_fecha2 as varchar(8)) from 7 for 2) || '/'||
substring( cast(an_fecha2 as varchar(8)) from 1 for 4);
num_dias = cast(:vs_fecha2 As Date) - cast(:vs_fecha1 As Date);
end
SUSPEND;
END


Código SQL [-] (http://www.clubdelphi.com/foros/#)select (select num_dias from RESTA(fecha1,fecha2,tipo) From TablaOrigen



Donde Tipo es M=Meses y por default días.

Espero en algo haberte ayudado,
Jorge.

Lepe
20-01-2007, 10:32:45
Para meses no he encontrado nada, para días tienes una UDF en rFunc (http://rfunc.sourceforge.net/)



Saludos

ElGatitoTapatio
22-01-2007, 16:35:15
Lo voy a implementar y les aviso resultados