5

スケジュールを使用するアプリケーションがあります。ユーザーがスケジュールの開始/終了時刻を選択すると、その開始/終了時刻がユーザーに表示されます。問題は、DSTが変更されたため、表示される時間がずれていることです。

自分のタイムゾーン(東部標準時)の問題を修正するか、GMTの問題を修正できますが、GMTの特定のケースを設定した場合、アラスカ時間はまだ間違っています。助言がありますか?

これが私のコードです:

表示されている時間:

long startTimeMillis = (startHour * 1000 * 60 * 60) + (startMin * 1000 * 60) - getTimeOffset();

getTimeOffset:

TimeZone tz = TimeZone.getDefault();

//deal with GMT weirdness
if (tz.getRawOffset() == 0)
    return tz.getRawOffset() + tz.getDSTSavings();
else
    return tz.getRawOffset();

私は次のようなものが必要だと思います:

else if(tz.inDaylightTime(new Date()))
    return tz.getRawOffset() + tz.getDSTSavings();

しかし、そうすると、東部時間は本来より1時間短くなり、アラスカ時間は2時間短くなります。反対の場合:(+の代わりに-)

else if(tz.inDaylightTime(new Date()))
    return tz.getRawOffset() - tz.getDSTSavings();

その場合、東部時間は本来より1時間長くなりますが、アラスカ時間は正しいです。

補遺:

tz.getOffset(new Date().getTime())また、これらの状況のそれぞれで、の代わりに使用してみましtz.getRawOffset()た。Googleのドキュメントによると、この関数はDSTを処理することになっているため、これは実際に私が最初に試したものです。

補遺終了

また、次のようにカレンダーを使用してみました。

Calendar calendar = GregorianCalendar.getInstance();

return calendar.get(Calendar.ZONE_OFFSET);

これにより、EST時間の正しい時刻が得られますが、GMTの場合は1時間進み、アラスカの場合は1時間遅れます。そして私はこれを試しました:

if(tz.inDaylightTime(new Date()))
    return calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
else
    return calendar.get(Calendar.ZONE_OFFSET);

しかし、これによりEDTは1時間短くなります。

私もこれを試しました:

return tz.getOffset(calendar.get(Calendar.ERA),
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH),
            calendar.get(Calendar.DAY_OF_WEEK),
            calendar.get(Calendar.MILLISECOND));

これにより、EDTも1時間短くなります。

そして、私が使用した場合、私は同じ結果を得る

GregorianCalendar calendar = new GregorianCalendar(tz);

それ以外の

Calendar calendar = GregorianCalendar.getInstance();

どうすればこれを正しく行うことができますか?

4

2 に答える 2

5

OK、私はついにそれを適切に行う方法を見つけました。これが私がそれを機能させた方法です:

long startTimeMillis = (startHour * 1000 * 60 * 60) + (startMinute * 1000 * 60);
startTimeMillis  -= getTimeOffset(startTimeMillis);

getTimeOffset():

public static int getTimeOffset(long time)
{
    TimeZone tz = TimeZone.getDefault();

    return tz.getOffset(time);
}
于 2013-03-18T12:57:18.103 に答える
1

を介して取得しているエミュレータのタイムゾーンを設定しているようですtz.getDefault()。カレンダーは、夏時間を内部で処理します-TimeZone夏時間をまったく監視するように設定されている場合。「America/Phoenix」や「MDT」などの一部のTimeZonesは節約時間を監視しませんが、「America/Denver」は監視します。

アラスカタイムゾーンは、協定世界時(UTC-9)から9時間を差し引くことにより、標準時間を監視します。夏時間の間、その時間オフセットは8時間(UTC-8)です。https://en.wikipedia.org/wiki/Alaska_Time_Zone

を使用TimeZone.getAvailableIDs()して、すべてのTimeZone名/キーのリストを取得できます。America/Anchorage、、Etc/GMT+9の違いを確認してくださいAmerica/Alaska

編集:更新されたコードこれは、日付とDSTを試すことができるいくつかの方法のサンプルコードです。

package com.codeshane.examples;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class Times {
public static final String[] yourZoneKeys =
  {"America/Anchorage", "America/Juneau", "America/Nome", "America/Yakutat",
   "Etc/GMT+9", "Pacific/Gambier", "SystemV/YST9", "SystemV/YST9YDT","US/Alaska"};

public static void main(String[] args){
    for (String timezoneKey: yourZoneKeys){
        TimeZone tz = getSelectedTimezone(timezoneKey);
        displayTimezoneInfo(tz);
        showTimeInNewCalendar(tz);
    }       
}

static void displayTimezoneInfo(TimeZone tz){
    System.out.println(
      "\n> TZ ID:" + tz.getID() +
      "  Display:" + tz.getDisplayName() +
      "  savings:" + tz.getDSTSavings() +
      "   offset:" + tz.getRawOffset() +
      ""
    );
}

static void showTimeInNewCalendar(TimeZone tz) {
    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);

    /***** DST US 2013 = Mar 10 - Nov 3
     * Daylight Saving Time (United States) 2013
     * began at 2:00 AM on Sunday, March 10
     *  ends at 2:00 AM on Sunday, November 3
     **/

    //The Calendar method output the same results, but since both
    //methods went through the DateFormat, I went ahead and just
    //used the DateFormat's internal date via getCalendar().set(..)
    //but left the Calendar code (commented out) for you to compare.

    //Calendar gc = Calendar.getInstance();
    //gc.setTimeZone(tz);
    //gc.set(2013, 2, 10, 1, 30, 0);

    // Setting the Calendar's date and time
    df.getCalendar().set(2013, 2, 10, 1, 30, 0);

    // Display some times at 30 minute intervals
    for (int i =0;i<3;i++){

        df.setTimeZone(tz);
        System.out.println(
          "\n " + tz.getID() +
          " " + df.format(df.getCalendar().getTime()) +// sdf. .format(myDateFormat, gc) +
          //" gc date:" + df.format(gc.getTime()) +
          "  " + tz.inDaylightTime(df.getCalendar().getTime()) +
          ""
        );
        df.getCalendar().add(Calendar.MINUTE, 30);
        //gc.add(Calendar.MINUTE, 30);
    }
}

private static TimeZone getSelectedTimezone(String timezoneKey){
    if (null==timezoneKey) return TimeZone.getDefault(); // system/network-provided
    return TimeZone.getTimeZone(timezoneKey); // Gets specified tz, or "GMT" if tzKey is invalid
}

}

編集:出力の追加2013年3月10日に観察した「春先」の時間に30分が追加されると、一部のタイムゾーンが前向きになりますが、そうでないものもあります。DSTを遵守するこれらのタイムゾーンを選択すると、変更が適用されます。他の人はそうしませんが。

TZ ID:アメリカ/アンカレッジディスプレイ:アラスカ標準時間節約:3600000オフセット:-32400000

アメリカ/アンカレッジ2013年3月10日日曜日1:30:00AMAKST false

アメリカ/アンカレッジ2013年3月10日日曜日3:00:00AMAKDT true

アメリカ/アンカレッジ2013年3月10日日曜日3:30:00AMAKDT true

TZ ID:アメリカ/ジュノーディスプレイ:アラスカ標準時の節約:3600000オフセット:-32400000

アメリカ/ジュノー2013年3月10日日曜日1:30:00AMAKST false

アメリカ/ジュノー2013年3月10日日曜日3:00:00AMAKDT true

アメリカ/ジュノー2013年3月10日日曜日3:30:00AMAKDT true

TZ ID:アメリカ/ノームディスプレイ:アラスカ標準時の節約:3600000オフセット:-32400000

アメリカ/ノーム2013年3月10日日曜日1:30:00AMAKST false

アメリカ/ノーム2013年3月10日日曜日3:00:00AMAKDT true

アメリカ/ノーム2013年3月10日日曜日3:30:00AMAKDT true

TZ ID:アメリカ/ヤクタットディスプレイ:アラスカ標準時の節約:3600000オフセット:-32400000

アメリカ/ヤクタット2013年3月10日日曜日1:30:00AMAKST false

アメリカ/ヤクタット2013年3月10日日曜日3:00:00AMAKDT true

アメリカ/ヤクタット2013年3月10日日曜日3:30:00AMAKDT true

TZ ID:Etc / GMT + 9ディスプレイ:GMT-09:00節約:0オフセット:-32400000

その他/GMT+92013年3月10日日曜日1:30:00AMGMT-09:00 false

その他/GMT+92013年3月10日日曜日2:00:00AMGMT-09:00 false

その他/GMT+92013年3月10日日曜日2:30:00AMGMT-09:00 false

TZ ID:パシフィック/ガンビアディスプレイ:ガンビア時間節約:0オフセット:-32400000

パシフィック/ガンビア2013年3月10日日曜日1:30:00AMGAMT false

パシフィック/ガンビア2013年3月10日日曜日2:00:00AMGAMT false

パシフィック/ガンビア2013年3月10日日曜日2:30:00AMGAMT false

TZ ID:SystemV / YST9ディスプレイ:アラスカ標準時間の節約:0オフセット:-32400000

SystemV /YST92013年3月10日日曜日1:30:00AMAKST false

SystemV /YST92013年3月10日日曜日2:00:00AMAKST false

SystemV /YST92013年3月10日日曜日2:30:00AMAKST false

TZ ID:SystemV / YST9YDTディスプレイ:アラスカ標準時間の節約:3600000オフセット:-32400000

SystemV /YST9YDT2013年3月10日日曜日1:30:00AMAKST false

SystemV /YST9YDT2013年3月10日日曜日2:00:00AMAKST false

SystemV /YST9YDT2013年3月10日日曜日2:30:00AMAKST false

TZ ID:US /アラスカディスプレイ:アラスカ標準時の節約:3600000オフセット:-32400000

米国/アラスカ2013年3月10日日曜日1:30:00AMAKST false

米国/アラスカ2013年3月10日日曜日3:00:00AMAKDT true

米国/アラスカ2013年3月10日日曜日3:30:00AMAKDT true

また、結果を本来あるべきhttp://www.worldtimeserver.com結果と比較できるので、お勧めします。

于 2013-03-16T18:17:06.070 に答える