Java 8 - Convertir la date en date locale et heure locale

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