Je pense utiliser le nouveau Java 8 Date Time API. J'ai googlé un peu et trouvé jodaTime comme bon choix pour Java mais toujours un peu intéressé de voir comment cette nouvelle API fonctionne.
Je stocke tout le temps en valeurs UTC dans ma banque de données et je les convertirai en valeur spécifique au fuseau horaire local en fonction du fuseau horaire de l'utilisateur. Je peux trouver de nombreux articles montrant comment utiliser la nouvelle API Java Date Time. Cependant, je ne sais pas si l'API prendra en charge les changements d'heure d'été? Ou avons-nous une meilleure façon de gérer la date?
Je viens d'apprendre la nouvelle API Date, alors j'ai pensé entendre vos réflexions sur la gestion du DateTime et son affichage sur la base de la zone horaire des utilisateurs.
Cela dépend de la classe que vous utilisez:
Instant
est un point instantané sur la ligne de temps globale (UTC) et n'est pas lié au fuseau horaire.LocalDate
et LocalDateTime
n'ont pas de notion de fuseau horaire, mais appeler 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
a une prise en charge complète des fuseaux horaires.La conversion entre eux nécessite généralement un fuseau horaire, donc pour répondre à votre question:
Oui, Java 8 Date/Time can s'occupe de l'heure d'été, si vous utilisez c'est bien.
La réponse par Andreas est correct.
Testons-le avec du code. DST aux États-Unis & Le Canada expire cette année à 02h00 le 1er novembre 2015.
Commençons par 1 heure du matin en date-heure "locale", ce qui signifie qu’elle n’est pas liée à la chronologie et qu’elle ignore le problème des fuseaux horaires. Ajoutez une heure, et nous obtenons 2 heures du matin. 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 devenons spécifiques, avec un fuseau horaire particulier. Nous prenons ce 1 AM n'importe où et le mettons 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.
Ajoutez maintenant 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 aurons 1 heure du matin… lorsque nous atteindrons 2 heures le heure de l'horloge murale revient à 1 heure du matin mais avec un nouveau décalage par rapport à l'UTC. Ceci est familièrement connu sous le nom de "repli" à 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 sur 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 h + 1 heure = 2 h. N'oubliez pas que ce sont des valeurs de date-heure "locales", et non UTC . Ils ne représentent que la vague idée d'une date-heure, pas un moment réel sur la chronologie.
localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00
Mais avec les fuseaux horaires appliqués le jour de l'expiration de l'heure d'été, nous obtenons des résultats différents. Notez comment l'heure du jour reste 01:00
mais offset-from-UTC change de -07:00
à -08:00
.
before : 2015-11-01T01:00-07:00[America/Los_Angeles]
after : 2015-11-01T01:00-08:00[America/Los_Angeles]
Cela serait peut-être plus clair et plus facile à vérifier si nous 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 alors 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
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien hérité classes date-heure telles que Java.util.Date
, Calendar
, & SimpleDateFormat
.
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers Java.time = classes.
Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 31 .
Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.*
Des classes.
Où obtenir les classes Java.time?
Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à Java.time. Vous pouvez trouver ici des classes utiles telles que Interval
, YearWeek
, YearQuarter
, et plus .
Oui, l'API Java prend en compte les changements d'heure d'été).
Ce tutoriel explique assez bien comment convertir des dates entre 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 de 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 en heure d'été: http://docs.Oracle.com/javase/8/docs/api/Java/time/zone/ZoneRules.html#isDaylightSavings -Java.time.Instant -