web-dev-qa-db-ja.com

javax.time.Instantをローカルタイムゾーンの文字列としてフォーマットするにはどうすればよいですか?

_javax.time.Instant_ をローカルタイムゾーンの文字列としてフォーマットするにはどうすればよいですか?次の例では、ローカルInstant[〜#〜] utc [〜#〜] に変換しますが、期待したとおりのローカルタイムゾーンには変換しません。 toLocalDateTime() への呼び出しを削除しても、同じことが行われます。代わりに現地時間を取得するにはどうすればよいですか?

_public String getDateTimeString( final Instant instant )
{
    checkNotNull( instant );
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
    DateTimeFormatter formatter = builder.appendPattern( "yyyyMMddHHmmss" ).toFormatter();
    return formatter.print( ZonedDateTime.ofInstant( instant, TimeZone.UTC ).toLocalDateTime() );
}
_

注: JSR-31 リファレンス実装の古いバージョン .6. を使用しています

24
Derek Mahar

私の回答に反対票を投じる前に、明示的に(太字の書体で)質問が古いバージョン0.6.3を参照していることに注意してください。 JSR-310リファレンス実装!Java 8と新しい日付ライブラリ!が到着するずっと前の2012年12月にこの質問をしました


JSR-310クラスDateTimeFormatterZonedDateTimeをあきらめ、代わりに旧式のJava.util.DateおよびJava.text.SimpleDateFormat

public String getDateTimeString( final Instant instant )
{
    checkNotNull( instant );
    DateFormat format = new SimpleDateFormat( "yyyyMMddHHmmss" );
    Date date = new Date( instant.toEpochMillisLong() );
    return format.format( date );
}
1
Derek Mahar

ほぼ完成したJDK1.8バージョンについてこの質問に答える

DateTimeFormatter formatter =
  DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.systemDefault());
return formatter.format(instant);

重要なのは、Instantにはタイムゾーン情報がないことです。したがって、「yyyyMMddHHmmss」などの日付/時刻フィールドに基づくパターンを使用してフォーマットすることはできません。 DateTimeFormatterでゾーンを指定すると、フォーマット時にインスタントが指定されたタイムゾーンに変換され、正しく出力されるようになります。

別の方法は、ZonedDateTimeに変換することです:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
return formatter.format(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()));

どちらのアプローチも同等ですが、データオブジェクトがInstantの場合、通常は最初のアプローチを選択します。

37
JodaStephen

なぜローカルタイムゾーンを使用すると思いますか?あなたは明示的にUTCを求めています:

ZonedDateTime.ofInstant(instant, TimeZone.UTC)

代わりにローカルタイムゾーンを指定してください:

ZonedDateTime.ofInstant(instant, TimeZone.getDefault())
6
Jon Skeet

これを試して:

String dateTime = DateTimeFormatter.ISO_ZONED_DATE_TIME.format(
    ZonedDateTime.ofInstant(instant, ZoneId.systemDefault())
);

これは与える:

2014-08-25T21:52:07-07:00[America/Los_Angeles]

フォーマッタとしてDateTimeFormatter.ISO_ZONED_DATE_TIME以外のものを使用して、フォーマットを変更できます。 DateTimeFormatterには、事前定義されたフォーマッタがたくさんありますが、独自に定義することもできます。

1
Luke Hutchison