[C] Conversion de dates (j'ai perdu 2h !!!)

Conversion de dates (j'ai perdu 2h !!!) [C] - C - Programmation

Marsh Posté le 09-10-2003 à 16:38:04    

Je cherche à écrire 2 fonction de conversion de date:
 
L'une qui me transforme un timestamp  "SQL-compliant" en timestamp en seconde (utc):

Code :
  1. char* DAT_SecondsToTimestamp(unsigned long seconds) {
  2. struct tm* time = NULL;
  3. static char timestamp[DAT_TIMESTAMP_SIZE] = "";
  4. //---
  5. time = gmtime(&seconds);
  6. sprintf(timestamp, "%02d-%02d-%02d %02d:%02d:%02d", time->tm_mday, time->tm_mon+1, (1900+time->tm_year)%1000, time->tm_hour, time->tm_min, time->tm_sec);
  7. return timestamp;
  8. }


 
L'autre fait la conversion inverse

Code :
  1. unsigned long DAT_TimestampToSeconds(char* timestamp) {
  2. char tmp[3];
  3. struct tm* time = NULL;
  4. //---
  5. time = (struct tm*)malloc(sizeof(struct tm));
  6. strncpy(tmp, &timestamp[DAT_TIMESTAMP_SS_POS], 2);
  7. time->tm_sec = atoi(tmp);
  8. strncpy(tmp, &timestamp[DAT_TIMESTAMP_MI_POS], 2);
  9.   time->tm_min = atoi(tmp);
  10. strncpy(tmp, &timestamp[DAT_TIMESTAMP_HH_POS], 2);
  11.   time->tm_hour = atoi(tmp);
  12. strncpy(tmp, &timestamp[DAT_TIMESTAMP_DD_POS], 2);
  13.   time->tm_mday = atoi(tmp);
  14. strncpy(tmp, &timestamp[DAT_TIMESTAMP_MM_POS], 2);
  15.   time->tm_mon = atoi(tmp) - 1;
  16. strncpy(tmp, &timestamp[DAT_TIMESTAMP_YY_POS], 2);
  17.   time->tm_year = atoi(tmp) + 100;
  18. time->tm_wday = 0;
  19.   time->tm_yday = 0;
  20.   time->tm_isdst = 1;
  21. return mktime(time);
  22. }


 
Mais cette dernière ne fonctionne pas correctement. Je "perd" 2h00 ... comme par hasard c'est le décalage horaire GMT.
 
1) Est-ce que je cherche compliqué et il existe une autre manière de faire ça ?
 
2) Sinon ... ben aidez moi !
 
Petit exemple:

Code :
  1. printf("1065705799 = %s\n", DAT_SecondsToTimestamp(1065705799));
  2. printf("09-10-03 13:23:19 = %d\n", toto = DAT_TimestampToSeconds("09-10-03 13:23:19" ));
  3. printf("Time = %s\n", DAT_SecondsToTimestamp(toto));


 
M'affiche ça:
1065705799 = 09-10-03 15:23:19
09-10-03 13:23:19 = 1065698599
Time = 09-10-03 13:23:19
 
PS: les constante:
#define DAT_TIMESTAMP_SIZE 17+1 // Format 'DD-MM-YY HH:MI:SS'
#define DAT_TIMESTAMP_DD_POS 0
#define DAT_TIMESTAMP_MM_POS 3
#define DAT_TIMESTAMP_YY_POS 6
#define DAT_TIMESTAMP_HH_POS 9
#define DAT_TIMESTAMP_MI_POS 12
#define DAT_TIMESTAMP_SS_POS 15


Message édité par mog le 09-10-2003 à 16:39:46
Reply

Marsh Posté le 09-10-2003 à 16:38:04   

Reply

Marsh Posté le 09-10-2003 à 18:41:08    

euh gmtime
 
localtime peut être  
 
edit : je fais comment pour aider si je suis de nouveau soumis à cette limitation à la con
 
 
pourquoi tu fais pas un sscanf ?
 
sscanf(timestamp, "%02d-%02d-%02d %02d:%02d:%02d", &time->tm_mday, &time->tm_mon+1, ...
 
c'est symétrique, fait ça, àa sera plus claire, on verra après.
 
ok pour le static, par contre dans le deuxième, tu as une fuite de mémoire : utiliser une vairable auto, pas besoin d'allocation dynamique. utlise des time_t au lieu de unsigned long


Message édité par Taz le 09-10-2003 à 19:23:56
Reply

Marsh Posté le 09-10-2003 à 18:53:29    

Code :
  1. const char* DAT_SecondsToTimestamp(time_t seconds)
  2. {
  3.   static char timestamp[DAT_TIMESTAMP_SIZE] = "";
  4.   struct tm *t = localtime(&seconds);
  5.   sprintf(timestamp, "%02d-%02d-%02d %02d:%02d:%02d",
  6.   t->tm_mday,
  7.   t->tm_mon+1,
  8.   t->tm_year%100,
  9.   t->tm_hour,
  10.   t->tm_min,
  11.   t->tm_sec
  12.   );
  13.   return timestamp;
  14. }
  15. time_t DAT_TimestampToSeconds(const char* timestamp)
  16. {
  17.   time_t now=time(NULL);
  18.   struct tm t=*localtime(&now);
  19.   sscanf(timestamp, "%d-%d-%d %d:%d:%d",
  20.   &t.tm_mday,
  21.   &t.tm_mon,
  22.   &t.tm_year,
  23.   &t.tm_hour,
  24.   &t.tm_min,
  25.   &t.tm_sec
  26.   );
  27.   t.tm_mon-=1;
  28.   t.tm_year+=100;
  29.   return mktime(&t);
  30. }


Message édité par Taz le 09-10-2003 à 19:31:33
Reply

Marsh Posté le 09-10-2003 à 18:54:43    

et utilise strftime également

Reply

Marsh Posté le 10-10-2003 à 08:26:04    

1) Si j'utilise gmtime c'est que je doit travaille avec l'heure universelle gmt.
 
2) En effet j'avais pas pensé au sscanf ... c'est quand même plus lisible !
 
3) OK pour la fuite, j'ai fait une chtite boulette.
 
4) J'ai essayé ta solution:


MOG
1065705799 = 09-10-03 13:23:19
09-10-03 13:23:19 = 1065698599
1065698599 = 09-10-03 11:23:19
 
TAZ
1065705799 = 09-10-03 15:23:19
09-10-03 13:23:19 = 1065698599
1065698599 = 09-10-03 13:23:19


 
J'ai toujours ma perte de 2h ... avec 2h de décalage horaire !


Message édité par mog le 10-10-2003 à 10:07:42
Reply

Marsh Posté le 10-10-2003 à 10:10:38    

ben tu perds 2 heures par rapport à l'heure locale, pas par rapport à la gmt, faudrait savoir...  
 
parce que figure toi qu'entre Paris et Greenwich, il y a un décalage horaire

Reply

Marsh Posté le 10-10-2003 à 10:21:32    

Je perd bien 2h par rapport à l'heure gmt:
 
1065705799 = 09-10-03 13:23:19 (gmt) et 15:23:19 (local)
 
Pourquoi est-ce que j'obtient 11:23:19 (en plein atlantique !) à la 2ème conversion ?


Message édité par mog le 10-10-2003 à 10:24:15
Reply

Marsh Posté le 10-10-2003 à 11:10:42    

J'ai le même soucis en utilisant des fonctions:
 

Code :
  1. long DAT_Today() {
  2.   struct timeval tp; 
  3.   struct timezone tzp; 
  4.   gettimeofday(&tp, &tzp);
  5.   return tp.tv_sec;
  6. }
  7. /* permet de passer à minuit (début) du jour suivant */
  8. long DAT_NextDay(long timestamp) {
  9.   struct tm t;
  10.   timestamp += DAT_24H_IN_SECONDS; // ajoute 86400 sec
  11.   t = *gmtime(&timestamp);
  12.   t.tm_hour = 0;
  13.   t.tm_min = 0;
  14.   t.tm_sec = 0;
  15.   t.tm_isdst = 1;
  16.   return mktime(&t);
  17. }
  18. int main() {
  19.   time_t toto;
  20.   toto = DAT_Today();
  21.   printf("Today = %d -> %s\n", toto, DAT_SecondsToTimestamp(toto));
  22.   toto = DAT_NextDay(toto);
  23.   printf("Tomorrow = %d -> %s\n", toto, DAT_SecondsToTimestamp(toto));
  24. }


 
Resultat:
Today    = 1065776523 -> 10-10-03 09:02:03
Tomorrow = 1065823200 -> 10-10-03 22:00:00
 
Et je passe à 22h00 du même jour ... manque encore 2h !

Reply

Marsh Posté le 10-10-2003 à 14:11:41    

Up

Reply

Marsh Posté le 10-10-2003 à 14:20:29    

t'es un vrai boolay toi ...


Message édité par Taz le 10-10-2003 à 14:20:38
Reply

Marsh Posté le 10-10-2003 à 14:20:29   

Reply

Marsh Posté le 10-10-2003 à 14:55:16    

Taz a écrit :

t'es un vrai boolay toi ...


 
Précise ta pensée ...

Reply

Marsh Posté le 10-10-2003 à 15:22:45    

micne, il y a gmtime et deux heures de décalages ...

Reply

Marsh Posté le 10-10-2003 à 15:34:15    

Relis mon post plus attentivement STP avant de te foutre de moi ... tiens ça me rappelle un autre topic, on ne change pas une équipe qui gagne !
 
Tiens d'ailleurs le décalage entre locale et GMT est de 1h normalement ...

Reply

Marsh Posté le 10-10-2003 à 15:35:04    

ou 2h suivant la saison

Reply

Marsh Posté le 10-10-2003 à 15:49:05    

Ca ne répond toujours pas à la question ...

Reply

Marsh Posté le 10-10-2003 à 15:55:48    

heink ?

Reply

Marsh Posté le 10-10-2003 à 16:01:15    

c'est ton PC qui est mal configuré ...
 

Code :
  1. #include <stdio.h>
  2. #include <time.h>
  3. const char* DAT_SecondsToTimestamp(time_t seconds)
  4. {
  5.   static char timestamp[100] = "";
  6.    
  7.   struct tm *t = localtime(&seconds);
  8.    
  9.   sprintf(timestamp, "%02d-%02d-%02d %02d:%02d:%02d",
  10.   t->tm_mday,
  11.   t->tm_mon+1,
  12.   t->tm_year%100,
  13.   t->tm_hour,
  14.   t->tm_min,
  15.   t->tm_sec
  16.   );
  17.   return timestamp;
  18. }
  19.  
  20.  
  21. time_t DAT_TimestampToSeconds(const char* timestamp)
  22. {
  23.   time_t now=time(NULL);
  24.   struct tm t=*localtime(&now); /* initialisation correcte*/
  25.   /* ou alors memset(&t, 0, sizeof t) */
  26.    
  27.   sscanf(timestamp, "%d-%d-%d %d:%d:%d",
  28.  &t.tm_mday,
  29.  &t.tm_mon,
  30.  &t.tm_year,
  31.  &t.tm_hour,
  32.  &t.tm_min,
  33.  &t.tm_sec
  34.  );
  35.   t.tm_mon-=1;
  36.   t.tm_year+=100;
  37.    
  38.   return mktime(&t);
  39. }
  40. long DAT_Today()
  41. {
  42.        
  43.   return time(NULL);
  44. }
  45.  
  46. /* permet de passer à minuit (début) du jour suivant */
  47. long DAT_NextDay(long timestamp) {
  48.   struct tm t;
  49.   timestamp += 86400; /* ajoute 86400 sec */
  50.   t = *gmtime(&timestamp);
  51.   t.tm_hour = 0;
  52.   t.tm_min = 0; 
  53.   t.tm_sec = 0;
  54.   t.tm_isdst = 1;
  55.   return mktime(&t);
  56. }
  57. int main() {
  58.   time_t toto;
  59.   toto = DAT_Today();
  60.   printf("Today = %lu -> %s\n", toto, DAT_SecondsToTimestamp(toto));
  61.   toto = DAT_NextDay(toto);
  62.   printf("Tomorrow = %lu -> %s\n", toto, DAT_SecondsToTimestamp(toto));
  63.   return 0;
  64. }


 
 
Today = 1065794458 -> 10-10-03 16:00:58
Tomorrow = 1065823200 -> 11-10-03 00:00:00


Message édité par Taz le 10-10-2003 à 16:03:26
Reply

Marsh Posté le 10-10-2003 à 16:17:30    

Encore une fois, tu travailles en localtime.
 
Moi, j'ai besoin de bosser en GMT ! Et c'est ça qui pose pb !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed