La Norme propose en exemple la recherche du jour de la semaine du 4 juillet 2001
(le C est américain jusqu'au bout ;) mais je les félicite de leur choix
d'exemple, à nouveau la Norme est beaucoup plus didactique qu'on ne le dit ne
général). Voici leur code mais adapté pour la recherche du jour de la semaine
pour un siècle plutôt :
Et quelle n'est pas ma surprise de voir l'affichage suivant :
-unknown-
Vérification faite, sur ma machine, le dernier jour qui ne marche pas est le
vendredi 13 (!!) décembre 1901 et ça me renvoie bien Sunday pour le 14 décembre
1901, on dirait le bug de 2038 avec des nombres négatifs (2038-1970=62 et
1970-62= 1902 et en fait environ décembre 1901 car le bug est en janvier 2038).
Je suis très étonné de cette impossibilité de répondre car je pensais que la
conversion était assurée pour les dates postérieures à 1900, cf. ce que dit la
Norme :
7.23 Date and time <time.h> 7.23.1 Components of time
1 (...) The semantics of the members and their normal ranges are expressed in
the comments.
tm_year; // years since 1900
[Au passage, je trouve assez curieux de donner des informations de spécification
dans des commentaires de code].
Sous Windows chez moi, c'est encore pire, ça ne marche qu'à partir du 2 janvier
1970 (Mingw et Visual C++).
Un compilateur conforme est-il censé traiter de toutes les dates depuis 1900 ?
[si je regarde le code de Plauger dans son livre, il fait attention à ce que ces
dates soient traitées entre 1801 et 2099].
Le 05/03/09 22:26, dans <49b04372$0$15788$, « candide » a écrit :
Je suis très étonné de cette impossibilité de répondre car je pensais que la conversion était assurée pour les dates postérieures à 1900,
1900 est juste l'offset, pas la date de départ, l'"Epoch". La date de départ est généralement 1970, mais ce n'est pas dans la norme C, mais dans la norme Unix. La date de fin de validité est souvent, hélas, 2038.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 05/03/09 22:26, dans <49b04372$0$15788$426a34cc@news.free.fr>,
« candide » <candide@free.invalid> a écrit :
Je suis très étonné de cette impossibilité de répondre car je pensais que la
conversion était assurée pour les dates postérieures à 1900,
1900 est juste l'offset, pas la date de départ, l'"Epoch". La date de départ
est généralement 1970, mais ce n'est pas dans la norme C, mais dans la norme
Unix. La date de fin de validité est souvent, hélas, 2038.
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 05/03/09 22:26, dans <49b04372$0$15788$, « candide » a écrit :
Je suis très étonné de cette impossibilité de répondre car je pensais que la conversion était assurée pour les dates postérieures à 1900,
1900 est juste l'offset, pas la date de départ, l'"Epoch". La date de départ est généralement 1970, mais ce n'est pas dans la norme C, mais dans la norme Unix. La date de fin de validité est souvent, hélas, 2038.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Antoine Leca
Le 05/03/2009 21:26, candide écrivit :
Vérification faite, sur ma machine, le dernier jour qui ne marche pas est le vendredi 13 (!!) décembre 1901 et ça me renvoie bien Sunday pour le 14 décembre 1901, on dirait le bug de 2038 avec des nombres négatifs (2038-1970b et 1970-62= 1902 et en fait environ décembre 1901 car le bug est en janvier 2038).
L'analyse est correcte, il s'agit bien du même problème.
Je suis très étonné de cette impossibilité
Tu ne devrais pas trop. Les timestamps *nix (dont sont dérivés nombre d'implémentations du type time_t) sont conçus pour dater des évènements intéressant la machine ; à partir de là, et sachant qu'il faut bien fixer une limite quelque part, il ne faut pas s'étonner que seuls les évènements ultérieurs au 1er janvier 1970 (le début de l'ère Posix) se doivent d'être représentables; de la même façon, il ne devrait pas être trop problématique *AUJOURD'HUI* d'être limité dans le futur à la présentation des évènements jusqu'en 2037 "seulement".
Note bien qu'actuellement, les implémentations profitent des plus grandes possibilités offertes par les matériels pour graduellement étendre le domaine couvert ; seulement, à l'inverse du battage médiatique organisé par les SSII au sujet du « bogue de l'an 2000 », la transition se fait en douceur, en essayant de préserver le plus possible les fonctionnalités existantes là où cela peut poser problème (donc pas de big bang pour avoir time2_t comme un compte de décimicrosecondes depuis les début de l'ère grégorienne, comme certains le propos[èr]ent). Alors effectivement cela signifie que certaines implémentations peuvent paraître aujourd'hui limitées, mais cela ne devrait pas être un problème dans la pratique.
Un autre problème très différent, et qui affecte surtout C plus que *nix, est l'utilisation faite par certains programmes du type time_t pour représenter des évènements sur une plus grande échelle ; un exemple typique ici est celui des dates de naissance, et avec difftime() on peut calculer plus facilement les horoscopes... Évidemment, il s'agit là d'une perversion.
Un compilateur conforme est-il censé traiter de toutes les dates depuis 1900 ?
Non. En fait il y a mêmes des implémentations classiques et conformes (sur ce point) qui ne remontent pas avant 1980...
De plus, tu as mélangé time_t et les spécifications de struct tm ; hors rien n'oblige à ce le premier couvre le même domaine que le second, et surtout pas les spécifications de mktime() (la fonction que passe de l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du calendrier ne peut être représenté...
Antoine
Le 05/03/2009 21:26, candide écrivit :
Vérification faite, sur ma machine, le dernier jour qui ne marche pas est le
vendredi 13 (!!) décembre 1901 et ça me renvoie bien Sunday pour le 14 décembre
1901, on dirait le bug de 2038 avec des nombres négatifs (2038-1970b et
1970-62= 1902 et en fait environ décembre 1901 car le bug est en janvier 2038).
L'analyse est correcte, il s'agit bien du même problème.
Je suis très étonné de cette impossibilité
Tu ne devrais pas trop.
Les timestamps *nix (dont sont dérivés nombre d'implémentations du type
time_t) sont conçus pour dater des évènements intéressant la machine ; à
partir de là, et sachant qu'il faut bien fixer une limite quelque part,
il ne faut pas s'étonner que seuls les évènements ultérieurs au 1er
janvier 1970 (le début de l'ère Posix) se doivent d'être représentables;
de la même façon, il ne devrait pas être trop problématique
*AUJOURD'HUI* d'être limité dans le futur à la présentation des
évènements jusqu'en 2037 "seulement".
Note bien qu'actuellement, les implémentations profitent des plus
grandes possibilités offertes par les matériels pour graduellement
étendre le domaine couvert ; seulement, à l'inverse du battage
médiatique organisé par les SSII au sujet du « bogue de l'an 2000 », la
transition se fait en douceur, en essayant de préserver le plus possible
les fonctionnalités existantes là où cela peut poser problème (donc pas
de big bang pour avoir time2_t comme un compte de décimicrosecondes
depuis les début de l'ère grégorienne, comme certains le propos[èr]ent).
Alors effectivement cela signifie que certaines implémentations peuvent
paraître aujourd'hui limitées, mais cela ne devrait pas être un problème
dans la pratique.
Un autre problème très différent, et qui affecte surtout C plus que
*nix, est l'utilisation faite par certains programmes du type time_t
pour représenter des évènements sur une plus grande échelle ; un exemple
typique ici est celui des dates de naissance, et avec difftime() on peut
calculer plus facilement les horoscopes... Évidemment, il s'agit là
d'une perversion.
Un compilateur conforme est-il censé traiter de toutes les dates depuis 1900 ?
Non. En fait il y a mêmes des implémentations classiques et conformes
(sur ce point) qui ne remontent pas avant 1980...
De plus, tu as mélangé time_t et les spécifications de struct tm ; hors
rien n'oblige à ce le premier couvre le même domaine que le second, et
surtout pas les spécifications de mktime() (la fonction que passe de
l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du
calendrier ne peut être représenté...
Vérification faite, sur ma machine, le dernier jour qui ne marche pas est le vendredi 13 (!!) décembre 1901 et ça me renvoie bien Sunday pour le 14 décembre 1901, on dirait le bug de 2038 avec des nombres négatifs (2038-1970b et 1970-62= 1902 et en fait environ décembre 1901 car le bug est en janvier 2038).
L'analyse est correcte, il s'agit bien du même problème.
Je suis très étonné de cette impossibilité
Tu ne devrais pas trop. Les timestamps *nix (dont sont dérivés nombre d'implémentations du type time_t) sont conçus pour dater des évènements intéressant la machine ; à partir de là, et sachant qu'il faut bien fixer une limite quelque part, il ne faut pas s'étonner que seuls les évènements ultérieurs au 1er janvier 1970 (le début de l'ère Posix) se doivent d'être représentables; de la même façon, il ne devrait pas être trop problématique *AUJOURD'HUI* d'être limité dans le futur à la présentation des évènements jusqu'en 2037 "seulement".
Note bien qu'actuellement, les implémentations profitent des plus grandes possibilités offertes par les matériels pour graduellement étendre le domaine couvert ; seulement, à l'inverse du battage médiatique organisé par les SSII au sujet du « bogue de l'an 2000 », la transition se fait en douceur, en essayant de préserver le plus possible les fonctionnalités existantes là où cela peut poser problème (donc pas de big bang pour avoir time2_t comme un compte de décimicrosecondes depuis les début de l'ère grégorienne, comme certains le propos[èr]ent). Alors effectivement cela signifie que certaines implémentations peuvent paraître aujourd'hui limitées, mais cela ne devrait pas être un problème dans la pratique.
Un autre problème très différent, et qui affecte surtout C plus que *nix, est l'utilisation faite par certains programmes du type time_t pour représenter des évènements sur une plus grande échelle ; un exemple typique ici est celui des dates de naissance, et avec difftime() on peut calculer plus facilement les horoscopes... Évidemment, il s'agit là d'une perversion.
Un compilateur conforme est-il censé traiter de toutes les dates depuis 1900 ?
Non. En fait il y a mêmes des implémentations classiques et conformes (sur ce point) qui ne remontent pas avant 1980...
De plus, tu as mélangé time_t et les spécifications de struct tm ; hors rien n'oblige à ce le premier couvre le même domaine que le second, et surtout pas les spécifications de mktime() (la fonction que passe de l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du calendrier ne peut être représenté...
Antoine
candide
Antoine Leca a écrit :
surtout pas les spécifications de mktime() (la fonction que passe de l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du calendrier ne peut être représenté...
OK, merci de ta réponse. Ce que je retiens de tout ça, c'est en particulier qu'il faut tester le retour de mktime().
Antoine Leca a écrit :
surtout pas les spécifications de mktime() (la fonction que passe de
l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du
calendrier ne peut être représenté...
OK, merci de ta réponse. Ce que je retiens de tout ça, c'est en particulier
qu'il faut tester le retour de mktime().
surtout pas les spécifications de mktime() (la fonction que passe de l'autre à l'un) qui prévoit explicitement des cas où la date-et-heure-du calendrier ne peut être représenté...
OK, merci de ta réponse. Ce que je retiens de tout ça, c'est en particulier qu'il faut tester le retour de mktime().
candide
Eric Levenez a écrit :
1900 est juste l'offset, pas la date de départ, l'"Epoch".
Oui, effectivement, on peut voir les choses comme ça.
Eric Levenez a écrit :
1900 est juste l'offset, pas la date de départ, l'"Epoch".
Oui, effectivement, on peut voir les choses comme ça.
1900 est juste l'offset, pas la date de départ, l'"Epoch".
Oui, effectivement, on peut voir les choses comme ça.
Xavier Roche
candide a écrit :
Sous Windows chez moi, c'est encore pire, ça ne marche qu'à partir du 2 janvier 1970 (Mingw et Visual C++).
A priori c'est un bug de la libc (enfin, de la couche de ""compatibilité"" POSIX) sous Windows, qui ne gère pas correctement les valeurs négatives (time_t est signé, même si ce n'est pas toujours explicitement dit)
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de 2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter le bug de l'an 2038 avec le remplacement progressif des 32-bit par du 64-bit pur)
candide a écrit :
Sous Windows chez moi, c'est encore pire, ça ne marche qu'à partir du 2 janvier
1970 (Mingw et Visual C++).
A priori c'est un bug de la libc (enfin, de la couche de
""compatibilité"" POSIX) sous Windows, qui ne gère pas correctement les
valeurs négatives (time_t est signé, même si ce n'est pas toujours
explicitement dit)
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter
le bug de l'an 2038 avec le remplacement progressif des 32-bit par du
64-bit pur)
Sous Windows chez moi, c'est encore pire, ça ne marche qu'à partir du 2 janvier 1970 (Mingw et Visual C++).
A priori c'est un bug de la libc (enfin, de la couche de ""compatibilité"" POSIX) sous Windows, qui ne gère pas correctement les valeurs négatives (time_t est signé, même si ce n'est pas toujours explicitement dit)
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de 2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter le bug de l'an 2038 avec le remplacement progressif des 32-bit par du 64-bit pur)
Eric Levenez
Le 06/03/09 18:32, dans <gormmu$cfm$, « Xavier Roche » a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter le bug de l'an 2038 avec le remplacement progressif des 32-bit par du 64-bit pur)
Avec un time_t de 64 bits il ne devrait pas y avoir de problème après 2038. Mais les programmes 32 bits auront sûrement des problèmes (même sur les OS 64 bits).
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type :
if (mktime(x) < 0)
Au lieu de :
if (mktime(x) == (time_t)-1)
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 18:32, dans <gormmu$cfm$1@news.httrack.net>, « Xavier Roche »
<xroche@free.fr.NOSPAM.invalid> a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au
même :-)
2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter
le bug de l'an 2038 avec le remplacement progressif des 32-bit par du
64-bit pur)
Avec un time_t de 64 bits il ne devrait pas y avoir de problème après 2038.
Mais les programmes 32 bits auront sûrement des problèmes (même sur les OS
64 bits).
Je pense qu'un time_t négatif est possible (après 2038), mais comme
certaines fonctions retournent -1, beaucoup de programmes ont fait du code
du type :
if (mktime(x) < 0)
Au lieu de :
if (mktime(x) == (time_t)-1)
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 18:32, dans <gormmu$cfm$, « Xavier Roche » a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
2038/1902 n'est ainsi vraie qu'en 32-bit -- on peut ainsi espérer éviter le bug de l'an 2038 avec le remplacement progressif des 32-bit par du 64-bit pur)
Avec un time_t de 64 bits il ne devrait pas y avoir de problème après 2038. Mais les programmes 32 bits auront sûrement des problèmes (même sur les OS 64 bits).
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type :
if (mktime(x) < 0)
Au lieu de :
if (mktime(x) == (time_t)-1)
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Xavier Roche
Eric Levenez a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en général time_t est aussi en 64-bit".
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type : if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas vraiment un code d'erreur.
Indice: * (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT"" * (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Bon alors là on prend un cachet d'aspirine, et on jette un oeil à POSIX en priant:
<http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html> "If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1 and may set errno to indicate the error."
Perdu: si ça renvoi (time_t) -1, "démerdez-vous avec l'implémentation".
Typiquement sous WIN32, il est sage d'aller calculer à la main le mktime avec les fonctions WIN32 (SystemTimeToFileTime et KB167296), et sous Linux on peut se permettre royalement:
errno = 0; if ( ( t = mktime(x) ) != (time_t) -1 || errno == 0) { .. c'est tout bon }
Eric Levenez a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au
même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça
que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en
général time_t est aussi en 64-bit".
Je pense qu'un time_t négatif est possible (après 2038), mais comme
certaines fonctions retournent -1, beaucoup de programmes ont fait du code
du type :
if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas
vraiment un code d'erreur.
Indice:
* (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT""
* (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Bon alors là on prend un cachet d'aspirine, et on jette un oeil à POSIX
en priant:
<http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html>
"If the time since the Epoch cannot be represented, the function shall
return the value (time_t)-1 and may set errno to indicate the error."
Perdu: si ça renvoi (time_t) -1, "démerdez-vous avec l'implémentation".
Typiquement sous WIN32, il est sage d'aller calculer à la main le mktime
avec les fonctions WIN32 (SystemTimeToFileTime et KB167296), et sous
Linux on peut se permettre royalement:
errno = 0;
if ( ( t = mktime(x) ) != (time_t) -1 || errno == 0) {
.. c'est tout bon
}
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en général time_t est aussi en 64-bit".
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type : if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas vraiment un code d'erreur.
Indice: * (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT"" * (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Bon alors là on prend un cachet d'aspirine, et on jette un oeil à POSIX en priant:
<http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html> "If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1 and may set errno to indicate the error."
Perdu: si ça renvoi (time_t) -1, "démerdez-vous avec l'implémentation".
Typiquement sous WIN32, il est sage d'aller calculer à la main le mktime avec les fonctions WIN32 (SystemTimeToFileTime et KB167296), et sous Linux on peut se permettre royalement:
errno = 0; if ( ( t = mktime(x) ) != (time_t) -1 || errno == 0) { .. c'est tout bon }
Eric Levenez
Le 06/03/09 19:54, dans <gorrhr$cfm$, « Xavier Roche » a écrit :
Eric Levenez a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en général time_t est aussi en 64-bit".
Mais sous Unix, Gnu/Linux, Mac OS X... time_t est quasiment tout le temps un typedef de "long" (c'est en fait dur de trouver une autre définition). Le monde Windows est à part bien sûr...
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type : if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas vraiment un code d'erreur.
Indice: * (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT"" * (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 19:54, dans <gorrhr$cfm$2@news.httrack.net>, « Xavier Roche »
<xroche@free.fr.NOSPAM.invalid> a écrit :
Eric Levenez a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au
même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça
que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en
général time_t est aussi en 64-bit".
Mais sous Unix, Gnu/Linux, Mac OS X... time_t est quasiment tout le temps un
typedef de "long" (c'est en fait dur de trouver une autre définition). Le
monde Windows est à part bien sûr...
Je pense qu'un time_t négatif est possible (après 2038), mais comme
certaines fonctions retournent -1, beaucoup de programmes ont fait du code
du type :
if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas
vraiment un code d'erreur.
Indice:
* (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT""
* (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini
les limites d'utilisation des fonctions pour que le -1 ne soit pas une
valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation
va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 19:54, dans <gorrhr$cfm$, « Xavier Roche » a écrit :
Eric Levenez a écrit :
A noter que, en général, sizeof(time_t) == sizeof(void*) (la limite de
En général sizeof(time_t) == sizeof(long int), ce qui revient parfois au même :-)
Hélas sizeof(long int) == 4 dans tous les cas sous WIN32, c'est pour ça que j'avais pris sizeof(void*) pour dire "quand le code est 64-bit, en général time_t est aussi en 64-bit".
Mais sous Unix, Gnu/Linux, Mac OS X... time_t est quasiment tout le temps un typedef de "long" (c'est en fait dur de trouver une autre définition). Le monde Windows est à part bien sûr...
Je pense qu'un time_t négatif est possible (après 2038), mais comme certaines fonctions retournent -1, beaucoup de programmes ont fait du code du type : if (mktime(x) < 0)
Bon alors en fait c'est beaucoup plus hilarant, car -1 n'est pas vraiment un code d'erreur.
Indice: * (time_t) 0 c'est "01 Jan 1970 00:00:00 GMT"" * (time_t) -1 c'est "31 Dec 1969 23:59:59 GMT"
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Xavier Roche
Eric Levenez a écrit :
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est _vraiment_ un entier signé.
memset(&tm, 0, sizeof(tm)); tm.tm_mday = 1; for(i = 1980 ; i > 1900 ; i -= 10) { time_t t; tm.tm_year = i - 1900; if ( ( t = mktime(&tm) ) != (time_t) -1 || errno == 0 ) { printf("%u: time_t == %dn", i, (int) t); } else { abort(); } }
return 0; }
Eric Levenez a écrit :
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini
les limites d'utilisation des fonctions pour que le -1 ne soit pas une
valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation
va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est
_vraiment_ un entier signé.
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est _vraiment_ un entier signé.
memset(&tm, 0, sizeof(tm)); tm.tm_mday = 1; for(i = 1980 ; i > 1900 ; i -= 10) { time_t t; tm.tm_year = i - 1900; if ( ( t = mktime(&tm) ) != (time_t) -1 || errno == 0 ) { printf("%u: time_t == %dn", i, (int) t); } else { abort(); } }
return 0; }
Eric Levenez
Le 06/03/09 20:29, dans <gorti0$cfm$, « Xavier Roche » a écrit :
Eric Levenez a écrit :
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est _vraiment_ un entier signé.
Tu généralises ton implémentation. Certaines implémentations gèrent les time_t négatif (hors -1), d'autres pas. Il est vrai que sur les systèmes de type unix, time_t est normalement un entier signé, mais ce n'est pas une règle. Sur QNX, le valeur est non signée, et permet donc d'aller jusqu'à 2106, et pas mal de systèmes embarqués avaient fait ce choix. Sur les OS grand public, la règle semble être : "on passera en 64 bits, et ça sera réglé".
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 20:29, dans <gorti0$cfm$3@news.httrack.net>, « Xavier Roche »
<xroche@free.fr.NOSPAM.invalid> a écrit :
Eric Levenez a écrit :
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini
les limites d'utilisation des fonctions pour que le -1 ne soit pas une
valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation
va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est
_vraiment_ un entier signé.
Tu généralises ton implémentation. Certaines implémentations gèrent les
time_t négatif (hors -1), d'autres pas. Il est vrai que sur les systèmes de
type unix, time_t est normalement un entier signé, mais ce n'est pas une
règle. Sur QNX, le valeur est non signée, et permet donc d'aller jusqu'à
2106, et pas mal de systèmes embarqués avaient fait ce choix. Sur les OS
grand public, la règle semble être : "on passera en 64 bits, et ça sera
réglé".
--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Le 06/03/09 20:29, dans <gorti0$cfm$, « Xavier Roche » a écrit :
Eric Levenez a écrit :
Si, si, -1 est bien un code d'erreur, et c'est l'implémentation qui défini les limites d'utilisation des fonctions pour que le -1 ne soit pas une valeur valide. Ainsi sur une machine typique 32 bits, la plage d'utilisation va de 1970 à 2038, et le 1969 que tu donnes est hors borne.
Non, non. C'est bien de 1900-et-des-poussières à 2038, time_t est _vraiment_ un entier signé.
Tu généralises ton implémentation. Certaines implémentations gèrent les time_t négatif (hors -1), d'autres pas. Il est vrai que sur les systèmes de type unix, time_t est normalement un entier signé, mais ce n'est pas une règle. Sur QNX, le valeur est non signée, et permet donc d'aller jusqu'à 2106, et pas mal de systèmes embarqués avaient fait ce choix. Sur les OS grand public, la règle semble être : "on passera en 64 bits, et ça sera réglé".
-- Éric Lévénez FAQ de fclc : <http://www.levenez.com/lang/c/faq/>