Les dates en Javascript sont bizarres. Brendan Eich a écrit la première version de Javascript en 10 jours, et la fonction Date
ne fait pas exception à la règle. Elle est basée sur un code qui a finalement été supprimé en Java.
Cela signifie que Javascript a hérité d'une Fonction Date
qui s'est avérée buggy et problématique en Java, la laissant pleine de
problèmes. Vous avez peut-être même rencontré vous-même certains
problèmes. Vous vous demandez peut-être, alors, "qu'est-ce qui est si
bizarre à ce sujet?". Regardons toutes les bizarreries et les pièges
communs avec le constructeur de Date de Javascript, afin que vous
puissiez les éviter.
Javascript ne prend pas en charge les dates
Il semble contre-intuitif, étant donné que le constructeur de date Javascript principal est appelé Date, mais Javascript ne prend pas en charge les dates. Javascript ne prend en charge que les heures de date. Toutes les dates Javascript sont des horodatages Unix en dessous. Cela signifie que si nous essayons de créer une date, nous créons en fait une heure de date. Toutes les dates Javascript sans horaire spécifiés par défaut jusqu'à minuit le jour donné.
let date = new Date(2011, 1, 22);
// Notice the date produced has a time attached:
// Tue Feb 22 2011 00:00:00 GMT+0000 (Greenwich Mean Time)
(N2)
Dates de parage
Les dates d'analyse comme nous l'avons fait ci-dessus fonctionnent
bien si vous savez que les mois commencent à 0, mais l'analyse des
chaînes de date varie considérablement d'un navigateur à l'autre. Il est
fortement conseillé de ne pas analyser les chaînes de dates. Avant la
spécification ECMAScript 5, comment Date
Les
dates de chaîne parsed n'ont jamais été définies, et différents
navigateurs ont de nombreuses bizarreries historiques qui le rendent
très peu fiable.
Selon la spécification actuelle, seules les chaînes conformes à la norme ISO-8601 devraient être par pair par pairie par Javascript, et toute autre date doit être retournée. NaN
c'est-à-dire:
let parseMyDate = Date.parse('2022-03-21T11:00:01+00:00');
Ce n'est pas le cas. De nombreux
navigateurs permettent l'analyse des dates en dehors de ce format. C'est
là qu'elle a le potentiel de se prêter à confusion. Disons que vous
voulez analyser un format de date dans la norme dd/mm/yyyy
le format de la date. Vous prenez une date standard, et vous l'obtenez dans le parse()
fonction:
let myDate = new Date("5/1/2020");
console.log(myDate);
Dans tous les navigateurs modernes, cela utilise le format de date des États-Unis, c'est-à-dire. mm/dd/yyyy
- c'est-à-dire qu'il revient le 1er mai, et non le 5 janvier, qui a donné des résultats inattendus.
Défauts de parution des dates parapement en UTC
Supposons que vous ayez une date qui n'a pas de temps ou de fuseau horaire associé à celle-ci :
let myDate = Date.parse('01 Jan 1999');
console.log(myDate);
Vous pourriez penser qu'il n'y a rien de confusion immédiat à ce sujet - cela représente une date fixe dans le temps. Toutefois :
- Si votre fuseau horaire est UTC, cela reviendra
915148800000
. - Si votre fuseau horaire est UTC 3:00, ce sera de retour
915138000000
, i.e. 3 heures de plus.
Si votre fuseau horaire est UTC-5:00, cela reviendra 915166800000
, i.e. 5 heures de moins.
Donc si votre fuseau horaire est à l'ouest de UTC, par exemple, -5:00, Javascript soustrait 5 heures de l'horodatage Unix. Depuis les jours qui commencent à minuit.
Cela signifie que si nous essayons d'utiliser cet horodatage avec un fuseau horaire différent, par exemple, dans un système dorsal, nous n'aurions pas le 1er janvier 1999, nous obtenons le 31 décembre 1998 Tout cela parce que Javascript ne met pas en œuvre de dates - chaque date a une heure qui lui est associée - dans ce cas, minuit.
Les mois commencent à 0 en Javascript Dates
Si nous voulons créer une date en Javascript, nous pouvons analyser les nombres représentant l'année, le mois et le jour. Par exemple, si nous voulons créer une date pour le 22 février 2011, nous écririons ceci, n'est-ce pas ?
let date = new Date(2011, 2, 22);
Seulement, cela nous donne Tue Mar 22 2011 00:00:00 GMT+0000 (Greenwich Mean Time)
. C'est parce que des mois en Javascript commencent à compter à partir de 0, donc février est 1, pas 2:
let date = new Date(2011, 1, 22);
Dates incorrectes
Disons que vous avez accidentellement créé une date incorrecte, disons le 31 février 2022. Vous passez ceci dans votre fonction de date, par erreur, à partir d'une base de données ou d'une API:
let date = new Date(2022, 1, 31);
Vous pourriez penser que ça reviendra juste Invalid Date
ou NaN
,
mais vous auriez tort. Javascript saute jusqu'au 3 mars Étant donné que
le mois de février ne dispose que de 28 jours en 2011, et il y a trois
jours supplémentaires, ces jours sont ajoutés à la fin du mois. En
d'autres termes, vous ne pouvez pas faire confiance Date
de renvoyer des erreurs à toutes les dates incorrectes.
Les chaînes de caractères ne sont pas transformées en nombres
Le comportement le plus étrange de tous est quand nous ne donnons pas des chaînes entières à Javascript en parse. Par exemple:
let myDate = new Date("0");
console.log(myDate);
Vous pourriez penser que cela reviendra l'année 0, ou peut-être l'epoch unix, mais il revient en fait à l'an 2000 - Sat Jan 01 2000 00:00:00 GMT+0000 (Greenwich Mean Time)
.
Plus étrange encore, cependant, si nous essayons d'augmenter cela, cela commence à compter dans les mois.
console.log(new Date("5")); // Tue May 01 2001 00:00:00 GMT+0100 (British Summer Time)
console.log(new Date("11")); // Thu Nov 01 2001 00:00:00 GMT+0000 (Greenwich Mean Time)
console.log(new Date("4")); // Sun Apr 01 2001 00:00:00 GMT+0100 (British Summer Time)
Pour couronner le tout, si vous essayez de faire new Date("13")
, nous obtiendrons Invalid Date
comme résultat, puisqu'il n'y a pas de treizième mois.
Les heures des nombres sont affectées par le fuseau horaire
Si nous ne passons un numéro à new Date()
,
il le traitera comme l'horodatage Unix - cependant, il n'est pas ajusté
pour le fuseau horaire. Par exemple, en UTC, le code suivant retourne Thu Jan 01 1970 00:00:00 GMT+0000 (Greenwich Mean Time)
:
console.log(new Date(0));
C'est logique, puisque c'est l'époque d'Unix - cependant, si nous sommes en UTC-5:00, ce code revient Wed Dec 31 1969 19:00:00 GMT-0500 (Eastern Standard Time)
- c'est-à-dire 5 heures avant.
Cela signifie, par défaut, les fuseaux horaires peuvent conduire à
beaucoup de confusion - si nous nous attendions à ce que la date soit
1er janvier 1970, nous avons immédiatement un problème lorsque nous
utilisons une méthode comme Date().toLocaleString()
.
En fin de compte, nous pouvons résoudre ce problème en utilisant la méthode. .toUTCString()
- mais cette complication conduit à beaucoup de confusion.
Les années sont vraiment incohérentes
Vous avez peut-être pensé que nous nous sommes faciles à débrayer, et seuls les horodatages et les fuseaux horaires sont brisés - mais même les années sont incohérentes. Si nous voulions créer une date pour le 1er Jan, en l'an 0, vous pourriez penser que nous écrivons ceci :
console.log(new Date(0, 0, 0));
Depuis le début des mois à partir de 0, cela semble juste - mais en fait, si l'année est inférieure à 100, 0
signifie l'année 1900.
Bon, vous pourriez penser, je suppose que ça devrait revenir 1er janvier 1900
Au lieu de ça - mais c'est en fait faux aussi - puisque les jours sont indexés à partir de 1, pas 0.
Le code ci-dessus retourne Sun Dec 31 1899 00:00:00 GMT+0000 (Greenwich Mean Time)
- étant donné que le 0ème jour du mois est compté comme le dernier jour du mois précédent. Voici quelques autres exemples :
console.log(new Date(0, 0, 0)); // Sun Dec 31 1899 00:00:00 GMT+0000 (Greenwich Mean Time)
console.log(new Date(50, 0, 0)); // Sat Dec 31 1949 00:00:00 GMT+0000 (Greenwich Mean Time)
console.log(new Date(30, 0, 0)); // Tue Dec 31 1929 00:00:00 GMT+0000 (Greenwich Mean Time)
console.log(new Date(24, 0, 0)); // Mon Dec 31 1923 00:00:00 GMT+0000 (Greenwich Mean Time)
Dès que vous arrivez au-dessus de
l'année 100, il revient ensuite à compter les années normalement.
Donc le code ci-dessous nous donne en fait l'année 101, pas l'année 2001 :
console.log(new Date(101, 0, 0)); // Fri Dec 31 0100 00:00:00 GMT-0001 (Greenwich Mean Time)
Cela peut être utile si vous utilisez des années après 1900, mais c'est incroyablement contre-intuitif pour quoi que ce soit auparavant.
Pourquoi n'a-t-on pas corrigé Javascript Dates ?
La fonction Javascript Date est fondamentalement brisée à bien des égards - c'est pourquoi la plupart des gens utilisent des outils comme Moment.js, mais pourquoi n'a-t-elle pas été réparée?
La raison principale en est que la majeure partie du web a été construite sur un code qui a pris en considération les défauts de la date. En tant que tel, le changement maintenant entraînerait la rupture de nombreux sites web.
Pour remédier à cette situation, Javascript introduit un tout nouvel ensemble de normes appelé Temporal qui occupera un espace de noms différent de Date, et résoudra la plupart des problèmes décrits dans cet article. En attendant, nous devons nous contenter des bizarreries produites par Javascript Dates.
Notes:
(N1) voir source pour le code
(N2) bientot