java timezone date - Pourquoi soustraire ces deux fois (en 1927) donne un résultat étrange?





4 Answers

Vous avez rencontré une discontinuité de l'heure locale :

Lorsque l'heure standard locale était sur le point d'atteindre le dimanche 1er janvier 1928, les horloges étaient remises en arrière de 0:05:52 heures au samedi 31 décembre, à 19h54 (heure locale).

Cela n’est pas particulièrement étrange et s’est produit un peu partout à un moment ou à un autre, car les fuseaux horaires ont été modifiés ou modifiés en raison d’actes politiques ou administratifs.

get list example

Si j'exécute le programme suivant, qui analyse deux chaînes de date faisant référence à une seconde d'intervalle 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 ld4-ld3 pas 1 (comme je l'attendrais de la différence d'une seconde dans les temps), mais 353 ?

Si je change les dates en fois 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 reconvertir en UTC, puis ajouter ou soustraire. Utilisez l'heure locale uniquement pour l'affichage.

De cette façon, vous serez capable de traverser toutes les périodes où des heures ou des minutes se répètent deux fois.

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




Je suis désolé de le dire, mais la discontinuité temporelle a un peu évolué

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

Leçon à apprendre: évitez à tout prix les heures non-UTC, à l'exception peut-être de l'affichage.




IMHO, la localisation implicite et omniprésente en Java est son principal défaut de conception. C’est peut-être destiné aux interfaces utilisateur, mais franchement, qui utilise réellement Java pour les interfaces utilisateur aujourd’hui, à l’exception de certains IDE pour lesquels vous pouvez ignorer la localisation, car les programmeurs ne sont pas exactement le public cible. Vous pouvez le réparer (en particulier sur les serveurs Linux) en:

  • export LC_ALL = C TZ = UTC
  • régler votre horloge système sur UTC
  • n'utilisez jamais d'implémentations localisées sauf en cas d'absolue nécessité (par exemple, pour l'affichage uniquement)

Aux membres du Java Community Process , je recommande:

  • les méthodes localisées ne sont pas les méthodes 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 car il s'agit simplement de la valeur par défaut aujourd'hui. Il n'y a aucune raison de faire autre chose, sauf si vous voulez produire des threads comme celui-ci.

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




Related