6

以下のコードに従って、指定されたタイムゾーンで指定された dateTime に Date オブジェクトを作成しています。
注: jvm のタイムゾーンは設定していません。ただし、このコードを別の Linux サーバーのタイムゾーンでテストしています。

    String date = "20121225 10:00:00";
    String timeZoneId = "Asia/Calcutta";
    TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);

    DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z");
                //This date object is given time and given timezone
    java.util.Date parsedDate = dateFormatLocal.parse(date + " "  
                     + timeZone.getDisplayName(false, TimeZone.SHORT));

    if (timeZone.inDaylightTime(parsedDate)) {
        // We need to re-parse because we don't know if the date
        // is DST until it is parsed...
        parsedDate = dateFormatLocal.parse(date + " "
                + timeZone.getDisplayName(true, TimeZone.SHORT));
    }


jvm
サーバーがISTで実行されている場合、 parsedDate オブジェクトの動作が異なり ます30:00 GMT jvm サーバーが EST で実行されている場合 parsedDate.getTime() -- 1356422400000 parsedDate.toString() -- Tue Dec 25 03:00:00 GMT の EST 2012 --- 12/25/2012 08:00 :00 GMT







私の両方のシステム時間は同期しています
Mon Dec 24 10:30:04 EST 2012
Mon Dec 24 21:00:48 IST 2012
両方のマシンで同じ GMT 時間を取得することを期待しています。
ここで何が問題だったのですか?

4

3 に答える 3

4

問題は、IST を解析しようとしていて、デフォルトの「場所」によって意味が異なることだと思います。

Time Zone Abbreviation  Zone Description    Relative UTC
IST     Irish Summer Time   UTC+01
IST     Israeli Standard Time   UTC+02
IST     Iran Standard Time  UTC+0330
IST     Indian Standard Time    UTC+0530

場所がインドの場合、IST は期待どおりに処理されますが、米国を使用している場合は、別のタイム ゾーンが推測されます。

解決策は、3 文字のタイムゾーンを使用せず、明示的に設定することです。

String date = "20121225 10:00:00";
String timeZoneId = "Asia/Calcutta";
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);

DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
dateFormatLocal.setTimeZone(timeZone);

Date parsedDate = dateFormatLocal.parse(date);

http://www.worldtimezone.com/wtz-names/wtz-ist.html

于 2012-12-28T20:48:56.100 に答える
3

短縮名は一意ではないため、タイム ゾーンを識別するのに適した方法ではありません。のJavadocjava.util.TimeZoneは、「「CST」は米国の「中央標準時」および「中国標準時」である可能性があるという例を示しています。

より一般的に。. . タイムゾーンを文字列として渡して解析するのではなく、既に持っているインスタンスを使用して、タイムゾーンが何であるかDateFormatを伝える方が理にかなっています。DateFormatTimeZone

    DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    dateFormatLocal.setTimeZone(timeZone);
    java.util.Date parsedDate = dateFormatLocal.parse(date);

(これにより、可能な範囲で自動的に夏時間も処理されます。)

于 2012-12-28T20:35:27.607 に答える
1

短縮されたタイムゾーン名を使用すると問題が発生し、ローカル環境、特にローカルのデフォルトによって結果が異なることを示す簡単なGroovyTimeZoneスクリプトを次に示します。

を解析したいとし2015-02-20T17:21:17.190ESTます。EST =米国東海岸の意味での東部標準時、つまりニューヨーク市の時間と見なします。したがって、エポック時間は正確に であると予想されます。1424470877190またはGMT: Fri, 20 Feb 2015 22:21:17.190 GMT、これESTが であるためですGMT-0500TimeZone以下は、現在のデフォルトがどのようESTに解釈されるかを示すテスト スクリプトです。

import java.util.*
import java.text.*

SimpleDateFormat sdf

TimeZone.setDefault(TimeZone.getTimeZone("Australia/Sydney"))
printDefaultTimeZone()

sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz")

checkTime(sdf.parse("2015-02-20T17:21:17.190EST").getTime())
checkTime(sdf.parse("2015-02-20T17:21:17.190-0500").getTime())

TimeZone.setDefault(TimeZone.getTimeZone("EST"))
printDefaultTimeZone()

// same SDF

checkTime(sdf.parse("2015-02-20T17:21:17.190EST").getTime())
checkTime(sdf.parse("2015-02-20T17:21:17.190-0500").getTime())

printDefaultTimeZone()

// new SDF
sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz")

checkTime(sdf.parse("2015-02-20T17:21:17.190EST").getTime())
checkTime(sdf.parse("2015-02-20T17:21:17.190-0500").getTime())

void printDefaultTimeZone() {
    println(TimeZone.getDefault().getDisplayName() + ":" +     TimeZone.getDefault().getRawOffset() / 3600 / 1000)
}

void checkTime(long time) {
    println(time + (time == 1424470877190L ? ": CORRECT" : ":"))
}

出力:

Eastern Standard Time (New South Wales):10 1424413277190: 1424470877190: CORRECT Eastern Standard Time:-5 1424413277190: 1424470877190: CORRECT Eastern Standard Time:-5 1424470877190: CORRECT 1424470877190: CORRECT

上記の出力では、予期しない/正しくない datetime は1424413277190 = GMT: Fri, 20 Feb 2015 06:21:17.190 GMTであり、これは解析された時間 (この場合は のバリアント) よりも11時間早いです。これは、その日付に夏時間が適用されるためです。ESTAustralia/SydneyEST

したがって、 の解釈は、構築時のESTデフォルトに依存することがわかります。最初の 2 つの変換バッチでは、デフォルトはで、それ自体が と省略されているため、Java は省略形をそのまま解釈します。デフォルトの TZ が変更された後、新しい SDF が構築されるまで、省略形が期待どおりに適用されていることがわかりません。TimeZoneTimeZoneAustralia/SydneyEST

デフォルトのタイムゾーンを設定する代わりにCalendar、SDF にインスタンスを設定することもできます。

sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz")
sdf.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("America/New_York"), new Locale("en_US")))

ESTこれにより、当初の予想どおりに解釈する効果が得られます。

于 2016-06-02T00:27:46.573 に答える