JSR 310 :: System.currentTimeMillis() vs Instant.toEpochMilli() :: Fuseau horaire
Pourriez vous s'il vous plaît jeter une certaine lumière sur la façon d'obtenir correcte époque le temps en millisecondes pour un fuseau horaire par défaut du système et compte tenu de fuseau horaire.
Donné
1. Fuseau horaire: GMT+3
2. L'extrait de code suivant:
import java.time.*;
public class Main {
public static void main(String[] args) {
System.out.println(LocalDateTime
.now()
.atZone(ZoneOffset.UTC)
.toInstant()
.toEpochMilli()
);
System.out.println(LocalDateTime
.now()
.atZone(ZoneOffset.of("+3"))
.toInstant()
.toEpochMilli()
);
System.out.println(System.currentTimeMillis());
}
}
3. Sortie:
1444158955508
1444148155508
1444148155508
4. JavaDoc pour Système.currentTimeMillis() qui indique que la valeur retournée sera la différence, mesurée en millisecondes, entre l'heure actuelle et à minuit, le 1er janvier 1970 UTC.
Alors, pourquoi
- la sortie de la
LocalDateTime
àGMT+3
est le même que celui deSystem.currentTimeMillis()
, bien que les docs pour laSystem.currentTimeMillis()
mentionUTC
? - la sortie de la
LocalDateTime
àUTC
diffère deSystem.currentTimeMillis()
, bien que les docs pour laSystem.currentTimeMillis()
mentionUTC
?
Vous devez vous connecter pour publier un commentaire.
Les deux
System.currentTimeMillis()
etInstant.toEpochMilli()
retourne le nombre de millisecondes écoulées depuis l'époque Unix. Ce n'est pas "dans" un moment particulier de la zone, bien que l'époque Unix est normalement exprimée comme "minuit le 1er janvier 1970 UTC". Mais un instant est un instant dans le temps, et c'est la même quel fuseau horaire vous êtes - mais il faudra réfléchir à une autre heure locale.La sortie de
LocalDateTime.atZone(UTC)
diffère parce que vous êtes en train de dire "Prendre la date et l'heure locales, et de la convertir en un instant comme si elle était dans le fuseau horaire UTC", même si, quand vous avez créé quiLocalDateTime
vous n'avez donc implicitement à l'UTC+3 fuseau horaire... c'est pourquoi il est "mauvais".LocalDateTime.now()
prend la date et l'heure locales dans le système de fuseau horaire par défaut. Donc, si votre fuseau horaire est UTC+3, le courant instantané dans le temps est 2015-10-06T16:57:00Z, puisLocalDateTime.now()
sera de retour.2015-10-06T19:57:00
. Disons quelocalNow
...Donc
localNow.atZone(ZoneOffset.of("+3"))
sera de retour d'uneZonedDateTime
représentant 2015-10-06T19:57:00+03 - en d'autres termes, la même date/heure, mais "savoir" qu'il est 3 heures à l'avance de l'heure UTC... donctoInstant()
sera de retour uneInstant
représentant 2015-10-06T16:57:00Z. La Great - nous en avons encore la date/heure actuelle.Mais
localNow.atZone(ZoneOffset.UTC)
sera de retour d'uneZonedDateTime
représentant 2015-10-06T19:57:00Z - en d'autres termes, la même date/heure, mais la "pensée", qu'il est déjà l'heure UTC... donctoInstant()
sera de retour uneInstant
représentant 2015-10-06T19:57:00Z.. ce qui n'est pas à l'heure actuelle à tous (c'est dans trois heures).Version courte:
Il n'y a aucun moyen de calculer
LocalDateTime -> Instant
, vous devez spécifier un fuseau horaire.Avec un fuseau horaire, vous obtenez un
ZonedDateTime
et peut calculerZonedDateTime -> Instant
Instant == System.currentTimeMillis()
si le fuseau horaire de la ZonedDateTime est égale à la valeur par défaut du système de fuseau horaire.Version longue:
LocalDateTime est à l'heure votre horloge(en plus de l'information de date). Ce qui n'est pas assez si vous ne nous dites pas ce qui le fuseau horaire de votre sont. 13:00 heures à Tokyo n'est pas le même Instant que de 13:00 heures de Paris.
Une fois que vous ajoutez un fuseau horaire de votre LocalDateTime vous obtenez un ZonedDateTime et on peut savoir à quel moment de temps vous êtes réellement. E. g. êtes-vous à 13:00 heures à Tokyo ou à Paris?
Pour obtenir le bon Instant le fuseau horaire de la ZonedDateTime doit être correcte. Si elle est de 13:00 heures à Tokyo, mais vous prétendez que vous êtes à 13:00 heures de Paris, vous obtiendrez un mauvais Instantanée.
LocalDateTime:
ZonedDateTime:
Pour obtenir un Instant vous avez besoin de convertir LocalDateTime à ZonedDateTime premier. Si vous avez fait ceci correctement(en indiquant le bon fuseau horaire) votre Instant d'accord avec le Système.currentTimeMillis().
Système.currentTimeMillis():
Si votre fuseau horaire est GMT+3 puis ZonedDateTime.toInstant() vous donnera le bon Instant et, par conséquent, d'accord avec Système.currentTimeMillis()
Si votre fuseau horaire est pas UTC puis ZonedDateTime.toInstant() vous donnera une incorrect Instant.