Visual Basic Foro
Programación => Bases de Datos => Mensaje iniciado por: E N T E R en Noviembre 24, 2012, 04:47:05 pm
-
Quiero restar 2 fechas entre si y que de como resultado de los años los meses y los días que han transcurrido.
SELECT (YEAR('2015-05-12'))-(YEAR('2012-05-12')) AS AÑO, TIMESTAMPDIFF(MONTH,TIMESTAMP('2015-05-12'),TIMESTAMP('2012-05-12')) AS MESES, DATEDIFF('2015-05-12' , '2012-05-12') AS DIAS
Tengo este SQL pero no tira bien el resultado: Tiene que mostrar como por ejemplo:
Diferencias:
3 Años | 8 Meses | 6 Días
-
SELECT (A.a % 365) % 30 AS 'Dias' ,FLOOR((A.a % 365) / 30) AS 'Meses', FLOOR(A.a / 365) AS 'Años'
FROM (SELECT timestampdiff(DAY, '2012-02-01', '2012-01-02') AS a) AS A;
Igual seria más facil traer el resultado de Timestampdiff y tratarlo en vb o en el lenguaje que estes usando
FLOOR es la funcion de redondear hacia abajo, es para que no redondee 3.8 Años a 4 .... es para que salga bien en 3.8 Años en 3 años 10 meses... por ejemplo (tambien esta en vb)
R = Timestampdif(...)
Años = R / 365
Meses = (R Mod 365) / 30
Dias = (R Mod 365) Mod 30
Si es "hace X tiempo"... saldrá negativo :P
-
Muy bueno Raul, funciona de lujo. No lo hice a traves de Vb por que quiero hacerle trabajar al motor BD lo mas que pueda.
Gracias hermano por tu tiempo, Asunto solucionado.
-
Raul, aparecio un problema que no vi en el momento, que pasa si el año es viciesto. no todos los años trae 365 días y no todos los meses trae 30.
-
Bueno... ahí... se pone más tensa la cosa... tan exacto tiene que ser? x'D
-
Sip. amigo
-
A ver si me corrigen, podrias usar esta funcioncita
Private Function DiasAnno(Ano As Integer) As Integer
If Day(DateSerial(Ano, 3, 0)) = 29 Then
DiasAnno = 366
Else
DiasAnno = 365
End If
End Function
Y los datos para la funcion de Raul:
R = Timestampdif(...)
Año = DiasAnno(Year(Date)) 'O en vez de Date el año que estas evaluando
Años = R / Año
Meses = (R Mod Año) / 30
Dias = (R Mod Año) Mod 30
s.e.u.o.
-
Hola gentes
YAcosta es a nivel de SQL
bueno yo encontré un algoritmo hecho en vb6 en la cual calcula la diferencia entre fecha les dejo aquí el link http://www.lawebdelprogramador.com/codigo/Visual_Basic/1405-Diferencia_entre_fechas.html (http://www.lawebdelprogramador.com/codigo/Visual_Basic/1405-Diferencia_entre_fechas.html)
la cual la procedí a migrar a SQL en el moto de base de datos FirebirdSQL creando un procedimiento almacenado para ayar dicha diferencia entre fechas
les dejo el código SQL
create procedure VER_TIEMPO (
XFECACT date,
XFECNAC date)
returns (
EDAD integer,
MES integer,
DIA integer)
as
declare variable XDIAS integer = 0;
declare variable XMESES integer = 0;
declare variable XANHOS integer = 0;
declare variable XANHOS_ACT integer = 0;
declare variable XANHOS_NAC integer = 0;
declare variable XMESES_ACT integer = 0;
declare variable XMESES_NAC integer = 0;
declare variable XDIAS_ACT integer = 0;
declare variable XDIAS_NAC integer = 0;
BEGIN
XANHOS_ACT = EXTRACT(YEAR FROM XFECACT);
XMESES_ACT = EXTRACT(MONTH FROM XFECACT);
XDIAS_ACT = EXTRACT(DAY FROM XFECACT);
XANHOS_NAC = EXTRACT(YEAR FROM XFECNAC);
XMESES_NAC = EXTRACT(MONTH FROM XFECNAC);
XDIAS_NAC = EXTRACT(DAY FROM XFECNAC);
XANHOS = XANHOS_ACT - XANHOS_NAC;
BEGIN
IF ( XMESES_ACT = XMESES_NAC ) THEN
XMESES = 0;
ELSE IF ( XMESES_ACT > XMESES_NAC ) THEN
XMESES = XMESES_ACT - XMESES_NAC;
ELSE IF ( XMESES_ACT < XMESES_NAC ) THEN
BEGIN
XMESES = 12 + (XMESES_ACT - XMESES_NAC);
XANHOS = XANHOS - 1;
END
END
BEGIN
IF ( XDIAS_ACT >= XDIAS_NAC ) THEN
XDIAS = XDIAS_ACT - XDIAS_NAC;
ELSE IF ( XDIAS_ACT < XDIAS_NAC ) THEN
BEGIN
XMESES = XMESES - 1;
IF ( XMESES < 0 ) THEN
BEGIN
XANHOS = XANHOS - 1;
XMESES = XMESES + 12;
END
IF ( XMESES_NAC = 1 OR XMESES_NAC = 3 OR XMESES_NAC = 5 OR XMESES_NAC = 7 OR XMESES_NAC = 8 OR XMESES_NAC = 10 OR XMESES_NAC = 12 ) THEN
XDIAS =XDIAS_ACT - XDIAS_NAC + 31;
ELSE IF ( XMESES_NAC = 2 ) THEN
BEGIN
XDIAS =XDIAS_ACT - XDIAS_NAC + 28;
IF ( MOD(XANHOS_NAC,4) =0 ) THEN XDIAS = XDIAS + 1;
END
ELSE
XDIAS =XDIAS_ACT - XDIAS_NAC + 30;
END
END
BEGIN
EDAD = XANHOS;
MES = XMESES;
DIA = XDIAS;
END
BEGIN
SUSPEND;
END
END
capto la idea de ENTER que el motor de base de datos te muestre por consulta yo que se, el tiempo transcurrido sin necesidad de manipular dicha fecha en
vb
bueno en un nuevo procedimiento que es listar los datos de las personas seria así mas o menos un ejemplo
create procedure PERSONA_LISTAR
returns (
xNOMBRES VARCHAR(60),
XANO integer,
XMES integer,
XDIA integer)
as
declare variable XFECHAACTUAL date;
declare variable XFECHANACIMIENTO date;
begin
--sacamos la fecha del servidor y lo guaramos en una variable
SELECT CURRENT_TIMESTAMP from RDB$DATABASE
INTO :XFECHAACTUAL;
FOR
select
persona.per_nombres,
persona.per_fechanacimiento
from persona
INTO :xNOMBRES ,:XFECHANACIMIENTO
DO
BEGIN
--aqui se ejecuta el procedimiento almacenado, para retornar en la lista
execute PROCEDURE VER_TIEMPO :XFECHAACTUAL,:XFECHANACIMIENTO RETURNING_VALUES :XANO,:XMES,:XDIA;
SUSPEND;
END
END
Gracias