2

この Java メソッドについてアドバイスが必要です。このメソッドの目的は、日付を表す文字列 (この文字列は EST タイム ゾーンの日付から作成されたもの) を取得し、それを UTC タイム ゾーンの Java Date オブジェクトに変換することです。

private Date buildValidationDate(String dateString) throws ParseException {
    System.out.println("dateString " + dateString);

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyy hh:mm a");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));  
    dateFormat.setLenient(true);
    Date dt = dateFormat.parse(dateString);

    System.out.println("dt " + dt);

    return dt;
}

私が見ている問題は、dt の値がずれているように見えることです。たとえば、dateString が「10/16/2012 12:06 PM」の場合、dt の値 (UTC) は「Tuesday, October 16, 2012 4:06 PM」のようになると予想しています。代わりに、dt の値は「Tue Oct 16 07:06:00 CDT 2012」です。これは正しい UTC 時間ではないようです。

アドバイスをいただければ幸いです。簡単な質問のようでしたら申し訳ありません。私は Java の日付に関して多くの問題を抱えています。コーディングが間違っているのか、方法論に問題があるのか​​ わかりません。ありがとう

4

2 に答える 2

4

Singhによる正しい回答が言うように、Date実際にUTCですが、そのtoString方法は文字列の生成中に現在のデフォルトのタイムゾーンを紛らわしく適用します。

ISO8601

10/16/2012 12:06 PM日時値などの形式は避けてください。テキストにシリアル化するときは、まさにこの目的のために標準として定義されているISO 8601形式を使用します。

java.time

これが簡単な質問のように思われる場合は申し訳ありません.Javaの日付に多くの問題があります.

それはあなたではありません。それはクラスです。古いレガシーの日時クラスは、日時の処理において業界をリードする勇敢な取り組みでした。しかし、それらは考えが浅く、設計が不十分で、非常に混乱し、面倒であることが判明しました。現在は java.time クラスに取って代わられています –大幅改善です。

この厄介な古いjava.util.Dateクラスは完全に避けてください。代わりに使用Instantしてください。

Instant

このクラスは、 UTCInstantのタイムライン上の瞬間をナノ秒単位(小数点以下 9 桁まで) で表します。

現在の瞬間を取得します。

Instant instant = Instant.now();

古い日時クラスに追加された新しい変換メソッドの 1 つを呼び出すことにより、Date を最新の置換に変換できます。toInstant を呼び出すだけで、非常に簡単です。

Instant instant = myJavaUtilDate.toInstant(); 

java.time クラスは、文字列の生成時にデフォルトで ISO 8601 形式を使用します。toStringオブジェクト内の値の明確な表現を取得するために呼び出すだけです。

String output = instant.toString();

2016-12-23T01:33:09.731Z

解析中

入力文字列を解析するには、一致するフォーマット パターンを定義します。パターン コードは のコードと似ていますがSimpleDateFormat、まったく同じではありません。そのため、必ずドキュメントを注意深く調べてください。

String input = "10/16/2012 12:06 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu hh:mm a" );

入力には、UTC からのオフセットまたはタイム ゾーンに関する手がかりがありません。したがって、 として解析する必要がありLocalDateTimeます。オフセットやゾーンがないため、aLocalDateTimeは可能な瞬間についての漠然とした考えにすぎず、タイムライン上のポイントを表していません。

LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString(): 2012-10-16T12:06

質問は、これが「ESTタイムゾーン」を意味していると主張しています. したがってZoneIdLocalDateTimeを取得するには、タイムゾーン a を適用する必要がありますZonedDateTime

、、、などの適切なタイム ゾーン名を の形式で指定します。またはなどの 3 ~ 4 文字の略語は絶対に使用しないでください。これらは実際のタイム ゾーンではなく、標準化されておらず、一意でもありません (!)。continent/regionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

おそらくEST、米国とカナダの東海岸の多くで使用されているタイム ゾーンを意味していたのでしょう。勝手に選びますAmerica/New_York

ZoneId z = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = ldt.atZone( z );

zdt.toString(): 2012-10-16T12:06-04:00[アメリカ/ニューヨーク]

UTC に到達するには、単純にInstant. これを概念的に次のように考えることができます。

ZonedDateTime = (インスタント + ZoneId)

Instant instant = zdt.toInstant();

インスタント.toString(): 2012-10-16T16:06:00Z

于 2016-12-23T01:37:58.223 に答える
3

あなたの日付は正しく変換されていますjava.util.Dateタイムゾーンに依存しないため、デフォルトのタイムゾーン形式で値を印刷するだけです。時間帯別の取り扱いをご希望の場合は をご利用くださいjava.util.Calendar

于 2012-10-16T16:24:38.903 に答える