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




java timezone utc (6)

Au lieu de convertir chaque date, vous utilisez le code suivant

long difference = (sDt4.getTime() - sDt3.getTime()) / 1000;
System.out.println(difference);

Et voir le résultat est:

1

https://code.i-harness.com

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

C'est un changement de fuseau horaire le 31 décembre à Shanghai.

Voir cette page pour plus de détails sur 1927 à Shanghai. À la fin de 1927, à minuit, les horloges remontaient à 5 minutes et 52 secondes. Donc, "1927-12-31 23:54:08" est en fait arrivé deux fois, et il semble que Java l’analyse comme l’instant le plus tard possible pour cette date / heure locale - d’où la différence.

Juste un autre épisode dans le monde souvent étrange et merveilleux des fuseaux horaires.

EDIT: Arrêtez appuyez! L'histoire change ...

La question initiale ne démontrerait plus le même comportement si elle était reconstruite avec la version 2013a de TZDB . En 2013a, le résultat serait de 358 secondes, avec un temps de transition de 23:54:03 au lieu de 23:54:08.

Je l’ai seulement remarqué parce que je collecte des questions comme celle-ci dans Noda Time, sous la forme de TZDB ... Le test a maintenant été modifié, mais il va sans dire: même les données historiques ne sont pas sûres.

EDIT: L' histoire a encore changé ...

Dans TZDB 2014f, l'heure du changement a été déplacée vers 1900-12-31, et il ne s'agit maintenant que d'un changement de 343 secondes (le temps entre t et t+1 est donc de 344 secondes, si vous voyez ce que je veux dire).

EDIT: Pour répondre à une question sur une transition à 1900 ... il semblerait que l’implémentation du fuseau horaire Java traite tous les fuseaux horaires comme étant simplement à leur heure normale pour tout instant avant le début de l’heure UTC:

import java.util.TimeZone;

public class Test {
    public static void main(String[] args) throws Exception {
        long startOf1900Utc = -2208988800000L;
        for (String id : TimeZone.getAvailableIDs()) {
            TimeZone zone = TimeZone.getTimeZone(id);
            if (zone.getRawOffset() != zone.getOffset(startOf1900Utc - 1)) {
                System.out.println(id);
            }
        }
    }
}

Le code ci-dessus ne produit aucune sortie sur ma machine Windows. Ainsi, tout fuseau horaire qui a un décalage autre que celui standard au début de 1900 comptera cela comme une transition. TZDB elle-même a des données qui remontent plus tôt que cela et ne se fie à aucune idée d'heure standard "fixe" (ce que getRawOffset suppose être un concept valide), les autres bibliothèques n'ont donc pas à introduire cette transition artificielle.


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 .......


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.


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.


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.







timezone