1

一部のユーザーのタイムゾーンを夏時間証明形式で保存したいと思います。
私の目標は、コードが実行されるたびに正しいGMTオフセットを取得することです。
私の最良の選択肢を見つけるために、私は次のように書いた:

ArrayList<String> list = new ArrayList<String>();
list.add( "EST");
list.add( "EDT");
list.add( "America/New_York");
long now = System.currentTimeMillis();
for( String tzID: list) {
    TimeZone tz = TimeZone.getTimeZone( tzID);
    System.out.println( tzID + " now=" + tz.getOffset( now) / 3600000 + " / +182=" + tz.getOffset( now + ( 182 * 86400000)) / 3600000);
}

簡単に言えば、今オフセットを教えてください。182日で
9月3日に実行され、出力は次のようになります。

EST now=-5 / +182=-5
EDT now=0 / +182=0
America/New_York now=-4 / +182=-4

これはいくつかの理由で予想外です
1)なぜAmerica/New_Yorkは-4/-5を与えないのですか?、それは日付に敏感であるはずではありませんか?
2)EDT == UTCなのはなぜですか?

4

2 に答える 2

3

あなたが抱えている問題の1つは、182*86400000がオーバーフローすることです。使用する場合

long now = System.currentTimeMillis();
for( String tzID: "EST,EDT,America/New_York".split(",")) {
    TimeZone tz = TimeZone.getTimeZone( tzID);
    System.out.println( tz.getDisplayName() + " now=" + tz.getOffset( now) / 36e5 
                     + " / +182=" + tz.getOffset( now + 182 * 86400000L) / 36e5);
}

プリント

Eastern Standard Time now=-5.0 / +182=-5.0
Greenwich Mean Time now=0.0 / +182=0.0
Eastern Standard Time now=-4.0 / +182=-5.0

getTimeZoneのjavadocとソースを見ると、次のことがわかります。

 * @return the specified <code>TimeZone</code>, or the GMT zone if the given ID
 * cannot be understood.

public static synchronized TimeZone getTimeZone(String ID) {
return getTimeZone(ID, true);
}

private static TimeZone getTimeZone(String ID, boolean fallback) {
TimeZone tz = ZoneInfo.getTimeZone(ID);
if (tz == null) {
    tz = parseCustomTimeZone(ID);
    if (tz == null && fallback) {
    tz = new ZoneInfo(GMT_ID, 0);
    }
}
return tz;
}

つまり、EDTは認識されないため、GMTになります。

于 2012-09-03T13:27:21.290 に答える
2

これが問題だと思います:

now + ( 182 * 86400000)

括弧で囲まれた算術式は32ビットをオーバーフローします。あなたはおそらく欲しい:

now + ( 182 * 86400000L)

ただし、それでも、夏時間が約6か月間適用されることを前提としています。これは、現実の世界では確かに当てはまりません。たとえば、サンパウロのタイムゾーンを見ると、10月と2月に切り替わります。したがって、9月にコードを実行すると、-3/-3が表示されます。DSTがほぼ6か月ごとにオン/オフに切り替わるタイムゾーンの場合でも、切り替えなしで毎年182日連続で検出される可能性が非常に高くなります(ほぼ定義上、半年弱であることを考えると)。

何をしようとしているのかは明確ではありませんが、「America /New_York」などのタイムゾーンIDを保存するだけでよいのではないかと思います。他のほとんどすべてがトラブルを求めています。

于 2012-09-03T13:25:01.250 に答える