1

さて、これは私を困惑させています。この文字列を作成しようとする次のコードがあります。

出力:52。2012(12月24日から12月30日)

これは、2012年の第52週の開始と終了であり、月曜日が週の最初の日です。

private Date getDateObject() {
    Calendar cld = Calendar.getInstance();
    cld.set(Calendar.YEAR, year);
    cld.set(Calendar.WEEK_OF_YEAR, week);
    cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    return cld.getTime();
}

private Date getEndDateObject() {
    Calendar cld = Calendar.getInstance();

    if (week < 52) {
        cld.set(Calendar.YEAR, year);
        cld.set(Calendar.WEEK_OF_YEAR, week + 1);
    } else {
        cld.set(Calendar.YEAR, year + 1);
        cld.set(Calendar.WEEK_OF_YEAR, 1);
    }

    cld.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
    return cld.getTime();
}

public String getDateRangeString() {
    String pattern = "d MMM";
    SimpleDateFormat formatter = new SimpleDateFormat(pattern); 

    Date startDate = getDateObject();
    Date endDate = getEndDateObject();

    String startDateFormatted = formatter.format(startDate);
    String endDateFormatted = formatter.format(endDate);

    String dateString = "" + this.week + ". " + this.year + " (" + startDateFormatted + " to " + endDateFormatted + ")";
    return dateString;
}

YEAR=2012およびWEEK=52のオブジェクトで関数getDateRangeStringを使用すると、次のデバイスで次の出力が得られます。

  • NexusS-4.1
  • エミュレータ4.1
  • エミュレータ4.2

出力:52。2012(12月24日から12月30日)

どちらが正しい!

しかし、4.2.1を実行しているNexus7では次のようになります。

出力:52。2012(12月24日から1月6日)

WTF !!?!?

すべてのデバイスはオーストラリアEST+10に設定されており、現在正しい時刻/日付を持っています。これは、4.2で12月が欠落していることとは関係がないと思いますが、とにかく4.2.1で修正する必要があります。

デバッグすると、カレンダーに正しい値がすべて含まれていると表示されます。それでは1月6日が出ますか?

12月31日の奇妙な1つは、53週目か何かのようなものですか?わからない、なぜこのデバイスが違うのかわからない。

4

1 に答える 1

3

オーケー、まず最初に、あらゆる種類の問題を回避するために週の終わりに 6 日を追加するという提案をしてくれた Jon Skeet に感謝します。それは間違いなく進むべき道です。

したがって、今後の参考のために、Java Calendar / Date を使用しないでください。しかし、偶然にもすべてのデバイス/プラットフォームでコードが動作するようになりました。

これが私の変更されたコードです:

private Date getDateObject() {
    Calendar cld = Calendar.getInstance();
    cld.set(Calendar.YEAR, year);
    cld.set(Calendar.WEEK_OF_YEAR, week);
    cld.get(Calendar.DAY_OF_WEEK); // WARNING this line is required to make the code work. Might have something to do with an inner function called complete which gets called on get.
    cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    return cld.getTime();
}

private Date getEndDateObject() {
    Date endDateObject = getDateObject();
    long timeMilliseconds = endDateObject.getTime();
    long sixDaysMilliseconds = 60 * 60 * 24 * 6 * 1000;
    endDateObject.setTime(timeMilliseconds + sixDaysMilliseconds);
    return endDateObject;
}

ラインに特に注意してください

    cld.get(Calendar.DAY_OF_WEEK);

ゲッターがカレンダーの出力に影響を与えている理由を誰かが説明できる場合は、それらにボーナスポイントがあります。しかし、申し訳ありませんが、私がこれに出くわした唯一の理由は、Log.i を取得し、コードがすべてのデバイスで機能していたことです。その後、クリーンアップしてデバッグとコメント付きのコードをすべて削除すると、再び動作しなくなりました。だから私は最終的にそれをゲッターに落としました。その行をコメントすると、戻ってくる日付が間違っていて、さらに悪いことに.....ロギングが異なる年と週を使用していることを示していても、カレンダーへのすべての呼び出しは同じ日付/時刻を返します.....要するに、可能であればJava Dateを使用しないでください。

ただし、古いコードを使用した場合、4.2.1 の Nexus 7 が最後の週に別の日付を返す理由はまだ説明されていません。私の 4.2 エミュレーターと Nexus 7 4.2.1 の間に違いがあると仮定することもできますが、そうではないようです。

とはいえ、6日間の追加方法を使用するのが最も安全で、全面的に機能するようです.

次回は Joda Time を使いますが、今は使い方を考える時間がありません。

助けてくれたすべての人に感謝しますが、これはまだ 2 つの点で奇妙なミステリーです。

  • getter が Calendar 関数の出力を変更するのはなぜですか? 私の推測では、内部的に呼び出すと主張する完全なメソッドと関係があると思います。しかし、ドキュメントに記載されていても、完全な自己とは言えません。

  • nexus 7 4.2.1 は、カレンダー機能にまったく同じパラメーターが供給されている場合、他のすべてのデバイス/エミュレーターとは異なる週を取得するのはなぜですか?

変。

于 2013-01-21T06:00:33.403 に答える