Au cours de l'expérience récente de l'écriture d'un JS interprète j'ai beaucoup lutté avec le fonctionnement interne de l'ECMA/JS dates. Donc, je me dis que je vais le jeter dans mes 2 cents ici. Espérons que le partage de ce genre de choses va aider les autres avec des questions sur les différences entre les navigateurs dans la façon dont ils gèrent les dates.
Le Côté De L'Entrée
Toutes les implémentations de stocker leurs valeurs de date en interne comme en 64 bits des nombres qui représentent le nombre de millisecondes écoulées depuis le 1/1/1970 UTC (GMT est la même chose que l'UTC). Dates survenant après l' 1/1/1970 00:00:00
sont des nombres positifs et les dates antérieures sont négatifs.
Par conséquent, le code suivant produit exactement le même résultat sur tous les navigateurs.
Date.parse('1/1/1970');
Dans mon fuseau horaire (heure de l'est), le résultat est 18000000 parce que de nombreux états membres sont en 5 heures, c'est seulement 4 heures au cours de l'heure d'été mois). La valeur sera différente dans différents fuseaux horaires. Tous les principaux navigateurs faire la même façon.
Là est le hic. Bien qu'il existe une certaine variation dans la chaîne d'entrée les formats les principaux navigateurs va analyser comme des dates, ils sont essentiellement les interpréter de la même aussi loin que les fuseaux horaires et l'heure d'été sont concernés. Le seul à tenir est le format ISO 8601. C'est le seul format décrit dans l'ECMA-262 v. 5 spec spécifiquement. Pour tous les autres formats de chaîne, l'interprétation est dépendant de l'implémentation. Ironiquement, c'est le format où les navigateurs peuvent différer. Voici une comparaison de sortie de Chrome vs Firefox pour 1/1/1970 sur ma machine en utilisant la norme ISO 8601 format de chaîne de caractères.
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0
Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000
Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
- Le "Z" spécificateur indique que l'entrée est déjà l'heure UTC et ne nécessite pas de décalage avant le stockage.
- Le "-0500" spécificateur indique que l'entrée est à GMT-05:00 donc, à la fois
les navigateurs n'interprètent comme étant dans mon fuseau horaire local. Cela signifie que l'
la valeur est convertie à l'UTC, avant d'être stockés. Dans mon cas, cela signifie l'ajout de 18000000ms à la date de valeur interne, ce qui exige un -18000000ms (-05:00) maj pour me remettre dans l'heure locale.
- Quand il n'y a pas de spécificateur cependant, FF traite de l'entrée en heure locale, tandis que Chrome
il les traite comme de l'heure UTC. Pour moi, cela crée à 5 heures de différence dans la valeur stockée, ce qui est problématique. Dans mon application j'ai fini par le parti de la FF ici parce que j'aime la sortie de l'
toString
pour correspondre à mon entrée valeur, à moins que je spécifier un autre fuseau horaire, je ne fais jamais. L' absence d'un spécificateur devrait présumer l'heure locale de l'entrée.
Mais c'est ce qui est pire, FF traite de la forme courte du format ISO 8601 ("YYYY-MM-DD") différemment de ce qu'il traite de la forme longue ("YYYY-MM-DDTHH:mm:ss:sssZ") pour aucune raison logique que ce soit. Voici la sortie de FF avec le long et à court ISO formats de date avec un pas de temps horaire spécificateur.
Date.parse('1970-01-01T00:00:00'); // 18000000
Date.parse('1970-01-01'); // 0
Donc, pour répondre à l'original asker la question directement, "YYYY-MM-DD"
est la forme courte de la norme ISO 8601 "YYYY-MM-DDTHH:mm:ss:sssZ"
. Donc, il est interprété comme de l'heure UTC, tandis que l'autre est interprétée comme un local. C'est pourquoi,
Ce n'est pas jive:
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08")).toString());
Ce n':
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
La ligne du bas est-ce pour l'analyse des chaînes date. La SEULE norme ISO 8601 chaîne de caractères que vous pouvez analyser tous les navigateurs est la forme longue. Et, TOUJOURS utiliser le "Z" spécificateur. Si vous faites cela, vous pouvez faire l'aller-retour entre le local et l'heure UTC.
Cela fonctionne sur tous les navigateurs (après IE9):
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
Heureusement, la plupart des navigateurs actuels ne traiter les autres formats d'entrée également, y compris les plus fréquemment utilisés "1/1/1970" et "1/1/1970 00:00:00' formats. Tous les formats suivants (et les autres) sont traités comme des locaux le temps d'entrée dans tous les navigateurs et converti à l'UTC, avant le stockage. Ainsi, les rendant compatible avec tous les navigateurs. La sortie de ce code est le même dans tous les navigateurs dans mon fuseau horaire.
console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
Le Côté De Sortie
Du côté de la production, tous les navigateurs traduire les fuseaux horaires de la même façon mais ils gèrent les formats de chaîne différemment. Voici l' toString
fonctions et qu'ils sortie. Avis de l' toUTCString
et toISOString
fonctions de sortie 5:00 du matin, sur ma machine.
Convertit de l'heure UTC en heure Locale avant l'impression
- toString
- toDateString
- toTimeString
- toLocaleString
- toLocaleDateString
- toLocaleTimeString
Imprime la stockées heure UTC directement
- toUTCString
- toISOString
Dans Chrome
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString 1/1/1970 12:00:00 AM
toLocaleDateString 1/1/1970
toLocaleTimeString 00:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
Dans Firefox
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString Thursday, January 01, 1970
toLocaleTimeString 12:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
J'ai l'habitude de ne pas utiliser le format ISO pour la chaîne d'entrée. La seule fois que l'utilisation de ce format est bénéfique pour moi, c'est quand les dates doivent être triés comme des chaînes de caractères. Le format ISO est sortable comme-est, tandis que les autres ne le sont pas. Si vous disposez de la compatibilité inter-navigateur, soit spécifier le fuseau horaire ou utiliser un format de chaîne de caractères.
Le code new Date('12/4/2013').toString()
passe par la suite de pseudo-transformation:
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
J'espère que cette réponse vous a été utile.