web-dev-qa-db-ja.com

文字列をインスタントに変換する

Java 8またはutilsパッケージを使用して、文字列のdatetimeをインスタントに変換しようとしています。

例えば.

String requestTime = "04:30 PM, Sat 5/12/2018";

Instant reqInstant should result in 2018-05-12T20:30:00.000Z

reqStringはアメリカ/トロントのタイムゾーンにあります。

これは私が試したものです

 String strReqDelTime = "04:30 PM, Sat 5/12/2018";
 Date date = new SimpleDateFormat("hh:mm a, EEE MM/dd/yyyy").parse(requestTime);
 Instant reqInstant = date.toInstant();

上記のコードの結果は"2018-05-12T23:30:00Z"

どんな助けも大歓迎です。

12
Venky

tl; dr

  • 埋め込まれていない月と日のフォーマットパターンを修正します。
  • Java.timeクラスのみを使用し、レガシークラスは使用しないでください。

考案された例:

LocalDateTime.parse(                   // Parse as an indeterminate `LocalDate`, devoid of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
    "04:30 PM, Sat 5/12/2018" ,        // This input uses a poor choice of format. Whenever possible, use standard ISO 8601 formats when exchanging date-time values as text. Conveniently, the Java.time classes use the standard formats by default when parsing/generating strings.
    DateTimeFormatter.ofPattern( "hh:mm a, EEE M/d/uuuu" , Locale.US )  // Use single-character `M` & `d` when the number lacks a leading padded zero for single-digit values.
)                                      // Returns a `LocalDateTime` object.
.atZone(                               // Apply a zone to that unzoned `LocalDateTime`, giving it meaning, determining a point on the timeline.
    ZoneId.of( "America/Toronto" )     // Always specify a proper time zone with `Contintent/Region` format, never a 3-4 letter pseudo-zone such as `PST`, `CST`, or `IST`. 
)                                      // Returns a `ZonedDateTime`. `toString` → 2018-05-12T16:30-04:00[America/Toronto].
.toInstant()                           // Extract a `Instant` object, always in UTC by definition.
.toString()                            // Generate a String in standard ISO 8601 format representing the value within this `Instant` object. Note that this string is *generated*, not *contained*.

2018-05-12T20:30:00Z

1桁のフォーマットパターンを使用する

書式設定パターンでMMを使用しました。これは、1桁の値(1月から9月まで)に先行ゼロが埋め込まれて表示されることを意味します。

しかし、入力には先行ゼロが埋め込まれていません。したがって、単一のMを使用します。

私が期待する月の日についても同じ:dではなくdd

Java.timeのみを使用してください

何年も前にJava.timeクラスに取って代わられた、面倒な欠陥のある古い日時クラス(DateSimpleDateFormat)を使用しています。新しいクラスは古いクラスに完全に取って代わります。レガシーとモダンを混在させる必要はありません。

LocalDateTime

入力文字列に time zone または offset-from-UTC のインジケータがないため、 LocalDateTime として解析します。そのような値はnot瞬間であり、notはタイムライン上のポイントです。それは、約26〜27時間の範囲に沿ったpotentialモーメントのセットにすぎません。

String input = "04:30 PM, Sat 5/12/2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "hh:mm a, EEE M/d/uuuu" , Locale.US );  // Specify locale to determine human language and cultural norms used in translating that input string.
LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString():2018-05-12T16:30

ZonedDateTime

カナダのトロント地域の人々が使用する実時間を使用した瞬間を表すために入力が意図されていることが確実な場合、ZoneIdを適用して ZonedDateTime オブジェクトを取得します。

タイムゾーンを割り当てると、ゾーン化されていないLocalDateTimeに意味が与えられます。これで、タイムライン上のポイントがあります。

ZoneId z = ZoneId.of( "America/Toronto" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  // Give meaning to that `LocalDateTime` by assigning the context of a particular time zone. Now we have a moment, a point on the timeline.

zdt.toString():2018-05-12T16:30-04:00 [アメリカ/トロント]

Instant

[〜#〜] utc [〜#〜] と同じ瞬間を見るには、 Instant を抽出します。同じ瞬間、異なる壁時計時間。

Instant instant = zdt.toInstant() ;

instant.toString():2018-05-12T20:30:00Z


Java.timeについて

Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは、面倒な古い legacy のような日時クラスに取って代わります Java.util.DateCalendar 、& SimpleDateFormat

Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracle Tutorial を参照してください。また、多くの例と説明についてはStack Overflowを検索してください。仕様は JSR 31 です。

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

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

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

ThreeTen-Extra プロジェクトは、Java.timeを追加のクラスで拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 IntervalYearWeekYearQuarter 、および more

22
Basil Bourque

コンピューター(サーバー)のタイムゾーンは米国太平洋夏時間(GMT-7)のようですが、米国東部夏時間(GMT-4)の結果が期待されます。

Instant.toString()は、UTC(GMT + 0)DateTimeをISO-8601形式で返します。 (末尾の「Z」はUTCを意味します)。

SimpleDateFormatは、指定されていない場合、コンピューターの既定のタイムゾーンのDateTime文字列を脅かします。また、入力はタイムゾーンを指定しません。

そのため、入力がどのタイムゾーンにあるかについて何かする必要があります。

PS。東部夏時間の鉱山機械では、コードはあなたが期待した通りの結果を私に与えます。

0
Vadim