JavaScriptアプリケーションとの間で日付をシリアル化/非シリアル化しようとしています。
サーバー側では、Javaを使用しており、JodaTimeがインストールされています。 UTCタイムゾーンでISOにシリアル化する方法を見つけましたが、逆の操作を行う方法を見つけることができません。
これが私のコードです
public static String getIsoDate( Date date )
{
SimpleDateFormat dateToIsoDateString = new SimpleDateFormat( ISO_8601_DATE_FORMAT );
TimeZone tz = TimeZone.getTimeZone("UTC");
dateToIsoDateString.setTimeZone( tz );
return dateToIsoDateString.format( date );
}
// this will return a date with GMT timezone
public static Date getDateFromIsoDateString( String iso8601date )
{
DateTimeFormatter jodaParser = ISODateTimeFormat.dateTimeNoMillis();
return jodaParser.parseDateTime( iso8601date ).toDate();
}
Jodaを使用してもしなくてもかまいませんが、迅速で実用的なソリューションが必要です。
Java 7以前を使用している場合は、これを参照できます post 。
Java 8を使用している場合、次のようにすることができます。
DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
TemporalAccessor accessor = timeFormatter.parse("2015-10-27T16:22:27.605-07:00");
Date date = Date.from(Instant.from(accessor));
System.out.println(date);
コメントの@BasilBourqueで指摘されているように、 TemporalAccessor はJavaフレームワークレベルのインターフェースであり、アプリケーションコードでの使用はお勧めできません。具象を使用することをお勧めしますインターフェイスではなくクラス。
このインターフェイスはフレームワークレベルのインターフェイスであり、アプリケーションコードで広く使用することはできません。代わりに、アプリケーションはLocalDateなどの具象型のインスタンスを作成して渡します。これには多くの理由があり、その一部は、このインターフェースの実装がISO以外のカレンダーシステムにある可能性があることです。問題の詳細については、ChronoLocalDateを参照してください。
LocalDate 、 LocalDateTime 、 OffsetDateTime 、 ZonedDateTime などの使用可能ないくつかの具象クラスがあります。
DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
OffsetDateTime offsetDateTime = OffsetDateTime.parse("2015-10-27T16:22:27.605-07:00", timeFormatter);
Date date = Date.from(Instant.from(offsetDateTime));
System.out.println(date);
OffsetDateTime.parse( "2015-10-27T16:22:27.605-07:00" )
.toInstant()
.toString()
2015-10-27T23:22:27.605Z
あなたの質問は明確で具体的ではありません。おそらく、これらの小さな例が役立つでしょう。古いJava.util.Dateクラスと.CalendarクラスをJoda-Timeと混在させると混乱を招く可能性があります。 Joda-Timeは、拡張ではなく、これらのクラスを完全に置き換えます。
最新のJava.timeクラスは、Javaのレガシー日時クラスと、インスピレーションを提供したJoda-Timeライブラリの両方に取って代わります。
OffsetDateTime
OffsetDateTime
クラスは、実時間を決定する特定のUTCからのオフセットでタイムライン上の瞬間を表します。
Java.timeクラスは、文字列の解析/生成時に、デフォルトで標準の ISO 8601 形式を使用します。したがって、フォーマットパターンを指定する必要はありません。
OffsetDateTime odt = OffsetDateTime.parse( "2015-10-27T16:22:27.605-07:00" ) ;
Instant
UTCから7時間遅れのオフセットからUTC自体に調整するには、時刻に7時間を追加し、必要に応じて日付をロールオーバーする必要があります。 OffsetDateTime
クラスでこの作業を行うことができます。 ZoneOffset.UTC
定数を使用してUTCを指定します。
OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC ) ;
odtUtc.toString():2015-10-27T23:22:27.605Z
このUTC値をコードで多く使用していて、通常は使用する必要がある場合は、Instant
オブジェクトを使用する方がわかりやすいかもしれません。 Instant
は、定義上、UTCではalwaysです。 Instant
からOffsetDateTime
を抽出できます。
Instant instant = odt.toInstant() ;
instant.toString():2015-10-27T23:22:27.605Z
上記の3つのオブジェクト(odt
、odtUtc
、instant
)はすべて、非常に同じ瞬間、つまりタイムライン上の同じポイントを表していることに注意してください。唯一異なるのは、実時間です。
ZonedDateTime
ちなみに、同じ瞬間を特定の地域の人々が使用している実時間に合わせて調整したい場合は、ZoneId
を使用してタイムゾーンを指定し、ZonedDateTime
オブジェクトを取得します。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString():2015-10-27T19:22:27.605-04:00 [アメリカ/モントリオール]
always_a_rookie_to_learnによる回答 は、上記のアプローチに似ていますが、インターフェース TemporalAccessor
を使用します。一般に、Javaではより高いインターフェースとスーパークラスを使用することをお勧めします。しかし、ここではありません。 Java.timeのドキュメントでは、それらの設計では、アプリでより具体的なクラスを使用するつもりであると説明されています。抽象化は、通常、フレームワーク内でのみ内部的に使用されます。
この質問の特定のケースでは、クラスOffsetDateTime
ではなくTemporalAccessor
が適切です。
Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは厄介な古い レガシーに取って代わりますJava.util.Date
、 Calendar
、& SimpleDateFormat
などの日時クラス.
Joda-Time プロジェクトは現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracleチュートリアル を参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様は JSR 310 です。
Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠した JDBCドライバー を使用します。文字列も、Java.sql.*
クラスも必要ありません。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 Interval
、 YearWeek
、 YearQuarter
、 more などの便利なクラスがここにあります。
更新:のJoda-Timeプロジェクトはメンテナンスモードであり、Java.timeクラスへの移行を推奨します。このセクションは、履歴のためにそのまま残されています。
Joda-Timeのデフォルトは ISO 8601 で、文字列は解析と生成の両方が行われます。 Joda-Time にはISO 8601のデフォルトのパーサーが組み込まれているため、準拠する文字列をコンストラクターまたは静的parse
メソッドに渡すだけです。
Java.util.Date date = new DateTime( "2010-01-01T12:00:00+01:00Z" ).toDate();
可能な場合は、Java.util.Dateと.Calendarを避け、stickとJoda-Timeを使用して、DateTime
などのクラスを作成します。他のクラスで必要な場合にのみ.Dateを使用してください。
DateTime dateTimeUtc = new DateTime( someJavaDotUtilDotDate, DateTimeZone.UTC ); // Joda-Time can convert from Java.util.Date type which has no time zone.
String output = dateTime.toString(); // Defaults to ISO 8601 format.
DateTime dateTimeUtc2 = new DateTime( output, DateTimeZone.UTC ); // Joda-Time can parse ISO 8601 strings.
プレゼンテーションでは、ユーザーが期待するタイムゾーンに調整します。
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
Java8のネイティブソリューション
Date.from(ZonedDateTime.parse("1994-11-05T08:15:30+05:30").toInstant())
Date.from(ZonedDateTime.parse("1994-11-05T13:15:30Z").toInstant())