PDA

Ver la Versión Completa : Alternativa a time.h


aguml
12-06-2014, 16:12:36
Hola amigos, he estado creando una aplicacion que le metes dos fechas y te calcula el tiempo transcurrido entre ellas y me he encontrado con un problema mas que sabido, las funciones de time.h trabajan con el rango de 1970 a 2038 así que si quiero por ejemplo calcular desde 1956 a 2014 pues estoy jodido. ¿hay alguna manera alternativa de hacer esto sin un rango tan pequeño? Las funciones que uso para ello son mktime, localtime, y time.

ecfisa
12-06-2014, 19:47:36
Hola aguml.

Revisa este si te sirve este enlace (https://github.com/schwern/y2038/wiki), (Fix time.h (https://github.com/schwern/y2038)).

Saludos :)

aguml
12-06-2014, 22:20:06
veo que habla de quitar el fix de 2038 pero no veo por ningun sitio que haya quitado el de 1970 pero habra que probar a ver que pasa. Una cosa, si un unsigned int da para 44 años, uno de 64 daria para 88 años? Si es asi me parece que sigue siendo muy poco ya que hay personas que a lo mejor tienen 100 años y si intentas calcular su edad metiendo su fecha de nacimiento y la actual pues estariamos igual. No se a que esperan para crear tipos mucho mas grandes para estos tipos de calculos ya que para proyectos cientificos se podrian usar cifras astronomicas.

aguml
13-06-2014, 10:08:35
Amigo tengo problemas con lo que pusiste. Lo estoy probando y me encuentro con estos errores: [Linker Error] Unresolved external 'mktime64(std::tm *)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF\UNIT1.OBJ [Linker Error] Unresolved external 'localtime64(const long long *)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF\UNIT1.OBJ No se que hago mal ya que he añadido el time64.c al proyecto y el time64.h lo incluyo al principio del archivo. Otra cosa que veo es que tambien uso las funciones: double _RTLENTRY _EXPFUNC difftime(time_t __time2, time_t __time1); time_t _RTLENTRY _EXPFUNC time(time_t *__timer); las cuales pertenecen a time.h y no están implementadas en time64.h y time_t es un long mientras que yo le meto como parametros los Time64_T que son long long y no se que pasará con eso pero me da mala espina. Aquí os pongo el proyecto para descargar: https://mega.co.nz/#!posS1KST!eE1-9nkWwu-KXOA4Q2c4mLzOM5LxWIRAN3EHuKyt7rw

aguml
13-06-2014, 11:08:28
Tambien he buscado otro codigo y he encontrado esto:
http://www.codeproject.com/Articles/4674/Time-bit-Times-for-bit-Windows-Apps

Lo he probado y me da los siguientes errores:
[Linker Error] Unresolved external 'time_64(long long *)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF64\UNIT1.OBJ
[Linker Error] Unresolved external 'mktime64(std::tm *)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF64\UNIT1.OBJ
[Linker Error] Unresolved external 'difftime_64(long long, long long)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF64\UNIT1.OBJ
[Linker Error] Unresolved external 'localtime_64(long long *)' referenced from C:\DOCUMENTS AND SETTINGS\AGUSTIN\ESCRITORIO\PROYECTO DATEDIFF64\UNIT1.OBJ

Aqui esta este proyecto tambien:
https://mega.co.nz/#!lltGXAgJ!2W9Njl60xgyuQozd1c27TvL3NyT8jRvAzwzNCUmCaLk Espero que podais ayudarme please.

PD: perdon por lo del mensaje anterior pero tenia bloqueado los scripts y se ve que hacian falta y por eso no ha respetado los saltos de linea.

webmasterplc
15-06-2014, 16:27:11
Buenas voy a colocal un link de un sitio donde consegui algo para calculos de fechac y me ha funcionado al pelo, no tengo nada que ver con ese sitio solo que tiene buena informacion gratuita con relacion a delphi
descargar el ejemplo de aqui (http://ajpdsoft.com/modules.php?name=Downloads&d_op=getit&lid=248)alli contiene el codigo

aguml
07-08-2014, 18:10:55
amigos al final hice funcionar esto ya que el problema que me daba era que los archivos eran time64.h y time64.c y por lo visto al colocar el #include "time64.h" buscaba el time64.cpp y le cambié la extension y listo.
Ahora tengo otro problema que creo que es cosa de mi codigo, las cuentas no me salen.
Os pongo las dos funciones encargadas del calculo de diferencia entre fechas a ver si veis el fallo porque yo ya no se que hacer.
int GetNDaysMonth(int mes, int anio)
{
int dias;

switch (mes)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
dias = 31;
break;
case 4: case 6: case 9: case 11:
dias = 30;
break;
case 2:if(anio%4==0)
dias = 28;
else
dias=29;
break;
default:
ShowMessage("El mes no es válido.");
break;
}
return dias;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button_CalcularClick(TObject *Sender)
{
t64 now, time1, time2;
struct tm aux, newyear1, newyear2, superior, inferior;
double segundos = 0, minutos = 0, horas = 0, dias = 0,meses = 0, anios = 0, timeAux;
int nDias;
bool error = false;

if(MaskEdit_Fecha1->Text.Length() != 10)
{
ShowMessage("Primera fecha tiene un formato de fecha inválido.\nFormato válido '00/00/0000'");
}
else if(RadioGroup_Tipo->ItemIndex == 0 && MaskEdit_Fecha2->Text.Length() != 10)
{
ShowMessage("Segunda fecha tiene un formato de fecha inválido.\nFormato válido '00/00/0000'");
}
else
{
time(&now); //Obtengo el tiempo condensado en segundos. Creo que aqui tendria problemas porque no es de 64 bits
aux = *localtime(&now);
aux.tm_hour = 0;
aux.tm_min = 0;
aux.tm_sec = 0;
aux.tm_wday = 0;
aux.tm_yday = 0;
now = mktime64(&aux);

newyear1 = *localtime(&now);
newyear1.tm_year = MaskEdit_Fecha1->Text.SubString(7,4).ToInt() - 1900;
newyear1.tm_mon = MaskEdit_Fecha1->Text.SubString(4,2).ToInt() - 1;
newyear1.tm_mday = MaskEdit_Fecha1->Text.SubString(1,2).ToInt();
newyear1.tm_hour = aux.tm_hour;
newyear1.tm_min = aux.tm_min;
newyear1.tm_sec = aux.tm_sec;
newyear1.tm_wday = 0;
newyear1.tm_yday = 0;

if(RadioGroup_Tipo->ItemIndex == 0)
{
newyear2 = newyear1;
newyear2.tm_year = MaskEdit_Fecha2->Text.SubString(7,4).ToInt() - 1900;
newyear2.tm_mon = MaskEdit_Fecha2->Text.SubString(4,2).ToInt() - 1;
newyear2.tm_mday = MaskEdit_Fecha2->Text.SubString(1,2).ToInt();

time1 = mktime64(&newyear1);
if(time1 == -1)
{
ShowMessage("Primera fecha no es correcta.");
error = true;
}
time2 = mktime64(&newyear2);
if(time2 == -1)
{
ShowMessage("Segunda fecha no es correcta.");
error = true;
}
}else{
time1 = mktime64(&newyear1);
if(time1 == -1)
{
ShowMessage("Primera fecha no es correcta.");
error = true;
}
time2 = now;
}

if(!error)
{
if(time1 > time2)
{
segundos = difftime(time1,time2);
superior = *localtime(&time1);
inferior = *localtime(&time2);
}
else
{
segundos = difftime(time2,time1);
superior = *localtime(&time2);
inferior = *localtime(&time1);
}

minutos = segundos / 60;
timeAux = segundos;
segundos = fmod(timeAux,60);

horas = minutos / 60;
timeAux = minutos;
minutos = fmod(timeAux,60);

dias = horas / 24;
timeAux = horas;
horas = fmod(timeAux,24);

nDias = GetNDaysMonth((inferior.tm_mon+1), (inferior.tm_year + 1900));

while(nDias <= dias)
{
if(inferior.tm_year <= superior.tm_year)
{
dias -= nDias;
nDias = GetNDaysMonth((inferior.tm_mon+1), (inferior.tm_year + 1900));

if(inferior.tm_mon == 11)
{
inferior.tm_mon = 0;
inferior.tm_year++;
meses++;
}
else
{
inferior.tm_mon += 1;
meses++;
}

if(meses == 12)
{
anios++;
meses = 0;
}
}
}

ShowMessage (AnsiString(anios)+" años\n" +
AnsiString(meses)+" meses\n" +
AnsiString(dias)+" dias");
}
}
}
//---------------------------------------------------------------------------


Os cuento el problema:
Si pongo como primera fecha 07/08/2014 y como segunda 07/08/2015, me dirá que han pasado 0 años, 11 meses y 29 dias. Deberia de devolver 1 año, 0 meses, 0 dias.
Si pongo como primera fecha 07/08/2014 y como segunda 07/08/2514 me dice que la diferencia es de 499 años, 3 meses, y 21 dias cuando creo que tendria que devolver 500 años.
Creo que el fallo está en lo que hago para calcular los dias, meses y años pero no veo el fallo.
A ver si podeis ayudarme en esto que llevo meses liado y no lo termino.
Si quereis los fuentes me lo decis y os los mando.