PDA

Ver la Versión Completa : Problema con EncodeDateTime < 1900


geolife
21-05-2012, 20:21:26
Hola amig@s,

Estoy haciendo una aplicación con Delphi 7 que trata con cálculos de fechas y me encuentro que al transformar valores inferiores al año 1900, los resultados con EncodeDateTime son incoherentes...


Var
A: TdateTime;
begin

// Fecha: 4 febrero 1755, 1 horas 22 minutos, 22 segundos -
A := EncodeDateTime (1755,2,4,1,22,22,1); // Uses DateUtils
ShowMessage (DateTimeToStr(A));
// Da como resultado 5 febrero de 1755 , 22 horas 37 segundos, es decir otro resultado?
// Obviamente uno esperaría 4 febrero 1755, 1 horas 22 minutos, 22 segundos
end;


He probado la misma rutina en Lazarus y funciona bien, no se si trata de alguna caracteristica especial en Delphi o que :confused:

¿Alguien se ha encontrado con lo mismo?

Gracias!

Casimiro Notevi
21-05-2012, 22:45:49
¿Y con un año más actual funciona bien?, ejemplo: 2012

geolife
21-05-2012, 22:55:05
Hola Casimiro!

Si!, en general a partir de 1900 hacia adelante funciona perfectamente, pero en fechas inferiores el resultado es completamente erróneo, da una fecha distinta a la introducida :confused: La verdad es que no tengo más remedio que usar esta función, para codificar los formatos de fecha y tiempo de una forma homogénea en cualquier región, pero nada!!

No he tenido oportunidad de probar en otras versiones de Delphi más actuales a la 7, solo probé en Lazarus el ejemplo adjunto y funciona bien.

Nota: Según la ayuda de Delphi, el año admite valores desde 1 a 9999, con lo que debería funcionar..., pero algo falla!

datetime routines

Delphi syntax:

function EncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word):TDateTime;

Description

EncodeDateTime returns a TDateTime from the values specified as the AYear, AMonth, ADay, AHour, AMinute, ASecond, and AMilliSecond parameters.

The year must be between 1 and 9999.

¿Y con un año más actual funciona bien?, ejemplo: 2012

gatosoft
22-05-2012, 03:15:56
hola geolife

El problema está en que el TdateTime es en realidad un valor numérico de punto flotante, un double o un Real... y el CERO representa el año 1900, Esto no es propio de Delphi, algunos motores de base de datos de hecho tienen como bae el 1899... No se por que ni cuando se pusieron de acuerdo en eso...

puedes hacer la prueba con algo como:

fecha: TDateTime
fecha:= 0;
showMessage(DateToStr(Fecha));

Y te debe retornar la fecha base....

No se si haya alguna utilidadad o unidad en Delphi solucione esto.. sorry

geolife
22-05-2012, 08:26:57
Gracias por la información Gatosoft, TDateTime funciona como tu comentas, pero no se como pasar los datos TTime en coma flotante de una forma predecible. De hecho la función EncodeDate ya funciona bien con fechas inferiores a 1900, el problema es cuando incluimos el tiempo de horas, minutos y segundos con EncodeDateTime.

Si fuera solo cuestión de guardar la información, podríamos pasar los valores de forma separada utilizando EncodeDate y EncodeTime, el problema es que el software se encarga de realizar cálculos de tiempo utilizando años,meses,dias, horas, minutos y segundos.

En resumen tenemos:

procedure TForm1.Button1Click(Sender: TObject);
Var
A,B: TDateTime;
begin

// Fecha: 4 febrero 1755, 1 horas 22 minutos, 22 segundos -
A := EncodeDateTime (1755,2,4,1,22,22,1); // Uses DateUtils
ShowMessage (DateTimeToStr(A));
// ERROR
// Da como resultado 5 febrero de 1755 , 22 horas 37 segundos, es decir otro resultado?
// Obviamente uno esperaría 4 febrero 1755, 1 horas 22 minutos, 22 segundos

A := EncodeDate (1755,2,4); B:= EncodeTime (1,12,22,1); // Uses DateUtils
ShowMessage (DateToStr(A)+ ' '+ (TimeToStr(B)));
// OK la visualización, pero tenemos la información en 2 variables.

// Intentamos poner en A el valor TDateTime por seperado
A := EncodeDate (1755,2,4); A := EncodeTime (1,12,22,1);
ShowMessage (DateTimeToStr(A));
// ERROR OTRA VEZ
// ¿¿ ????
end;
end.


:confused::confused::confused:, atascado con TdateTime...

LoPiTaL
22-05-2012, 08:43:13
Tal vez ya te has dado cuenta, o ha sido al ponerlo en el navegador, pero la última parte de tu código está mal.

Debería ser:


// Intentamos poner en A el valor TDateTime por seperado
A := EncodeDate (1755,2,4) + EncodeTime (1,12,22,1); //Debes sumar fecha y hora, si no,
//sólo te quedará en A la hora, a fecha base (1900)
ShowMessage (DateTimeToStr(A)); //Debería ir bien ahora
// ERROR OTRA VEZ
// ¿¿ ????


Sólo por curiosidad, he probado en XE2 y en Delphi 2010 y el error está corregido: la sentencia


A := EncodeDateTime (1755,2,4,1,22,22,1); // Uses DateUtils


funciona correctamente.

Un saludo,
LoPiTaL

geolife
22-05-2012, 09:13:29
Hola LoPiTaL!,

Llevas toda la razón, la sentencia correcta para ese tipo de asignación debe ser una suma, el codigo era parte de varias pruebas y me habia quedado así...:o

Te agradezco tus pruebas, parece ser entonces que en versiones sucesivas de Delphi esto esta corregido, y es una buena noticia.
Me parece que me voy abocado a una actualización de Delphi.

Gracias otra vez!

;)

Tal vez ya te has dado cuenta, o ha sido al ponerlo en el navegador, pero la última parte de tu código está mal.

Debería ser:


// Intentamos poner en A el valor TDateTime por seperado
A := EncodeDate (1755,2,4) + EncodeTime (1,12,22,1); //Debes sumar fecha y hora, si no,
//sólo te quedará en A la hora, a fecha base (1900)
ShowMessage (DateTimeToStr(A)); //Debería ir bien ahora
// ERROR OTRA VEZ
// ¿¿ ????


Sólo por curiosidad, he probado en XE2 y en Delphi 2010 y el error está corregido: la sentencia


A := EncodeDateTime (1755,2,4,1,22,22,1); // Uses DateUtils


funciona correctamente.

Un saludo,
LoPiTaL