web-dev-qa-db-fra.com

Comment faire date.getTime () renvoie l'heure UTC?

J'ai un objet Date qui représente une heure UTC. Lorsque j'utilise la méthode getTime () pour obtenir la valeur longue de cet objet, la valeur renvoyée correspond à notre heure locale (centre des États-Unis). Quelle est la bonne façon de récupérer la valeur qui correspond à l'heure UTC d'origine?

Merci

18
flyingfromchina

La classe DateFormat a une méthode pour définir votre fuseau horaire préféré , et il existe une classe de fuseau horaire qui a un paramètre pour l'heure UTC .

Donc, par exemple,

SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);
22
Pops

Java.util.Date n'a pas de concept de fuseau horaire. Il tient simplement le temps par rapport à Epoch, qui est le 1 janvier 1970 00:00:00 UTC. La date est un modèle, distinct de la vue. Lorsque vous affichez la date, le concept de fuseau horaire est ensuite appliqué. Date's toString () affiche une date lisible par l'homme dans le fuseau horaire par défaut. Vous pouvez soit utiliser une DateFormat pour afficher une date dans un fuseau horaire différent (tel que UTC), ou modifier le fuseau horaire par défaut de la machine virtuelle Java.

22
Steve Kuo

tl; dr

Instant.now()

…et…

Instant.ofEpochMilli( n ) 

…et…

instant.toEpochMilli()

Date est toujours en UTC

Lorsque j'utilise la méthode getTime () pour obtenir la valeur longue de cet objet, la valeur renvoyée correspond à notre heure locale (au centre des États-Unis).

Non, la valeur renvoyée par Date::getTime() correspond toujours à UTC (pratiquement la même chose que GMT dans ce contexte). Pour citer le document de classe:

Renvoie le nombre de millisecondes depuis le 1er janvier 1970, 00:00:00 GMT représenté par cet objet Date.

Votre question n'a donc aucun sens en ce sens qu'une Date est déjà en UTC. Pas besoin de "récupérer la valeur qui correspond à l'heure UTC d'origine",

Vous pouvez confondre le comportement de getTime avec celui de la méthode toString. La méthode toString applique de manière gênante et déroutante le fuseau horaire par défaut actuel lors de la génération de la chaîne. Ainsi, la sortie de chaîne apparaît avec un fuseau horaire alors qu’en fait, aucun fuseau horaire ne doit être défini ou obtenu à partir de la variable Date elle-même. (Il existe en réalité une zone au cœur de la variable Date, mais elle n’est pas pertinente pour la présente discussion. Cette classe est un désordre déroutant!)

Java.time

La manière moderne de faire cela utilise des classes Java.time.

Instant

La classe Instant représente un moment sur la ligne temporelle en UTC avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une fraction décimale). 

Obtenez le moment actuel.

Instant instant = Instant.now();

Vous pouvez convertir une Date en son remplacement moderne en appelant l'une des nouvelles méthodes de conversion ajoutées aux anciennes classes date-heure. Il suffit d'appeler toInstant, assez facile.

Instant instant = myJavaUtilDate.toInstant();  

Je ne recommande pas du tout l’utilisation d’un nombre à compter de l’époque comme moyen de suivi du temps. Utilisez plutôt les objets Java.time. En dehors de Java, sérialiser en texte utilise les formats ISO 8601

Mais si vous devez, vous pouvez extraire un compte de millisecondes depuis l’époque du 1970-01-01T00: 00: 00Z. Notez que cela peut impliquer une perte de données! Un Instant a une résolution plus fine de nanosecondes. Donc, aller en millisecondes peut couper une fraction de la fraction de seconde.

long millisecondsSinceEpoch = instant.toEpochMilli();  // Caution: Possible data-loss in going from nanoseconds to milliseconds.

Aller dans l'autre sens, d'un compte à un Instant.

Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;

À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes problématiques héritées _ date-heure telles que Java.util.Date , Calendar _, & SimpleDateFormat .

Le projet Joda-Time , désormais en mode maintenance , conseille de migrer vers les classes Java.time .

Pour en savoir plus, consultez le Tutoriel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Où obtenir les classes Java.time? 

  • Java SE 8 et SE 9 et versions ultérieures
    • Intégré. 
    • Une partie de l'API Java standard avec une implémentation fournie.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et SE 7
    • Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts à Java.time. Vous pouvez y trouver des classes utiles telles que Interval _, YearWeek , YearQuarter _ et plus _.

20
Basil Bourque

getTime() renvoie "le nombre de millisecondes depuis le 1er janvier 1970, 00:00:00 GMT", rien de plus, rien de moins (vous devez évidemment le créer correctement). Vous pouvez le formater comme vous le souhaitez, en commençant par ex. le constructeur GregorianCalendar(TimeZone).

7
Matthew Flaschen

La plupart des fonctions de la classe Date sont obsolètes car elles sont maintenant déplacées dans la classe Calendar.

Voici le code pour obtenir l'heure UTC à partir du calendrier.

Date date = new Date(timeStamp);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);

Voici l'exemple de code pour obtenir l'année, le mois, etc.

System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));

Calendrier prend également en charge de nombreuses autres informations utiles, telles que TIME, DAY_OF_MONTH, etc. Voici la documentation les répertoriant toutes. Notez que le mois est basé sur 0. Janvier est le 0ème mois.

0
Amol Dixit