17

開始日と終了日からなる時間間隔があります。ユーザーが DatePickerDialogs を介してこれらの日付を設定できるようにする方法があります。ダイアログを作成して表示するメソッドのコードは次のとおりです。

private void editInterval(boolean beginning) {
    DatePickerDialog dpd;
    Calendar cal = Calendar.getInstance();
    if (beginning) {
        dpd = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {             
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                someTimeDuringYear1 = year;
                someTimeDuringMonth1 = monthOfYear + 1;
                someTimeDuringDay1 = dayOfMonth;
                Calendar cal1 = Calendar.getInstance();
                cal1.set(Calendar.YEAR, year);
                cal1.set(Calendar.MONTH, monthOfYear);
                cal1.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                Calendar cal2 = Calendar.getInstance();
                cal2.set(Calendar.YEAR, someTimeDuringYear2);
                cal2.set(Calendar.MONTH, someTimeDuringMonth2);
                cal2.set(Calendar.DAY_OF_MONTH, someTimeDuringDay2);
                if (cal1.getTimeInMillis() > cal2.getTimeInMillis()) {
                    someTimeDuringYear2 = someTimeDuringYear1;
                    someTimeDuringMonth2 = someTimeDuringMonth1;
                    someTimeDuringDay2 = someTimeDuringDay1;
                }
                updateSomeTimeDuring();
                editDepartureInterval();
            }
        }, someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1);
        dpd.setTitle(getString(R.string.beginning_of_interval));
        cal.add(Calendar.MONTH, 6);
        dpd.getDatePicker().setMaxDate(cal.getTimeInMillis());
        cal.add(Calendar.MONTH, -6);
        cal.add(Calendar.DATE, 2);
        dpd.getDatePicker().setMinDate(cal.getTimeInMillis());
    } else {
        dpd = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {             
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                someTimeDuringYear2 = year;
                someTimeDuringMonth2 = monthOfYear + 1;
                someTimeDuringDay2 = dayOfMonth;
                updateSomeTimeDuring();
                editDepartureInterval();
            }
        }, someTimeDuringYear2, someTimeDuringMonth2 - 1, someTimeDuringDay2);
        dpd.setTitle(getString(R.string.end_of_interval));
        cal.add(Calendar.MONTH, 6);
        dpd.getDatePicker().setMaxDate(cal.getTimeInMillis());
        cal.set(someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1);
        dpd.getDatePicker().setMinDate(cal.getTimeInMillis());
    }
    dpd.show();
    dpd.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}

変数の値はbeginning、ユーザーが間隔の開始日または終了日を編集することを選択したかどうかを決定します。それらsomeTimeDuringYear1と同様のものは開始日に関連するメンバー変数でsomeTimeDuringYear2あり、同様のものは間隔の終了日に関連しています。これらはすべて、このダイアログが作成および表示される前に事前設定されています。

開始間隔と終了間隔の両方を編集しているときに、例外がスローされます。インターバルの終了日を編集することを選択したとしましょう。許可されている最後の日付に日付を設定するまで、すべてが完全に機能します。それを行って確認すると、すべて問題ないように見えますが、間隔の終了日を再度編集しようとすると、アプリケーションがクラッシュし、例外がスローされます。(間隔の開始日を最後に許可された日付に設定してから、もう一度編集しようとすると、同じことが起こります。)

LogCat からのログは次のとおりです。

03-28 17:18:16.901: E/AndroidRuntime(6112): FATAL EXCEPTION: main
03-28 17:18:16.901: E/AndroidRuntime(6112): java.lang.IllegalArgumentException: Time not between Sat Mar 30 17:18:16 CET 2013 and Sat Sep 28 17:18:16 CEST 2013
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.CalendarView.goTo(CalendarView.java:805)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.CalendarView.setMinDate(CalendarView.java:487)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.DatePicker.setMinDate(DatePicker.java:315)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.skypicker.android.MainActivity.editInterval(MainActivity.java:344)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.skypicker.android.MainActivity.access$10(MainActivity.java:296)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.skypicker.android.MainActivity$5.onClick(MainActivity.java:261)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:924)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.AdapterView.performItemClick(AdapterView.java:292)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.AbsListView.performItemClick(AbsListView.java:1063)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2519)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.widget.AbsListView$1.run(AbsListView.java:3173)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.os.Handler.handleCallback(Handler.java:605)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.os.Looper.loop(Looper.java:137)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at android.app.ActivityThread.main(ActivityThread.java:4424)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at java.lang.reflect.Method.invokeNative(Native Method)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at java.lang.reflect.Method.invoke(Method.java:511)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
03-28 17:18:16.901: E/AndroidRuntime(6112):     at dalvik.system.NativeStart.main(Native Method)

私は答えを探していて、午後中ずっと解決策を考え出そうとしていました. どんな助けでも大歓迎です。

ありがとうございました。

PS: 初めて質問するので、間違っていたらすみません。何が起こっているかについて不足している情報を提供させていただきます。

編集:不思議なことに、 を設定しようとすると問題が発生しますが、minDate実際には日付が よりも「大きい」ようmaxDateです。私がこれを信じる理由は、のsomeTimeDuringDay2 - 1代わりにsomeTimeDuringDay2DatePickerDialogコンストラクターに渡すと、問題がなくなるからです。しかし、その後、「日」フィールドは、DatePicker実際には、私が望むよりも 1 つ小さくなっています。ではなく、 が表示されているsomeTimeDuringDay2ときにに設定する必要があります。しかし、日付がその日付と同じである場合、問題があるようです。DatePickerDialogsomeTimeDuringDay2 - 1maxDate

4

8 に答える 8

28

DatePicker問題は、の設定に使用していたカレンダーの時間、分、秒、およびミリ秒が、minDate呼び出されmaxDateた時刻に対応する値に設定されることでしたCalendar.getInstance()。そして、日、月、年を のコンストラクターに渡すとDatePickerDialog、日付は同じでしたが、ミリ秒が異なっていました。そのため、 maxDate に設定されたミリ秒がDatePickerの現在の時刻に設定されたミリ秒よりも小さい可能性があり、そのため、 が表示するはずだった日付DatePickerがよりも大きいと評価されましたmaxDate(たとえそれがまだ同じ日であったとしても、もう少しだけミリ秒)... 同様にminDate.

理解できることを願っています。

そのため、カレンダーを設定に使用する場合はカレンダーをその日の最後のミリ秒に設定し、設定に使用するmaxDate場合はその日の最初のミリ秒に設定することが役に立ちminDateました。そのようです:

else(節のコードの一部です。)

        dpd.setTitle(getString(R.string.end_of_interval));
        cal.add(Calendar.MONTH, 6);
        cal.set(Calendar.HOUR_OF_DAY, cal.getMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getMaximum(Calendar.MILLISECOND));
        dpd.getDatePicker().setMaxDate(cal.getTimeInMillis());
        cal.set(someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1);
        cal.set(Calendar.HOUR_OF_DAY, cal.getMinimum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
        dpd.getDatePicker().setMinDate(cal.getTimeInMillis());

それが誰かに役立つことを願っています。

また、誰かがよりエレガントな解決策を思いついたら、私に知らせてください。

于 2013-03-29T06:54:36.863 に答える
2

同じエラーが発生していました。設定して修正します

dialog.getDatePicker().setCalendarViewShown(false); 

アプリではcalenderviewは必要ありませんでした, これは私がしたことです

Calendar tempDate =Calendar.getInstance(); 
dialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis();
dialog.getDatePicker().setCalendarViewShown(false);
tempDate.add(Calendar.YEAR, -120);
dialog.getDatePicker().setMinDate(tempDate.getTimeInMillis());
于 2015-09-09T10:49:05.767 に答える
1

これは、DatePicker で発生したのと同じエラーに対して行ったことです。そのため、DatePicker で MaxDate と MinDate を設定していた頃には、ミリ秒が変化していました。私のアプリケーションでは、日付が 1 秒ずれていても問題ありませんでした。min と maxdates の差を 2 日として必要でした。

        final Calendar c = Calendar.getInstance();
        c.setTimeZone(TimeZone.getDefault());
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, year, month, day);
        long OFFSET = 1000 ; //milli seconds offset for your date.
        datePickerDialog.getDatePicker().setMaxDate(c.getTimeInMillis() + 1 * OFFSET);
        c.add(Calendar.DAY_OF_MONTH, -1);
        datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis() - 1 * OFFSET);

これが誰かに役立つことを願っています。これにより、日付が境界の間に設定されたままになります。アプリケーションに基づいてオフセットを変更する必要がある場合があります。

于 2015-08-25T20:48:42.760 に答える
0

カレンダーの制限を(今日の日付から)1年に設定することで、同様の問題を解決しました

    long A_YEAR_MILLISECOND = 12 * 30 * 24 * 60 * 60 * 1000L;

    datePickerDialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis() + A_YEAR_MILLISECOND);
    datePickerDialog.getDatePicker().setMinDate(Calendar.getInstance().getTimeInMillis());
于 2016-07-05T12:42:38.030 に答える