web-dev-qa-db-ja.com

LocalDate.now()をミリ秒単位で返すにはどうすればよいですか?

今すぐ日付を作成します:

_ZoneId gmt = ZoneId.of("GMT");
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDateNow = localDateTime.toLocalDate();
_

次に、この日付をミリ秒単位で返します:

_localDateNow.atStartOfDay(gmt) - 22.08.2017
localDateNow.atStartOfDay(gmt).toEpochSecond(); - 1503360000 (18.01.70)
_

LocalDate.now()をミリ秒単位で返すにはどうすればよいですか?

12
user5620472

@ JB Nizetのコメント で示唆されているように、toInstant().toEpochMilli()を呼び出すのが正しい答えですが、ローカル日付の使用については注意が必要な、少し複雑な詳細があります。

しかしその前に、他のいくつかの小さな詳細:

  • ZoneId.of("GMT")の代わりに、組み込み定数_ZoneOffset.UTC_を使用できます。それらは同等ですが、APIがまったく同じことを行うオブジェクトを既に提供している場合、余分な冗長オブジェクトを作成する必要はありません。
  • LocalDateTime.now()を呼び出してから.toLocalDate()を呼び出す代わりに、LocalDate.now()を直接呼び出すことができます-これらは同等です。

トリッキーな詳細:now()メソッド(LocalDateTimeまたはLocalDateのいずれか)を呼び出すと、JVMのデフォルトのタイムゾーンを使用して現在の日付の値を取得し、この値は、JVMで構成されたタイムゾーンによって異なる場合があります。

私が使用しているJVMでは、デフォルトのタイムゾーンは_America/Sao_Paulo_であり、ここの現地時間は09:37 AMです。 LocalDate.now()は_2017-08-22_を返します(8月22番目2017)。

しかし、デフォルトのタイムゾーンを _Pacific/Kiritimati_ に変更すると、_2017-08-23_が返されます。それは、キリティマティでは、今はすでに8月23であるためです番目2017(そして、現地時間は、これを書いている時点では02:37 AMです)。

したがって、デフォルトのタイムゾーンが_Pacific/Kiritimati_のときにこのコードを実行すると:

_LocalDate dtNow = LocalDate.now(); // 2017-08-23
System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
_

出力は次のとおりです。

1503446400000

8月に相当する23番目2017年の深夜0時(UTC)。

デフォルトのタイムゾーンが_America/Sao_Paulo_のときに同じコードを実行すると、結果は次のようになります。

1503360000000

8月に相当する22番目2017年の深夜0時(UTC)。

now()を使用すると、コードがJVMのデフォルトのタイムゾーンに依存するようになります。そして、この構成 実行時でも予告なしに変更することができます 。このような変更が発生すると、コードは異なる結果を返します。

そして、あなたはそのような極端なケースを必要としません(誰かがJVMを「非常に遠い」タイムゾーンに誤って設定するような)。私の場合、たとえば_America/Sao_Paulo_タイムゾーンで、11 PMでコードを実行すると、LocalDateが返されます8月22番目、UTCの現在の日付はすでに8月です23番目。それは、11 PMはUTCの翌日の午前2時と同じであるためです。

_// August 22th 2017, at 11 PM in Sao Paulo
ZonedDateTime z = ZonedDateTime.of(2017, 8, 22, 23, 0, 0, 0, ZoneId.of("America/Sao_Paulo"));
System.out.println(z); // 2017-08-22T23:00-03:00[America/Sao_Paulo]
System.out.println(z.toInstant()); // 2017-08-23T02:00:00Z (in UTC is already August 23th)
_

したがって、LocalDate.now()を使用すると、not現在の日付が常にになることが保証されますUTC


UTCの現在の日付(JVMのデフォルトのタイムゾーンに関係なく)を使用し、時刻を深夜に設定する場合は、ZonedDateTime

_// current date in UTC, no matter what the JVM default timezone is 
ZonedDateTime zdtNow = ZonedDateTime.now(ZoneOffset.UTC);
// set time to midnight and get the epochMilli
System.out.println(zdtNow.with(LocalTime.MIDNIGHT).toInstant().toEpochMilli());
_

出力は次のとおりです。

1503360000000

8月に相当する22番目2017年の深夜0時(UTC)。

別の代替方法は、タイムゾーンを_LocalDate.now_に渡すことです。これにより、指定されたゾーンの現在の日付の正しい値を取得できます。

_// current date in UTC, no matter what the JVM default timezone is 
LocalDate dtNowUtc = LocalDate.now(ZoneOffset.UTC);
// set time to midnight and get the epochMilli
System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
_
17
user7605325