1

私は11月7日に激怒しています。

2 つの Java Date オブジェクト間の日数を計算するメソッドを作成しました (言及される前に、JodaTime はオプションではありません)。このメソッドはほとんどの場合機能しますが、開始 xor 終了日が日中に発生した場合時間を節約すると、出力は 1 日ずれます。

カレンダーには日付のタイムゾーンをオーバーライドする方法がありますか? 日付が実際にどのタイムゾーンにあるかは気にしませんが、同じである必要があります!

以下のコード:

public int getDayRange() {

        //startDate = "Sat Nov 06 00:00:00 EDT 2010";
        //endDate = "Sun Nov 07 23:59:59 EST 2010";

    TimeZone tz = TimeZone.getTimeZone("UTC");

    GregorianCalendar cal1 = new GregorianCalendar(tz); 
    GregorianCalendar cal2 = new GregorianCalendar(tz); 

    cal1.setTime(startDate);
    cal2.setTime(endDate);

    long ms1 = cal1.getTime().getTime(); 
    long ms2 = cal2.getTime().getTime(); 
    long difMs = ms2-ms1; 
    long msPerDay = 1000*60*60*24; 

    double days = difMs / msPerDay;

    return (int) Math.floor(days)+1;
        //returns 3(!!!) days (wrong)
}
4

2 に答える 2

5

1000 * 60 * 60*24を1日として使用して日数を数えようとしないでください。それは明らかに間違っています。何らかの理由で本当に自分で計算を実装する必要がある場合は、カレンダーのYEARフィールドとDAY_OF_YEARフィールドを使用して、実際の日の差異をカウントします。

java.util.Dateに関連付けられたタイムゾーン情報がないため、のタイムゾーンを単純に「オーバーライド」することはできません。解釈される予定のタイムゾーンを把握し、人間の表現に変換するときにそのタイムゾーンを使用する必要があります。お気づきのように、UTCを任意に使用して解釈すると、一貫した結果が得られません。

  public int getDayRange() {

        //startDate = "Sat Nov 06 00:00:00 EDT 2010";
        //endDate = "Sun Nov 07 23:59:59 EST 2010";

    TimeZone tz1 = TimeZone.getTimeZone("EDT");
    TimeZone tz2 = TimeZone.getTimeZone("EST");

    GregorianCalendar cal1 = new GregorianCalendar(tz1); 
    GregorianCalendar cal2 = new GregorianCalendar(tz2); 

    cal1.setTime(startDate);
    cal2.setTime(endDate);

    if (cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) {
        return cal2.get(Calendar.DAY_OF_YEAR) - cal1.get(Calendar.DAY_OF_YEAR) + 1;
    } else {
        //this gets complicated, but you can see what to do, plenty of examples online
    }

  }
于 2012-11-27T21:43:41.370 に答える
1

システムはすべてのタイムスタンプを UTC で保存する必要があります。
そうしないと、それが機能することはありません。
そうすれば、差の計算は簡単です。

localTime も表示する必要がある場合は、TimeZone と日付をペアとして保存する必要があります。例: (long timeUtc, int timezoneOffSetToUtc)。timezoneOffSetToUtc は、ペアの作成日に有効なオフセットです。

TimeZone は、("Austria / Vienna") のような String からのみインスタンス化する必要があります。

于 2012-11-27T22:06:29.907 に答える