【问题标题】:DatePicker.setMinDate(long minDate) throws IllegalArgumentException: Time not betweenDatePicker.setMinDate(long minDate) throws IllegalArgumentException: Time not between
【发布时间】:2013-03-19 04:30:19
【问题描述】:

我有一个由开始日期和结束日期组成的时间间隔。我有办法让用户通过 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 而不是someTimeDuringDay2 传递给DatePickerDialog 的构造函数,那么问题就消失了。但是DatePicker 中的“日”字段确实比我想要的小一。当显示DatePickerDialog 时,我需要将其设置为someTimeDuringDay2,而不是someTimeDuringDay2 - 1。但是当日期和它的maxDate相同时,它似乎有问题。

【问题讨论】:

  • 这是很多文字,为简单起见,第 344 行是什么?
  • dpd.getDatePicker().setMinDate(cal.getTimeInMillis()); - 在else 子句中
  • 我不确定你在代码中做了什么,但对我来说,错误唯一有意义的方法是 someTimeDuringYear / Month / Day2 的日期在 cal.getTimeInMillis() 之前(甚至是毫秒) .自己与Log.v("Compare", cal.compareTo(calendar.set(someTimeDuringYear2, ...));比较日期
  • 请查看我对原始问题所做的编辑。感谢您的推荐,我将尝试比较我能做到的毫秒数,希望它能让我更多地了解那里发生的事情......

标签: android datepicker datepickerdialog


【解决方案1】:

问题是我用于设置DatePickerminDatemaxDate 的日历的小时、分钟、秒和毫秒设置为与@987654324 时的时间相对应的值@ 被称为。当我将日、月和年传递给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());

希望对某人有所帮助。

另外,如果有人提出更优雅的解决方案,请告诉我。

【讨论】:

    【解决方案2】:

    当今天不在 [minDate, maxDate] 时,我遇到了同样的异常。但是,如果我将代码更改为在setMaxDate() 之前调用setMinDate(),它就起作用了。

    【讨论】:

    • 我不知道背后的逻辑是什么。这对我完全有用!问题是:这个问题只在果冻豆设备上,棒棒糖设备正在处理这个问题。不知道其他安卓版本!
    【解决方案3】:

    为了增强上面的答案,我决定发布这个。

    当多次调用 setMaxDate() 时,假设 onPrepareDialog() 发生动态变化,您必须确保新的最大年份不等于前一个最大年份或新的最大日期等于旧的最大日期。

    听起来很奇怪,但这是来自grep code的源代码

    public void setMaxDate(long maxDate) {
        mTempDate.setTimeInMillis(maxDate);
            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
                return;
            }
            mMaxDate.setTimeInMillis(maxDate);
            mCalendarView.setMaxDate(maxDate);
            if (mCurrentDate.after(mMaxDate)) {
                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
                updateCalendarView();
            }
        updateSpinners();
    }
    

    所以对我来说,我调用了两次 setMaxDate()。一次使用虚拟值,其中年份偏移 +100,第二次使用我想要的实际字段。

    综合结果如下:

    maxDate.set(Calendar.HOUR_OF_DAY, maxDate.getMaximum(Calendar.HOUR_OF_DAY));      
    maxDate.set(Calendar.MINUTE, maxDate.getMaximum(Calendar.MINUTE));                
    maxDate.set(Calendar.SECOND, maxDate.getMaximum(Calendar.SECOND));                
    maxDate.set(Calendar.MILLISECOND, maxDate.getMaximum(Calendar.MILLISECOND));      
    maxDateDummy.set(Calendar.HOUR_OF_DAY, maxDate.getMaximum(Calendar.HOUR_OF_DAY)); 
    maxDateDummy.set(Calendar.MINUTE, maxDate.getMaximum(Calendar.MINUTE));           
    maxDateDummy.set(Calendar.SECOND, maxDate.getMaximum(Calendar.SECOND));           
    maxDateDummy.set(Calendar.MILLISECOND, maxDate.getMaximum(Calendar.MILLISECOND)); 
    
    //update the dummy date by 100 years to force android OS to change max time.      
    maxDateDummy.set(Calendar.YEAR, maxDateDummy.get(Calendar.YEAR) + 100);           
    
    datePicker.setMaxDate(maxDateDummy.getTimeInMillis());                            
    datePicker.setMaxDate(maxDate.getTimeInMillis());  
    

    【讨论】:

      【解决方案4】:

      setMinDate 有类似问题,解决了:

      int year=2017, month=1, day=1; // for min. date: 1. feb. 2017
      Calendar cal = Calendar.getInstance();
      cal.set( year, month, day, 0, 0, 0 ); //hour=0 min=0 sec=0
      datePickerDialog.getDatePicker().setMinDate(cal.getTimeInMillis());
      

      【讨论】:

        【解决方案5】:

        我遇到了同样的错误,我通过设置修复它

        dialog.getDatePicker().setCalendarViewShown(false); 
        

        在应用程序中不需要任何日历视图,这就是我所做的

        Calendar tempDate =Calendar.getInstance(); 
        dialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis();
        dialog.getDatePicker().setCalendarViewShown(false);
        tempDate.add(Calendar.YEAR, -120);
        dialog.getDatePicker().setMinDate(tempDate.getTimeInMillis());
        

        【讨论】:

          【解决方案6】:

          这就是我为在 DatePicker 上遇到的相同错误所做的。因此,当我在 DatePicker 上设置 MaxDate 和 MinDate 时,毫秒数正在发生变化。对于我的申请,日期是否相差一秒并不重要。我需要 mindates 和 maxdates 之间的差异为两天。

                  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);
          

          希望这对某人有所帮助。这将使日期设置在界限之间。您可能需要根据您的应用程序更改偏移量。

          【讨论】:

            【解决方案7】:

            我通过将日历的限制设置为一年(从今天开始)解决了类似的问题

                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());
            

            【讨论】:

              【解决方案8】:

              就我而言,我在设置最大日期后设置了最小日期。它会导致崩溃。

              之前:

              if (!currentDateandTimeSampai.equalsIgnoreCase("")) {
                  datePickerDialog.getDatePicker().setMaxDate(end.getTime());
              } 
              

              datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);

              之后:

              datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);

              if (!currentDateandTimeSampai.equalsIgnoreCase("")) {
                   if (isSameDate(new Date(), end)){
                        datePickerDialog.getDatePicker().setMaxDate(new Date().getTime());
                   }else {
                        datePickerDialog.getDatePicker().setMaxDate(end.getTime());
                   }
               }
              

              您可以添加此功能来检查您的 maxDate 是否与当天是同一天:

              public boolean isSameDate(Date date1, Date date2) {
                  Calendar cal1 = Calendar.getInstance();
                  Calendar cal2 = Calendar.getInstance();
                  cal1.setTime(date1);
                  cal2.setTime(date2);
                  return cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) &&
                          cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
              }
              

              【讨论】:

                猜你喜欢
                • 2018-09-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-06-13
                • 2022-01-26
                相关资源
                最近更新 更多