[JAVA] L'histoire selon laquelle traiter d'anciennes dates est agaçante

Aperçu

En général, je pense que le traitement des dates en programmation est un processus assez fastidieux, mais je vais vous dire que ce sera plus gênant lorsqu'il s'agit d'anciennes dates. L'exemple de code est écrit en Java, mais je pense que des problèmes similaires se produiront dans d'autres langues.

Environnement d'exploitation

Texte

Cas 1: le décalage du fuseau horaire devient "+09: 18: 59"

LocalDateTime.of(1887, 1, 1, 0, 0).atZone(ZoneId.of("Asia/Tokyo"));
// 1887-01-01T00:00+09:18:59[Asia/Tokyo]

Le décalage de fuseau horaire dans l'heure standard du Japon est essentiellement "+09: 00", mais si vous spécifiez 1887, le décalage de fuseau horaire est "+09: 18: 59". Étant donné que les secondes sont également incluses et qu'il est différent du format général, par exemple, si cette valeur est générée sur le serveur et renvoyée au client, des problèmes tels qu'un échec lors de l'analyse avec du code JavaScript sur le côté frontal peuvent survenir. (arrivé)

Cause

C'est parce que la base de données tz le fait réellement. Comme son nom l'indique, la base de données tz est une base de données d'informations sur les fuseaux horaires. En Java, il est fourni avec JRE et référencé par la bibliothèque qui gère la date et l'heure en Java.

L'heure standard japonaise actuelle a commencé le 1er janvier 1888 et elle était différente avant cela, ce qui est reflété dans la base de données tz.

Cas 2: la date saute pendant 10 jours

Voici un exemple où le résultat change entre l'ancienne API et la nouvelle API après Java 8.

D'abord de l'ancienne API.

var cal = Calendar.getInstance();
cal.clear();
cal.set(1582, Calendar.OCTOBER, 4);

var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.format(cal.getTime());    // "1582-10-04 00:00:00"

J'ai spécifié 1582/10/4 et il a été sorti tel quel. Alors qu'en est-il de la nouvelle API?

var cal = Calendar.getInstance();
cal.clear();
cal.set(1582, Calendar.OCTOBER, 4);

LocalDateTime.ofInstant(cal.toInstant(), ZoneId.of("Asia/Tokyo"));
// 1582-10-14T00:18:59

Il était hors de 10 jours.

Cause

En effet, différentes bibliothèques les traitent différemment avant le 15 octobre 1582. Le 15 octobre 1582 est une date spéciale, le jour où le calendrier Gregorio actuel a été introduit. Avant cela, le calendrier Julius était utilisé. Par conséquent, il est divisé en une bibliothèque qui traite la veille du 15 octobre 1582 comme le calendrier Julius tel quel, et une bibliothèque qui le traite comme un pseudo calendrier Gregorio (à partir du calendrier Gregorio). En Java, l'ancienne API est l'ancienne et la nouvelle Le résultat a changé car l'API est différente de cette dernière.

En outre, la transition du calendrier Julius au calendrier Gregorio a été effectuée sous la forme que le jour après le 4 octobre 1582 dans le calendrier Julius a été fixé au 15 octobre 1582 dans le calendrier Gregorio. En d'autres termes, il a volé pendant 10 jours, de sorte que la différence est ressortie telle qu'elle résultait du traitement de la bibliothèque de dates.

Cas 3: le décalage du fuseau horaire est décalé d'une heure

LocalDateTime.of(1950, 8, 1, 0, 0).atZone(ZoneId.of("Asia/Tokyo"));
// 1950-08-01T00:00+10:00[Asia/Tokyo]

Le décalage de fuseau horaire dans l'heure standard japonaise est essentiellement "+09: 00". (Deuxième fois) Cependant, ce résultat est "+10: 00".

Cause

Identique au cas 1, mais parce que la base de données tz le fait réellement. En ce qui concerne l'actualité, il y a eu beaucoup de bruit il y a quelque temps en essayant d'introduire l'heure d'été pour les Jeux olympiques de Tokyo. Beaucoup d'entre vous le savent peut-être en regardant les actualités à cette époque, mais au Japon, l'heure d'été a été introduite vers 1949-1951. Cela est fidèlement reflété dans la base de données tz.

Résumé

Lien de référence

http://nowokay.hatenablog.com/entries/2015/01/09 https://ja.wikipedia.org/wiki/Tz_database http://www.mwsoft.jp/programming/other/time_mendoi.html https://qiita.com/sota2502/items/e8df68d9cfebd01af809

Recommended Posts

L'histoire selon laquelle traiter d'anciennes dates est agaçante
Une histoire sur la connexion à un serveur CentOS 8 avec un ancien Ansible
[Android] Comment gérer les thèmes sombres
C'est bien d'aller dans une école de programmation.
Si vous voulez créer un fichier zip avec Ruby, c'est rubyzip.
Comment gérer les actifs de précompilation a échoué.
Défi pour gérer les caractères déformés avec Java AudioSystem.getMixerInfo ()
[Rails] rails nouveau pour créer une base de données avec PostgreSQL
Convertissez une chaîne en un tableau caractère par caractère avec Swift
Transition vers un contrôleur de vue avec Swift WebKit
Ripper un CD en MP3 avec Ubuntu 18.04 LTS
J'ai essayé de casser le bloc avec java (1)
[Docker] Comment mettre à jour à l'aide d'un conteneur dans Heroku et comment gérer l'erreur de migration
Comment gérer les erreurs dans Rails? Impossible de trouver un runtime JavaScript.
Minecraft BE Tap avec une épée en bois pour sauter
Soumettre une tâche à AWS Batch avec Java (Eclipse)
Programme de régime avec préprocesseur (comment gérer la taille i-appli)
Compte tenu de l'éditeur de propriétés utilisé dans SpringToolSuite (STS)
Comment supprimer un objet new_record construit avec Rails
Comment traiter Aucun modèle de demande interactive
Comment générer manuellement un JWT avec Knock in Rails
[Environnement Docker] Comment gérer ActiveSupport :: MessageEncryptor :: InvalidMessage
Je souhaite surveiller un fichier spécifique avec WatchService
Une histoire d'essayer de s'entendre avec Mockito
[Comment insérer une vidéo dans un hameau avec Rails]
[Rails] Comment gérer les modifications d'URL après le rendu
Refus d'installer un package avec le nom "webpack" sous un package
Une histoire sur la réduction de la consommation de mémoire à 1/100 avec find_in_batches
[Java] Comment rompre une ligne avec StringBuilder
Ce n'est pas un gros problème si vous comprenez que j'étais accro à recevoir du courrier avec Java Mail depuis Exchange Online