LocalDateをLocalDateTimeまたはjava.sql.Timestampに変換します


126

JodaTime 1.6.2を使用しています。

LocalDate(Joda )LocalDateTimeまたはjava.sqlTimestampormappingのいずれかに変換する必要があるを持っています。

この理由は、a LocalDateTimeとaの間で変換する方法を理解したためですjava.sql.Timestamp

LocalDateTime ldt = new LocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.forPattern("yyyy-MM-dd HH:mm:ss");
Timestamp ts = Timestamp.valueOf(ldt.toString(dtf));

したがって、LocalDateとの間で変換できる場合はLocalDateTime、継続してに変換できjava.sql.Timestampます。正しい方向に向けて微調整をありがとう!


FYI、ジョダタイムプロジェクトは、今でメンテナンスモードへの移行を助言チームと、java.timeのクラス。Oracleによるチュートリアルを参照してください。また、このjava.sql.Timestampクラスはレガシーになり、java.timeクラス、特にに取って代わられましたInstant
バジルブルク2018年

回答:


269

JodaTime

JodaTimeをに変換するには、次のorg.joda.time.LocalDateようjava.sql.Timestampにします。

Timestamp timestamp = new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());

JodaTimeをに変換するには、次のorg.joda.time.LocalDateTimeようjava.sql.Timestampにします。

Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis());

JavaTime

Java8をに変換するには、次のjava.time.LocalDateようjava.sql.Timestampにします

Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay());

Java8をに変換するには、次のjava.time.LocalDateTimeようjava.sql.Timestampにします

Timestamp timestamp = Timestamp.valueOf(localDateTime);

すべてのが有効なわけではないため、変換時に注意LocalDateTimeDateTimeてください。ソース:joda-time.sourceforge.net/faq.html#illegalinstantと実行します。LocalDateTimeDateTime
Christophe De Troyer 2015

valueOf()が文字列を受け入れるため、引数のコンパイルエラーが発生しました。
愛国心が

@Patriotic:これは、Java SE 1.8以降を実際に使用していない場合にのみ発生します。回答と提供されたJavadocへのリンク(上記の回答の青色のテキストは実際にはリンクです。クリックしてJavadocにドリルダウンできます)に示されているように、このTimestamp#valueOf()メソッドはJava SE 1.8以降も受け入れますLocalDateTime
BalusC

60

Java 8 time APIを使用する最良の方法:

  LocalDateTime ldt = timeStamp.toLocalDateTime();
  Timestamp ts = Timestamp.valueOf(ldt);

モデルに組み込まれたJPAで使用する場合(https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa):

@Converter(autoApply = true)
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime ldt) {
        return Timestamp.valueOf(ldt);
    }

    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp ts) {
        return ts.toLocalDateTime();
    }
}

したがって、これは相対的なタイムゾーンに依存しない時間です。さらにそれは簡単です:

  LocalDate ld = ldt.toLocalDate();
  LocalTime lt = ldt.toLocalTime();

フォーマット:

 DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
 String str = ldt.format(DATE_TME_FORMATTER);
 ldt = LocalDateTime.parse(str, DATE_TME_FORMATTER);

更新:postgres 9.4.1208、HSQLDB 2.4.0などは、会話なしでJava 8 Time APIを理解します!


17

tl; dr

ジョダタイムプロジェクトは現在に取って代わられ、メンテナンスモード、であるjava.timeのクラス。

  • java.time.Instantクラスを使用するだけです。
  • 必要はありません:
    • LocalDateTime
    • java.sql.Timestamp
    • 文字列

UTCで現在の瞬間をキャプチャします。

Instant.now()  

その瞬間をデータベースに保存するには:

myPreparedStatement.setObject(  , Instant.now() )  // Writes an `Instant` to database.

その瞬間をdatbaseから取得するには:

myResultSet.getObject(  , Instant.class )  // Instantiates a `Instant`

壁時計の時刻を特定のタイムゾーンの時刻に合わせる。

instant.atZone( z )  // Instantiates a `ZonedDateTime`

LocalDateTime 間違ったクラスです

他の答えは正しいですLocalDateTimeが、それはあなたの目的にとって間違ったクラスであることを指摘することができません。

java.timeJoda -Timeの両方で、LocalDateTime意図的にタイムゾーンやオフセットからのオフセットの概念が欠けています。そのため、それは瞬間を表すものではなく、タイムライン上のポイントではありません。A LocalDateTimeは、約26〜27時間の範囲の潜在的な瞬間についての大まかな考えを表します。

LocalDateTimeゾーン/オフセットが不明な場合(良好な状況ではない)、またはゾーンオフセットが不確定な場合は、forを使用します。たとえば、「クリスマスは2018年12月25日の最初の瞬間に始まります」はとして表されますLocalDateTime

a ZonedDateTimeを使用して、特定のタイムゾーンの瞬間を表します。たとえば、Pacific/Aucklandまたはなどの特定のゾーンで始まるクリスマスAmerica/Montrealは、ZonedDateTimeオブジェクトで表されます。

常にUTCでしばらくの間、を使用しますInstant

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

タイムゾーンを適用します。同じ瞬間、タイムライン上の同じポイントですが、異なる実時間で表示されています。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, different wall-clock time.

したがって、LocalDateとLocalDateTimeの間で変換できる場合、

いいえ、間違った戦略です。日付のみの値があり、日時の値が必要な場合は、時刻を指定する必要があります。その時間帯は、特定のゾーンのその日に有効でない場合があります。その場合、ZonedDateTimeクラスは必要に応じて時間帯を自動的に調整します。

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 14 , 0 ) ;  // 14:00 = 2 PM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

時刻として一日の最初の瞬間が必要な場合は、java.timeにその瞬間を決定させます。日が00:00:00に始まると想定しないでください。夏時間(DST)などの異常は、その日が01:00:00などの別の時間に始まることを意味します。

ZonedDateTime zdt = ld.atStartOfDay( z ) ;

java.sql.Timestamp 間違ったクラスです

java.sql.Timestamp今では完全に取って代わらレガシー、ある厄介な古い日付時刻クラスの一部であるjava.timeのクラス。そのクラスは、ナノ秒の分解能でUTCの瞬間を表すために使用されました。その目的は現在で提供されています。java.time.Instant

getObject/を含むJDBC 4.2setObject

以下のようJDBC 4.2以降では、あなたのJDBCドライバを直接呼び出すことにより、データベースとjava.time・オブジェクトを交換することができます:

例えば:

myPreparedStatement.setObject(  , instant ) ;

…と…

Instant instant = myResultSet.getObject(  , Instant.class ) ;

レガシー⬌モダンを変換

java.timeにまだ更新されていない古いコードとインターフェースする必要がある場合は、古いクラスに追加された新しいメソッドを使用して、前後に変換します。

Instant instant = myJavaSqlTimestamp.toInstant() ;  // Going from legacy class to modern class.

…そして…

java.sql.Timestamp myJavaSqlTimestamp = java.sql.Timestamp.from( instant ) ;  // Going from modern class to legacy class.

java.timeについて

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.DateCalendar、& SimpleDateFormat

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

java.timeオブジェクトをデータベースと直接交換することができます。JDBC 4.2以降に準拠したJDBCドライバーを使用します。文字列もクラスも必要ありません。java.sql.*

java.timeクラスはどこで入手できますか?

  • Java SE 8 Java SE 9以降
    • 内蔵。
    • 実装がバンドルされた標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6および Java SE 7
    • java.time機能の多くは、ThreeTen-BackportでJava 6および7にバックポートされています。
  • アンドロイド
    • Androidの新しいバージョンには、java.timeクラスの実装がバンドルされています。
    • 以前のAndroid(<26)では、ThreeTenABPプロジェクトはThreeTen-Backport(上記)を採用しています。ThreeTenABPの使用方法…を参照してください。

ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがIntervalYearWeekYearQuarter、および多くを


5

タイムゾーンによっては、数分を失う可能性があります(1650-01-01 00:00:00は1649-12-31 23:52:58になります)

それを回避するには、次のコードを使用します

new Timestamp(localDateTime.getYear() - 1900, localDateTime.getMonthOfYear() - 1, localDateTime.getDayOfMonth(), localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour(), localDateTime.getSecondOfMinute(), fractional);

3

Jodaが衰退しているので、誰かがJava 8 に変換LocaltDateしたいと思うかもしれません。Java8では、およびを使用してインスタンスを作成する方法を提供します。こちらをチェックしてください。LocalDateTimeLocalDateTimeLocalDateTimeLocalDateLocalTime

パブリック静的LocalDateTime of(LocalDate date、LocalTime time)

サンプルは、

    // just to create a sample LocalDate
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
    LocalDate ld = LocalDate.parse("20180306", dtf);

    // convert ld into a LocalDateTime
    // We need to specify the LocalTime component here as well, it can be any accepted value
    LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00

参考までに、以下のエポック秒を取得するために使用できます。

    ZoneId zoneId = ZoneId.systemDefault();
    long epoch = ldt.atZone(zoneId).toEpochSecond(); 

    // If you only care about UTC
    long epochUTC = ldt.toEpochSecond(ZoneOffset.UTC);

LocalDateTimeここではまったく使用する必要はありません。このクラスには、意図的にタイムゾーンやUTCからのオフセットの概念がありません。したがって、ここでは有用な目的はありません。代わりにLocalDate.parse( “20180306” , DateTimeFormatter.BASIC_ISO_DATE ).atStartOfDay( ZoneId.of( “Africa/Tunis” ).toEpochSecond()、日が00:00から始まるとは限りません。常にそうとは限りません。
バジルブルク2018年

あなたは00.00で一日の始まりを負いませんによって意味ですかWhay
プライム

1
夏時間(DST)などの異常は、場所によっては1日が01:00:00などの別の時間に始まることを意味します。したがって、想定するのではなく、を取得するために呼び出してjava.timeに最初の瞬間を決定させます。私の回答の例を参照してください。私がコメントしたように、クラスはこのすべてにおいて役に立たず、逆効果です。java.time.LocalDate.atStartOfDayZonedDateTimeLocalDateTime
バジルブルク2018年

したがってLocalDateTimeZoneId?を使用する必要があります。
プライム

あなたは私のすべてのポイントを逃したと思います。このページの回答をもう一度読んでください。Stack Overflowを検索して、さらに多くの例とディスカッションから詳細を学んでください。しかし、ここで最後に言います。ここで問題となっている問題に適切でLocalDateTimeはありません。A LocalDateTimeは瞬間を表しませA LocalDateTimeは特定の地域やタイムゾーン何の関係もありませんが、名前は一見それ以外の意味を持っている可能性があります。このクラスの意図と詳細については、こちらをご覧ください。LocalDateTimeクラスは目的ではなく、この質問で見られる目的を果たすん。
バジルブルク2018年


0

Java8 +

import java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)

便利ですが、実際には質問に答えていないようです。
Ole VV 2018

コードをありがとう、しかしそれは質問とは何の関係もありません。
refaelio
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.