0

私は、使用ごとに情報を保存するアプリに取り組んでいます。このデータは、基本的に、今日、今週、今月、およびアプリの有効期間中にイベントが発生した回数をカウントすることになります。このデータを、SharedPreferences を使用してロード/保存できる 4 つの異なるカウンターに保存します。

アプリの「最終実行時間」を日付として保存するデータに加えて、ロード時にカウンターにロードし、保存された日付を今日の日付に対してテストして、どのカウンターをクリアする必要があるかを判断するという計画でした。

シンプルですね!

しばらく髪を伸ばして、Calendar のドキュメントを行ったり来たりした後、次のことを思い付くのに十分理解できたと思います。

    Calendar last = Calendar.getInstance();
    last.setTimeInMillis(lastDate);

    Calendar today = Calendar.getInstance();
    today.add(Calendar.DATE, -1);

    if ( !last.after(today) )
    {
                     today = 0;
    }

    today.add(Calendar.WEEK_OF_MONTH, -1);
    today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

    if ( !last.after(today) )
    {
                     today = 0;
                     week = 0;
    }

    today = Calendar.getInstance();
    today.add(Calendar.MONTH, -1);
    today.set(Calendar.DATE, today.getActualMaximum(Calendar.DATE));

    if ( !last.after(today) )
    {
                     today = 0;
                     week = 0;
                     month = 0;
    }   

これで問題ないと思いますが、問題はテストです。今日のテストは簡単ですが、月のロジックをテストするには、1 か月待つか、Calendar API を使用して古い日付をシミュレートするテスト ケースを作成する必要がありますが、 API がどのように機能するかについての私の仮定がそもそも間違っていたら、テスト ケースを書くことはできません。

したがって、テキストの大きな壁の後に私の質問は...上記のコードブロックは正気に見えますか、それともJavaで日付を操作することを完全に誤解していますか?

ありがとう!

編集:

コードでの 2 番目のパス:

これはより賢明に見えますか?私が物事を正しく理解している場合、最後に保存された日付の終わりを今日、今週、今月の始まりと比較しようとしています。

Calendar last = Calendar.getInstance();
    last.setTimeInMillis(lastDate);

    last.set(Calendar.HOUR_OF_DAY, last.getActualMaximum(Calendar.HOUR_OF_DAY));
    last.set(Calendar.MINUTE, last.getActualMaximum(Calendar.MINUTE));
    last.set(Calendar.SECOND, last.getActualMaximum(Calendar.SECOND));
    last.set(Calendar.MILLISECOND, last.getActualMaximum(Calendar.MILLISECOND));

    Calendar todayStart = Calendar.getInstance();
    todayStart.set(Calendar.HOUR_OF_DAY, todayStart.getActualMinimum(Calendar.HOUR_OF_DAY));
    todayStart.set(Calendar.MINUTE, todayStart.getActualMinimum(Calendar.MINUTE));
    todayStart.set(Calendar.SECOND, todayStart.getActualMinimum(Calendar.SECOND));
    todayStart.set(Calendar.MILLISECOND, todayStart.getActualMinimum(Calendar.MILLISECOND));

    // If the last recorded date was before the absolute minimum of today
    if ( last.before(todayStart) )
    {
        todayCount = 0;
    }

    Calendar thisWeekStart = Calendar.getInstance();
    thisWeekStart.set(Calendar.HOUR_OF_DAY, thisWeekStart.getActualMinimum(Calendar.HOUR_OF_DAY));
    thisWeekStart.set(Calendar.MINUTE, thisWeekStart.getActualMinimum(Calendar.MINUTE));
    thisWeekStart.set(Calendar.SECOND, thisWeekStart.getActualMinimum(Calendar.SECOND));
    thisWeekStart.set(Calendar.DAY_OF_WEEK, thisWeekStart.getFirstDayOfWeek());
    thisWeekStart.set(Calendar.MILLISECOND, thisWeekStart.getActualMinimum(Calendar.MILLISECOND));

    // If the last date was before the absolute minimum of this week then clear
    // this week (and today, just to be on the safe side)
    if ( last.before(thisWeekStart) )
    {
        todayCount = 0;
        weekCount = 0;
    }

    Calendar thisMonthStart = Calendar.getInstance();
    thisMonthStart.set(Calendar.HOUR_OF_DAY, thisMonthStart.getActualMinimum(Calendar.HOUR_OF_DAY));
    thisMonthStart.set(Calendar.MINUTE, thisMonthStart.getActualMinimum(Calendar.MINUTE));
    thisMonthStart.set(Calendar.SECOND, thisMonthStart.getActualMinimum(Calendar.SECOND));
    thisMonthStart.set(Calendar.DAY_OF_MONTH, thisMonthStart.getActualMinimum(Calendar.MONTH));
    thisMonthStart.set(Calendar.MILLISECOND, thisMonthStart.getActualMinimum(Calendar.MILLISECOND));

    // If the last date was before the absolute minimum of this month then clear month...
    if ( !last.after(thisMonthStart) )
    {
        todayCount = 0;
        weekCount = 0;
        monthCount = 0;
    }   
4

3 に答える 3

1

「今日」と呼ばれる変数を使用し、それを「今日」ではないあらゆる種類のものに設定するという読みやすさの課題を除いて、あなたは時間を処理していません。

今が3:20で、1月31日の午後5時に何かが起こった場合でも、それを1月に起こったと見なしたいと思いますか?時間に関連するフィールドも1日の終わりまで最大にする必要があります。

週のことについては、日曜日が週の最初の日と見なされるロケールで誰かが実行する場合、それは本当に混乱する可能性があります。日曜日ではなく、システムの最初の曜日の使用を検討することをお勧めします。

また、これはCalendar.add()適切に機能するためのの使用に明示的に依存していることに注意する価値があります。 同じことではなく、壊れてしまいcal.set(Calendar.MONTH, cal.get(Calendar.MONTH) -1);ます

于 2013-02-07T22:22:02.753 に答える
1

Joda-Timeを使用する必要があります。コードを実行すると、次のようになります。

DateTime oneMonthAgo = new DateTime().minusMonths(1);
DateTime oneWeekAgo = new DateTime().minusWeeks(1);

など...JDK自体以外の依存関係は必要なく、Androidで動作します。お役に立てば幸いです。

于 2013-02-08T21:03:04.257 に答える