[java] Pourquoi soustraire ces deux temps (en 1927) en donnant un résultat étrange?



Answers

Vous avez rencontré une discontinuité temporelle locale :

Lorsque l'heure locale locale était sur le point d'atteindre dimanche, le 1er janvier 1928, les horloges de 00:00:00 ont été retournées 0:05:52 heures au samedi, 31. décembre 1927, 23:54:08 heure locale standard à la place

Ce n'est pas particulièrement étrange et cela s'est passé à peu près partout à un moment ou à un autre car les fuseaux horaires ont été changés ou changés en raison d'actions politiques ou administratives.

Question

Si j'exécute le programme suivant, qui analyse deux chaînes de date faisant référence à des temps d'une seconde et les compare:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

La sortie est:

353

Pourquoi ld4-ld3 n'est pas 1 (comme je m'attendrais à la différence d'une seconde dans le temps), mais 353 ?

Si je change les dates aux heures 1 seconde plus tard:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";  

Alors ld4-ld3 sera 1 .

Version Java:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)

Timezone(`TimeZone.getDefault()`):

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]

Locale(Locale.getDefault()): zh_CN



Lorsque vous incrémentez le temps, vous devez revenir à UTC, puis ajouter ou soustraire. Utilisez l'heure locale uniquement pour l'affichage.

De cette façon, vous serez en mesure de marcher à travers les périodes où les heures ou les minutes se produisent deux fois.

Si vous avez converti en UTC, ajoutez chaque seconde et convertissez en heure locale pour l'affichage. Vous passeriez par 23:54:08 pm LMT - 23:59:59 pm LMT et puis 23:54:08 pm CST - 23:59:59 CST.




IMHO la localisation implicite omniprésente dans Java est son plus grand défaut de conception. Il peut être destiné aux interfaces utilisateur, mais franchement, qui utilise vraiment Java pour les interfaces utilisateur aujourd'hui, sauf pour certains IDE où vous pouvez essentiellement ignorer la localisation parce que les programmeurs ne sont pas exactement le public cible pour cela. Vous pouvez le réparer (en particulier sur les serveurs Linux) en:

  • export LC_ALL = C TZ = UTC
  • réglez l'horloge de votre système sur UTC
  • N'utilisez jamais de mises en œuvre localisées à moins que ce ne soit absolument nécessaire (c'est-à-dire pour l'affichage uniquement)

Aux membres du processus de communauté Java , je recommande:

  • Les méthodes localisées ne sont pas celles par défaut, mais nécessitent que l'utilisateur demande explicitement la localisation.
  • utilisez plutôt UTF-8 / UTC comme valeur par défaut FIXED parce que c'est simplement la valeur par défaut aujourd'hui. Il n'y a aucune raison de faire autre chose, sauf si vous voulez produire des discussions comme celle-ci.

Je veux dire, allez, les variables statiques globales ne sont-elles pas un modèle anti-OO? Rien d'autre sont ces défauts omniprésents donnés par quelques variables d'environnement rudimentaires .......




Je suis désolé de le dire, mais la discontinuité du temps a bougé un peu

JDK 6 il y a deux ans, et dans JDK 7 tout récemment dans la mise à jour 25 .

Leçon à apprendre: éviter les heures non UTC à tout prix, sauf, peut-être, pour l'affichage.




Related