Autor Tema: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970  (Leído 8938 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Pues como dice el titulo necesito implementar un algoritmo que me determine la Fecha (Año, mes, día) más hora (Hora, minutos, segundos, y hasta mili-segundos pero no importan  :mrgreen: ) entregándome como dato los mili-segundos transcurridos desde el 1 de enero a las 00:00:00.000 de 1970 en 48-bits  :z) Aquí les dejo el que he implementado en C30. Tengo uno similar en C18, pero las variables de 64-bits las creo mediante uniones y la operación de multiplicaciones se hace un poco lenta  :undecided:

Código: C
  1. unsigned long High_Data;
  2. unsigned int Low_Data;
  3. unsigned long long Elapsed_Milliseconds;
  4. unsigned long Elapsed_Days;
  5. unsigned char Elapsed_Years;
  6. unsigned char Elapsed_Years_Leap;
  7. unsigned int Days_Of_Year;
  8. unsigned char Month, Day, Hour, Minute, Second, Millisecond;
  9. unsigned int Year;
  10. unsigned long Milliseconds_Day;
  11.  
  12.  
  13. int main (int argc, char * argv[]){
  14.         //125F18457C0
  15.         // PIC 8-bits, C18.-
  16.         //High_Data=0x012A828F;
  17.         //Low_Data=0xFE28;
  18.        
  19.         Elapsed_Milliseconds=0x012A828FFE28;//((unsigned long long)(High_Data*65536)+ Low_Data);
  20.        
  21.         Elapsed_Days=Elapsed_Milliseconds/86400000;
  22.         Elapsed_Years=Elapsed_Days/365;
  23.         Elapsed_Years_Leap=(Elapsed_Years + 1)/4;
  24.         Days_Of_Year=Elapsed_Days -((Elapsed_Years_Leap*366)+(Elapsed_Years-Elapsed_Years_Leap)*365);
  25.         Year=1970+Elapsed_Years;
  26.         // 31 59 90 120 151 181 212 243 273 304 334 365
  27.         if((Year%4)!=0){
  28.                 if(Days_Of_Year<182){
  29.                         Month=6;
  30.                         Day=Days_Of_Year-150;
  31.                         if(Days_Of_Year<91){
  32.                                 if(Days_Of_Year<32){Month=1;Day=Days_Of_Year+1;}
  33.                                 else if(Days_Of_Year<60){Month=2;Day=Days_Of_Year-30;}
  34.                                 else{Month=3;Day=Days_Of_Year-58;}
  35.                         }else{
  36.                                 if(Days_Of_Year<121){Month=4;Day=Days_Of_Year-89;}
  37.                                 else if(Days_Of_Year<152){Month=5;Day=Days_Of_Year-119;}
  38.                         }
  39.                 }else{
  40.                         Month=12;
  41.                         Day=Days_Of_Year-333;
  42.                         if(Days_Of_Year<274){
  43.                                 if(Days_Of_Year<213){Month=7;Day=Days_Of_Year-180;}
  44.                                 else if(Days_Of_Year<244){Month=8;Day=Days_Of_Year-211;}
  45.                                 else{Month=9;Day=Days_Of_Year-242;}
  46.                         }else{
  47.                                 if(Days_Of_Year<305){Month=10;Day=Days_Of_Year-272;}
  48.                                 else if(Days_Of_Year<335){Month=11;Day=Days_Of_Year-303;}
  49.                         }
  50.                 }      
  51.         }else{
  52.                 if(Days_Of_Year<183){
  53.                         Month=6;
  54.                         Day=Days_Of_Year-151;
  55.                         if(Days_Of_Year<92){
  56.                                 if(Days_Of_Year<32){Month=1;Day=Days_Of_Year+1;}
  57.                                 else if(Days_Of_Year<61){Month=2;Day=Days_Of_Year-30;}
  58.                                 else{Month=3;Day=Days_Of_Year-59;}
  59.                         }else{
  60.                                 if(Days_Of_Year<122){Month=4;Day=Days_Of_Year-90;}
  61.                                 else if(Days_Of_Year<153){Month=5;Day=Days_Of_Year-120;}
  62.                         }
  63.                 }else{
  64.                         Month=12;
  65.                         Day=Days_Of_Year-334;
  66.                         if(Days_Of_Year<275){
  67.                                 if(Days_Of_Year<214){Month=7;Day=Days_Of_Year-181;}
  68.                                 else if(Days_Of_Year<245){Month=8;Day=Days_Of_Year-212;}
  69.                                 else{Month=9;Day=Days_Of_Year-243;}
  70.                         }else{
  71.                                 if(Days_Of_Year<306){Month=10;Day=Days_Of_Year-273;}
  72.                                 else if(Days_Of_Year<336){Month=11;Day=Days_Of_Year-304;}
  73.                         }
  74.                 }      
  75.         }
  76.        
  77.         Milliseconds_Day=Elapsed_Milliseconds - ((unsigned long long)Elapsed_Days*86400000);
  78.         Hour=Milliseconds_Day/3600000;
  79.         Minute=(Milliseconds_Day/60000)-((unsigned int)Hour*60);
  80.         Second=(Milliseconds_Day/1000)-((unsigned int)Minute*60)-((unsigned long)Hour*3600);
  81.         Millisecond=Milliseconds_Day-((unsigned int)Second*1000)-((unsigned long)Minute*60000)-((unsigned long)Hour*3600000);
  82.  
  83.         while(1);
  84. }


Si se les ocurre alguna sugerencia, bienvenida sea  :)


Saludos!



« Última modificación: 19 de Agosto de 2010, 11:43:54 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Hola Suky, y los años bisiestos?  --->   if año/4 = año\4   bisiesto
 if  int(año/4)= año/4  ---> bisiesto....

te parece?

Norberto
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Hola Suky, y los años bisiestos?  --->   if año/4 = año\4   bisiesto
 if  int(año/4)= año/4  ---> bisiesto....

te parece?

Norberto

Eso lo tengo en cuenta con :
Código: C
  1. if((Year%4)!=0){


A eso te refieres?

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Hola Suky. Lo que estás intentando es obtener el timestamp, aunque en realidad el timestamp tiene una resolución de segundo, no de milisegundo como tu caso.

La implementación de año bisiesto está incompleta, un año es bisiesto si es múltiplo de 4, pero no de 400. Entonces, por ejemplo, el año 2000 NO fue bisiesto, pese a  ser multiplo de 4.

Necesitas la precision de milisegundos realmente? Porque sino por ahí seguro hay algún algoritmo de timestamp que te sirve, aunque dudo de la optimización del código....
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Hola Suky. Lo que estás intentando es obtener el timestamp, aunque en realidad el timestamp tiene una resolución de segundo, no de milisegundo como tu caso.

La implementación de año bisiesto está incompleta, un año es bisiesto si es múltiplo de 4, pero no de 400. Entonces, por ejemplo, el año 2000 NO fue bisiesto, pese a  ser multiplo de 4.

Necesitas la precision de milisegundos realmente? Porque sino por ahí seguro hay algún algoritmo de timestamp que te sirve, aunque dudo de la optimización del código....


Estas equivocado, los años finales de siglo son bisiestos si son divisibles por 400 (2000 fue bisiesto). Y como no creo que llegue al año 2100 no hice ese control en el algoritmo  :mrgreen:

Los milisegundos no son necesarios, por lo general las estaciones ignoran este valor y lo colocan a 000  ;-)


Saludos!

No contesto mensajes privados, las consultas en el foro

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Y lo dije todo mal!

Acabo de revisar año bisiesto en wikipedia y es un poco más complejo aún...

La idea es reducir la cantidad de multiplicaciones??

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Hola Suky! Muy bueno che, pero hay una cosita q me llama la atencion. La cabecera estandar:
int main (int argc, char * argv[])
Lo estas ejecutando en un pic??
saludos!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Hola, yo utilizaria Julian Dates ( buscar en la web ) eso te da la cantidad de dias pasados desde una fecha especifica, despues solo te resta multiplicar por la cantidad de milisegundos en un dia.

Saludos !

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Y lo dije todo mal!

Acabo de revisar año bisiesto en wikipedia y es un poco más complejo aún...

La idea es reducir la cantidad de multiplicaciones??

Saludos.

Sip, es un toque más complejo. Pero en mi caso es para consultar solo si en el año que estoy trabajando es bisiesto  :undecided:

Hola Suky! Muy bueno che, pero hay una cosita q me llama la atencion. La cabecera estandar:
int main (int argc, char * argv[])
Lo estas ejecutando en un pic??
saludos!!

Sip, en C30 se utiliza esa cabecera... :roll:

Hola, yo utilizaria Julian Dates ( buscar en la web ) eso te da la cantidad de dias pasados desde una fecha especifica, despues solo te resta multiplicar por la cantidad de milisegundos en un dia.



Saludos !

Buscando! Igual tengo que implementar el caso contrario, de la fecha actual determinar los milisegundos  :)


Edit: No quiero que se mal entienda, yo presento el algoritmo que he realizado para determinar la fecha, y funciona correctamente (Puede servirle a alguien). Pero como lo mio no es la programación, de algoritmos tengo poca idea, puede que haya otra forma más simple de hacerlo  ;-)



Saludos!

« Última modificación: 19 de Agosto de 2010, 00:29:25 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Sip, en C30 se utiliza esa cabecera... :roll:
Y de donde recibe los parametros argc y argv? En la compu los carga el sistema operativo con los parametros que uno ponga al ejecutar el programa, pero en un pic?? O.o

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970
« Respuesta #10 en: 19 de Agosto de 2010, 01:03:31 »
Sip, en C30 se utiliza esa cabecera... :roll:
Y de donde recibe los parametros argc y argv? En la compu los carga el sistema operativo con los parametros que uno ponga al ejecutar el programa, pero en un pic?? O.o

Lo mio fue Copy&Paste  :mrgreen:  :D :D :D

También se usa int main()...
« Última modificación: 19 de Agosto de 2010, 01:07:05 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970
« Respuesta #11 en: 19 de Agosto de 2010, 01:40:32 »
JAJAJA me mato la cara :D
ta bien, ya voy a ver si encuentro algo googleando jeje. Perdon por desvirtuar el hilo :P
saludosss!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 965
Re: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970
« Respuesta #12 en: 19 de Agosto de 2010, 02:12:43 »
   
Código: [Seleccionar]
        Elapsed_Milliseconds=0x012A828FFE28;//((unsigned long long)(High_Data*65536)+ Low_Data);

Elapsed_Days=Elapsed_Milliseconds/86400000;
Elapsed_Years=Elapsed_Days/365;
Elapsed_Years_Leap=Elapsed_Years/4;
Days_Of_Year=Elapsed_Days -((Elapsed_Years_Leap*366)+(Elapsed_Years-Elapsed_Years_Leap)*365);
Year=1970+Elapsed_Years;
// 31 59 90 120 151 181 212 243 273 304 334 365
if((Year%4)!=0){

Estás contando los bisiestos cada 4 años pero a partir de 1970, y 1970 no fué bisiesto ==> agrega 1 día en 1970,1974,1978,1982... que no fueron bisiestos.

Si el año de base fuera un bisiesto como 1980 no habría problema.




Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970
« Respuesta #13 en: 19 de Agosto de 2010, 02:27:51 »
   
Código: [Seleccionar]
        Elapsed_Milliseconds=0x012A828FFE28;//((unsigned long long)(High_Data*65536)+ Low_Data);

Elapsed_Days=Elapsed_Milliseconds/86400000;
Elapsed_Years=Elapsed_Days/365;
Elapsed_Years_Leap=Elapsed_Years/4;
Days_Of_Year=Elapsed_Days -((Elapsed_Years_Leap*366)+(Elapsed_Years-Elapsed_Years_Leap)*365);
Year=1970+Elapsed_Years;
// 31 59 90 120 151 181 212 243 273 304 334 365
if((Year%4)!=0){

Estás contando los bisiestos cada 4 años pero a partir de 1970, y 1970 no fué bisiesto ==> agrega 1 día en 1970,1974,1978,1982... que no fueron bisiestos.

Si el año de base fuera un bisiesto como 1980 no habría problema.


Ya se, yo calculo cuantos años bisiestos hay en el rango.. No veo el error, y como dije anteriormente, lo he probado y funciona perfectamente  :undecided:

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Algoritmo para determinar Fecha y hora según mili-segundos pasados desde 1970
« Respuesta #14 en: 19 de Agosto de 2010, 10:38:23 »
Hola Suky, disculpa la pregunta, ¿para qué sirve recibir esa cantidad en ms y convertirla a una fecha?

Si el PIC estuviera recibiendo tal cantidad, mejor que la PC ya se la mande completa en vez de atarearlo más. En todo lenguaje actual ya hay librerías para esas conversiones, por ejemplo:

http://dotnetperls.com/datetime-1

Y si el cálculo se hace en la PC pues estaría de sobra.