Java 8 - Convertir la date en LocalDate et LocalDateTime
Lejava.util.Date
n'a pas de concept de fuseau horaire et ne représente que le nombre de secondes écoulées depuis leUnix epoch time - 1970-01-01T00: 00: 00Z (minuit au début du 1er janvier 1970 GMT / UTC)
Note
Le nouveau Java 8java.time.Instant
est la classe équivalente auxjava.util.Date
classiques
1. Date → java.time
L'idée de la conversion de date:
Date -> Instant + System default time zone = LocalDate Date -> Instant + System default time zone = LocalDateTime Date -> Instant + System default time zone = ZonedDateTime
Cet exemple vous montre comment convertirjava.util.Date
en nouvelles API de date Java 8 -LocalDate
,LocalDateTime
etZonedDateTime
DateToJavaTime.java
package com.example.java8; import java.time.*; import java.util.Date; public class DateToJavaTime { public static void main(String[] args) { //Asia/Kuala_Lumpur +8 ZoneId defaultZoneId = ZoneId.systemDefault(); System.out.println("System Default TimeZone : " + defaultZoneId); //toString() append +8 automatically. Date date = new Date(); System.out.println("date : " + date); //1. Convert Date -> Instant Instant instant = date.toInstant(); System.out.println("instant : " + instant); //Zone : UTC+0 //2. Instant + system default time zone + toLocalDate() = LocalDate LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate(); System.out.println("localDate : " + localDate); //3. Instant + system default time zone + toLocalDateTime() = LocalDateTime LocalDateTime localDateTime = instant.atZone(defaultZoneId).toLocalDateTime(); System.out.println("localDateTime : " + localDateTime); //4. Instant + system default time zone = ZonedDateTime ZonedDateTime zonedDateTime = instant.atZone(defaultZoneId); System.out.println("zonedDateTime : " + zonedDateTime); } }
Sortie
System Default TimeZone : Asia/Kuala_Lumpur date : Fri Aug 19 21:46:31 MYT 2016 instant : 2016-08-19T13:46:31.981Z localDate : 2016-08-19 localDateTime : 2016-08-19T21:46:31.981 zonedDateTime : 2016-08-19T21:46:31.981+08:00[Asia/Kuala_Lumpur]
2. Explication - Q&R
2.1 Question: SiDate
n'a pas de concept de fuseau horaire, pourquoi le fuseau horaire sera-t-il affiché pendant que nous imprimons l'objetDate
? Par exemple :
//Fri Aug 19 11:52:06 MYT 2016 System.out.println(new Date()); //MYT = my system default time zone
Answer: Vérifiez le code source dejava.uti.Date.toString()
, si vous imprimez l'objetDate
, le fuseau horaire par défaut du système sera ajouté et s'affichera ensemble.
java.util.Date
public String toString() { //...omitted... TimeZone zi = date.getZone(); if (zi != null) { sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz } else { sb.append("GMT"); } sb.append(' ').append(date.getYear()); // yyyy return sb.toString(); }
Note
Ce comportement est un défaut de conception depuis le JDK1.1, cela crée beaucoup de confusion. Encore une fois, lejava.util.Date
ne stocke aucune information sur le fuseau horaire, mais si vous l'imprimez, le fuseau horaire par défaut du système sera affiché ensemble.
2.2 Question: Pour la conversion deDate
, pourquoi nous devons ajouter un fuseau horaire par défaut du système pourjava.time.instant
?
Answer: Reportez-vous aux questions et réponses 2.1 ci-dessus. Examinez un autre exemple:
1. Date = 19/08/2016T10:00:00 2. System default time zone = +08:00 [Asia/Kuala_Lumpur] 3. Date (Print) = 19/08/2016T10:00:00+08:00 = 19/08/2016T18:00:00
Le but de la conversion est de s'assurer que printDate
et printLocalDate
génèrent la même sortie.
// Assume 19/08/2016T10:00:00 = 1000 // System default time zone = +8 1. Date (1000) -> Print Date (1000) = 1000+08:00 // we always see "1000+08:00" (but the Date is still 1000) 2. Date (1000) -> Instant (1000) // instant has no time zone or zero offset (UTC+0/Z) 3. Instant(1000) -> LocalDate(1000) -> Print LocalDate(1000) = 1000 // The result is "1000", different with print date! 4. LocalDate(1000) + 08:00 -> LocalDate(1000+08:00) // add default time zone +8 5. Print LocalDate(1000+08:00) = 1000+08:00
3. java.time → Date
Cet exemple vous montre comment reconvertir lesLocalDate
,LocalDateTime
etZonedDateTime
enjava.util.Date
classiques
JavaTimeToDate.java
package com.example.java8; import java.time.*; import java.util.Date; public class JavaTimeToDate { public static void main(String[] args) { //Asia/Kuala_Lumpur +8 ZoneId defaultZoneId = ZoneId.systemDefault(); System.out.println("System Default TimeZone : " + defaultZoneId); LocalDate localDate = LocalDate.of(2016, 8, 19); Date date = Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()); System.out.println("\n1. LocalDate -> Date"); System.out.println("localDate : " + localDate); System.out.println("date : " + date); LocalDateTime localDateTime = LocalDateTime.of(2016,8,19,21,46,31); Date date2 = Date.from(localDateTime.atZone(defaultZoneId).toInstant()); System.out.println("\n2. LocalDateTime -> Date"); System.out.println("localDateTime : " + localDateTime); System.out.println("date2 : " + date2); ZonedDateTime zonedDateTime = localDateTime.atZone(defaultZoneId); Date date3 = Date.from(zonedDateTime.toInstant()); System.out.println("\n3. ZonedDateTime -> Date"); System.out.println("zonedDateTime : " + zonedDateTime); System.out.println("date3 : " + date3); } }
Sortie
System Default TimeZone : Asia/Kuala_Lumpur 1. LocalDate -> Date localDate : 2016-08-19 date : Fri Aug 19 00:00:00 MYT 2016 2. LocalDateTime -> Date localDateTime : 2016-08-19T21:46:31 date2 : Fri Aug 19 21:46:31 MYT 2016 3. ZonedDateTime -> Date zonedDateTime : 2016-08-19T21:46:31+08:00[Asia/Kuala_Lumpur] date3 : Fri Aug 19 21:46:31 MYT 2016