web-dev-qa-db-ja.com

Java 8のLocalDateTimeをJodaのLocalDateTimeに変換する簡単な方法

Java 8のLocalDateTimeをJodaのLocalDateTimeに変換する簡単な方法はありますか?

方法の1つは、それを文字列に変換し、その文字列からJodaのLocalDateTimeを作成することです。

17
Naresh

エポックミリ秒で変換(基本的にはJava.util.Date()):

Java.time.LocalDateTime Java8LocalDateTime = Java.time.LocalDateTime.now();

// Separate steps, showing intermediate types
Java.time.ZonedDateTime Java8ZonedDateTime = Java8LocalDateTime.atZone(ZoneId.systemDefault());
Java.time.Instant Java8Instant = Java8ZonedDateTime.toInstant();
long millis = Java8Instant.toEpochMilli();
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis);

// Chained
org.joda.time.LocalDateTime jodaLocalDateTime =
        new org.joda.time.LocalDateTime(
            Java8LocalDateTime.atZone(ZoneId.systemDefault())
                              .toInstant()
                              .toEpochMilli()
        );

// One-liner
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(Java8LocalDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

1行ですが長いので「簡単」ですか?それはすべて相対的です。

19
Andreas

どちらのlocalDateタイプも(year, month, date)で構成されているため、これらの値をコピーするだけです。

public static org.joda.time.LocalDate toJoda(Java.time.LocalDate input) {
    return new org.joda.time.LocalDate(input.getYear(),
                                       input.getMonthValue(),
                                       input.getDayOfMonth());
}
5
araqnid

少し短い方法:
ZoneOffsetの代わりにZoneIdを使用して問題が解決できる場合は、コードが少し短くなることがあります。

_Java.time.LocalDateTime Java8LDT = Java.time.LocalDateTime.now();
org.joda.time.LocalDateTime jodaLDT = new org.joda.time.LocalDateTime(
    Java8LDT.toInstant(ZoneOffset.UTC).toEpochMilli()
);
_

atZone()メソッドへのタイムゾーンオフセットを指定することで、toInstant()メソッドの呼び出しを削除できます。

詳細な説明
明確にするために、削除したステップは中間のZonedDateTimeオブジェクトを作成することです。シーケンスのこの部分は、Jodaを使用する前にJava 8 APIを使用しています。

変換プロセスでは、最初にJava 8 LocalDateTimeをエポック以降のミリ秒数に変換します。これは、いくつかの異なる方法で実現できます。たとえば、Andreasの回答の場合:

_LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Instant instant = zdt.toInstant();
long millis = instant.toEpochMilli();
_

または私の代替:

_LocalDateTime ldt = LocalDateTime.now();
Instant instant = ldt.toInstant(ZoneOffset.UTC);
long millis = instant.toEpochMilli();
_

違いは、Java 8 ZonedDateTimeの作成をスキップし、代わりにタイムゾーンオフセットをtoInstant()メソッドに渡すことです。

この時点から、2つの答えは同じです。

_org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis);
_

警告
これは、夏時間の変更が適用されない一貫したオフセットを使用して変換する場合にうまく機能します。たとえば、UTCは常に+0:00です。オフセットが変更される可能性があるローカルタイムゾーンに変換する必要がある場合は、atZone()を使用して少し長い回答が必要になります。

両方のAPI(Java 8とJoda)を持つLocalDateTimeは、タイムゾーンのないDateTimeです。ただし、エポック以降のミリ秒数がある場合は、日付と時刻を取得するためのオフセットが必要です。 Java 8 APIではオフセットまたはタイムゾーンを明示的に渡す必要がありますが、Joda APIは何も渡されない場合はシステムデフォルトを使用します。

Joda LocalDateTimeを構築するより正確な方法は次のとおりです。

_org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis, DateTimeZone.UTC);
_

これは、正しい日付と時刻を取得するために、構築中にのみタイムゾーンを使用します。 LocalDateTimeにはタイムゾーンがないため、コンストラクタが完了すると、タイムゾーンはオブジェクトの一部を形成しません。

1
Ben Thurley