web-dev-qa-db-ja.com

Java 8で現在の時刻を取得する

Java 8.の新しいJava.time APIを検討しています。現在の時間(現在の時間帯、異なる時間帯、異なるオフセット)を取得しようとしています。

コードは次のとおりです。

public static void getCurrentLocalTime(){
    LocalTime time = LocalTime.now();
    System.out.println("Local Time Zone: "+ZoneId.systemDefault().toString());
    System.out.println("Current local time : " + time);
}

public static void getCurrentTimeWithTimeZone(){
    LocalDateTime localtDateAndTime = LocalDateTime.now();
    ZoneId zoneId = ZoneId.of("America/Los_Angeles");
    ZonedDateTime dateAndTimeInLA  = ZonedDateTime.of(localtDateAndTime, zoneId);
    String currentTimewithTimeZone =dateAndTimeInLA.getHour()+":"+dateAndTimeInLA.getMinute();
    System.out.println("Current time in Los Angeles: " + currentTimewithTimeZone);
}

public static void getCurrentTimeWithZoneOffset(){
    LocalTime localtTime = LocalTime.now();
    ZoneOffset offset = ZoneOffset.of("-08:00");
    OffsetTime  offsetTime  = OffsetTime.of(localtTime, offset);
    String currentTimewithZoneOffset =offsetTime.getHour()+":"+offsetTime.getMinute();
    System.out.println("Current time  with offset -08:00: " + currentTimewithZoneOffset);
}

しかし、メソッドを呼び出すと、同じ時刻(システム時刻)が取得されますが、これは明らかに期待したものではありません。

メソッド呼び出しの出力:

Current time in Los Angeles: 19:59
Local Time Zone: Asia/Calcutta
Current local time : 19:59:20.477
Current time  with offset -08:00: 19:59

別のタイムゾーンとオフセットを設定した後でも、なぜ同じ時間になるのですか?

15
user2693135

LocalDateTime.now()は、常にデフォルトのタイムゾーンで現在の日付/時刻を返します(たとえば、ロンドンの10月13日午前11時20分)。特定のZonedDateTimeまたはOffsetTimeを使用してZoneIdまたはZoneOffsetを作成すると、同じ日付と時刻を取得しますが、タイムゾーンは異なります(たとえば、ロサンゼルスの午前11時20分に10月13日)、これは異なる時点を表します。

あなたはおそらく次のようなものを探しています:

Instant now = Instant.now();
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
ZonedDateTime dateAndTimeInLA = ZonedDateTime.ofInstant(now, zoneId);

これにより、ロサンゼルスの現在の日付と時刻が10月13日午前3時20分に計算されます。

21
assylias

以下の固定方法を検討してください。

_public static void getCurrentLocalTime() {
    LocalTime time = LocalTime.now();
    System.out.println("Local Time Zone: " + ZoneId.systemDefault().toString());
    System.out.println("Current local time : " + time);
}

public static void getCurrentTimeWithTimeZone() {
    LocalDateTime localDateAndTime = LocalDateTime.now(ZoneId.of("America/Los_Angeles"));
    System.out.println("Current time in Los Angeles: " + localDateAndTime.toLocalTime());
}

public static void getCurrentTimeWithZoneOffset() {
    LocalTime localTime = LocalTime.now(ZoneOffset.of("-08:00"));
    System.out.println("Current time  with offset -08:00: " + localTime);
}
_

変更されたのは、 now() を呼び出す代わりに、 now(zone) が呼び出されることです。これは、now()が常にタイムゾーンの現在のシステム時刻を返すためです。 atZone、_OffsetTime.of_、または_ZoneDateTime.of_の呼び出しは、日付/時刻を変更せず、Javaこのタイムゾーンの日付/時刻。

これらの3つのメソッドを呼び出すときのマシン上の出力は次のとおりです。

_Local Time Zone: Europe/Paris
Current local time : 12:32:21.560
Current time in Los Angeles: 03:32:21.579
Current time  with offset -08:00: 02:32:21.580
_

これを非常に明確にするために、あなたはヨーロッパにいてLocalDateTime.now().atZone(ZoneId.of("America/Los_Angeles"))を呼び出します-あなたはロサンゼルスにいるかのようにヨーロッパの現在の時刻を表す日付/時刻を作成しているので、ロサンゼルス在住者の実際の未来である日付/時刻(DSTに応じて、未来8時間または9時間)。

7
Tunaki

withZoneSameInstantを使用して、別のゾーンで時間を表示する別の方法もあります。

// now, in current zone,
// 2016-04-13T14:24:57.618+02:00[Europe/Warsaw]
ZonedDateTime now = ZonedDateTime.now();

// 2016-04-13T05:24:57.618-07:00[America/Los_Angeles]
ZonedDateTime losAngelesDateTime = now.withZoneSameInstant(ZoneId.of("America/Los_Angeles"));
6
mlewandowski