2015-09-29 2 views
9

Je pense à utiliser le nouveau java 8 Date Time API. J'ai cherché un peu sur jodaTime et j'ai trouvé jodaTime comme un bon choix pour Java, mais je suis quand même intéressé de voir comment fonctionne cette nouvelle API.La nouvelle API Java Date Time de Java 8 prend-elle en charge DST?

Je stocke tous les temps dans les valeurs UTC dans mon datastore et les convertira en valeur spécifique de fuseau horaire local basé sur le fuseau horaire de l'utilisateur. Je peux trouver de nombreux articles montrant comment utiliser la nouvelle API Java Date Time. Cependant, je ne suis pas sûr que l'API prendra en charge les modifications DST? Ou avons-nous une meilleure façon de gérer Date? Je viens d'apprendre la nouvelle API Date, alors je pense à votre avis sur la gestion de la DateTime et l'affichage sur la base de Users TimeZone.

+3

En bref: oui, l'heure d'été est prise en compte. API Java 8 date-heure a été créée en fonction de l'heure Joda. –

+1

@Raja Je vais corriger vos termes pour éviter toute confusion ... "Local" dans le travail de date-heure signifie "pour toute localité", comme dans "Noël commence à minuit le 25 décembre 2015". Une telle date-heure locale n'a pas de fuseau horaire. En effet, il n'a aucune signification réelle jusqu'à ce que vous l'ajustiez dans un fuseau horaire spécifique. Minuit le 25 vient plus tôt à Paris qu'à Montréal. Ainsi, dans les applications commerciales courantes, nous utilisons rarement "Local". Vous récupérerez vos valeurs de date et d'heure stockées dans votre base de données, en travaillant avec eux dans votre logique métier en UTC en général, et en vous ajustant à un "ZonedDateTime" uniquement pour la présentation à un utilisateur. –

Répondre

15

cela dépend de quelle classe y OU utilisez:

  • Instant est un point instantané sur le temps global en ligne (UTC), et est sans rapport avec le fuseau horaire.
  • LocalDate et LocalDateTime n'ont aucun concept de fuseau horaire, mais l'appel now() vous donnera bien sûr votre heure exacte.
  • OffsetDateTime a un fuseau horaire, mais ne prend pas en charge l'heure d'été.
  • ZonedDateTime prend en charge le fuseau horaire complet.

La conversion entre les nécessite généralement un fuseau horaire, pour ainsi répondre à votre question:

        Oui, Java 8 Date/Heure peut prendre soin de la DST, si vous utilisez c'est vrai.

+0

merci de mentionner que 'OffsetDateTime' ne supporte pas DST, c'est exactement ce dont j'avais besoin, merci! –

3

Oui, l'API Java prendra en compte les modifications DST.

Ce tutoriel explique très bien comment convertir des dates entre les fuseaux horaires et comment choisir la bonne classe pour représenter une date: https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

Vous pouvez également consulter cette classe, qui représente les règles pour chaque zone: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html

en particulier, cette méthode peut vous dire si un instant particulier est la lumière du jour: économies http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time.Instant-

+0

Merci de me rappeler la valeur des documents Orcale :) Ces liens me sont plus utiles. – Raja

14

The Answer par Andreas est correct sur place.

Exemple de code

Testons-le avec du code.

Commençons par 1 heure du matin dans la date-heure "locale", ce qui signifie qu'elle n'est pas liée au scénario et qu'elle ignore le problème des fuseaux horaires. Ajouter une heure, et nous obtenons 2 AM. Logique.

LocalDateTime localDateTime = LocalDateTime.of(2015 , Month.NOVEMBER , 1 , 1 , 0); // 1 AM anywhere. Not tied the timeline nor to any time zone. 
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours(1); // 2 AM anywhere, in no particular time zone, ignoring DST. 

Ensuite, nous obtenons spécifiques, avec un fuseau horaire particulier.Nous prenons ce 1 AM partout et le mettre dans le fuseau horaire de America/Los_Angeles (côte ouest des États-Unis).

ZoneId zoneId_LosAngeles = ZoneId.of("America/Los_Angeles"); 
ZonedDateTime before = localDateTime.atZone(zoneId_LosAngeles); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line. 

Maintenant, ajoutez une heure et voyez ce que nous obtenons. Si l'heure d'été est ignorée, nous aurons 2 heures du matin. Si l'heure d'été est respectée, nous obtenons 1 heure du matin ... à 2 heures du matin, le wall-clock time revient à 1 heure du matin mais avec un nouveau décalage par rapport à l'heure UTC. Ceci est familièrement connu comme "fall back" à l'automne (automne).

ZonedDateTime after = before.plusHours(1); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015. 

Dump vers la console.

System.out.println("localDateTime : " + localDateTime); 
System.out.println("localDateTimeOneHourLater : " + localDateTimeOneHourLater); 
System.out.println("before : " + before); 
System.out.println("after : " + after); 

Lors de l'exécution, nous obtenons cette sortie. Sans fuseau horaire, 1 heure + 1 heure = 2 heures. Rappelez-vous qu'il s'agit de valeurs date-heure "locales", et non UTC. Ils représentent seulement l'idée vague d'une date-heure, pas un moment réel sur la chronologie.

localDateTime : 2015-11-01T01:00 
localDateTimeOneHourLater : 2015-11-01T02:00 

Mais avec l'application de fuseaux horaires le jour où l'heure d'été d'été arrive à échéance, nous obtenons des résultats différents. Notez comment l'heure du jour reste 01:00 mais le offset-from-UTC passe de -07:00 à -08:00. Peut-être que cela serait plus clair et plus facile à vérifier si nous ajustons en UTC. Nous pouvons le faire simplement en accédant aux objets before et after en tant qu'objets Instant. Le System.out.println appelle ensuite implicitement la méthode toString.

System.out.println("before.toInstant : " + before.toInstant()); 
System.out.println("after.toInstant : " + after.toInstant()); 

Lors de l'exécution.

before.toInstant : 2015-11-01T08:00:00Z 
after.toInstant : 2015-11-01T09:00:00Z