Java 8 - 日付をLocalDateとLocalDateTimeに変換する

`java.util.Date`はタイムゾーンの概念を持たず、https://en.wikipedia.org/wiki/Unix__time[Unixエポックタイム]から経過した秒数を表します - 1970-01-01T00: 00:00Z(1970年1月1日(GMT/UTC)の開始時の深夜)

1. Date - > java.time

日付変換のアイデア:

Date -> Instant + System default time zone = LocalDate
Date -> Instant + System default time zone = LocalDateTime
Date -> Instant + System default time zone = ZonedDateTime

この例では、 java.util.Date`を新しいJava 8のDate API( LocalDate`、 LocalDateTime 、` ZonedDateTime`)に変換する方法を示します。

DateToJavaTime.java

package com.mkyong.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);

    }

}

出力

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.解説 -  Q&A

**  2.1質問** : `Date`にタイムゾーンの概念がない場合、なぜ` Date`オブジェクトをプリントアウトしている間にタイムゾーンが表示されるのですか?例えば ​​:

....//Fri Aug 19 11:52:06 MYT 2016
System.out.println(new Date());//MYT = my system default time zone
  • Answer ** : `java.uti.Date.toString()`ソースコードをチェックし、 `Date`オブジェクトを出力すると、システムのデフォルトタイムゾーンが追加されて一緒に表示されます。

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();
}
  • 注意** この動作は、JDK1.1以降の設計上の欠陥です。混乱を招きます。 `java.util.Date`はタイムゾーン情報を保存しませんが、もしあなたがそれをプリントアウトすれば、システムのデフォルトタイムゾーンが一緒に表示されます。

  • 2.2質問 : Date`変換のために、なぜ java.time.instant`にシステムのデフォルトタイムゾーンを追加する必要がありますか? 回答** :上記2.1 Qを参照してください。

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

変換の目的は、 Date`と LocalDate`の両方の出力が同じ出力を生成することを確認することです。

…​.//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  - >日付

この例は `LocalDate`、` LocalDateTime`と `ZonedDateTime`を古典的な` java.util.Date`に戻す方法を示しています

JavaTimeToDate.java

package com.mkyong.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);
}

}

出力

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

=== 参考文献

.  https://jcp.org/ja/jsr/detail?id=310[JSR 310:Date and Time API]

.  https://en.wikipedia.org/wiki/Unix__time[Unix時間]

.  https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html[Instant

JavaDoc]。 https://docs/

JavaDoc]。 link://java/java-convert-date-time-time-time-timezone/[Java  -

タイムゾーン間の日付と時刻を変換する]

リンク://タグ/変換/[変換]リンク://タグ/java-time/[java.time]link://tag/java8/[java8]link://tag/localdate/[localdate]link://タグ/localdatetime/[localdatetime]link://tag/zoneddatetime/[zoneddatetime]
前の投稿:ZIP形式でファイルを圧縮する方法
次の投稿:PDFBox - JavaでPDFファイルを読む方法