2013-03-28 2 views
15

Ich habe ein Zeitintervall bestehend aus einem Anfangs- und einem Enddatum. Ich habe eine Möglichkeit, den Benutzer diese Daten über DatePickerDialogs festlegen zu lassen. Hier ist der Code der Methode, die erstellt und zeigt die Dialoge:DatePicker.setMinDate (long minDate) löst IllegalArgumentException aus: Zeit nicht zwischen

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

Der Wert des beginning Variable bestimmt, ob die Benutzer entschieden haben, den Anfang oder das Enddatum des Intervalls zu bearbeiten. Diese someTimeDuringYear1 und ähnliche sind Mitgliedsvariablen, die sich auf das Anfangsdatum beziehen, someTimeDuringYear2 und ähnliche beziehen sich auf das Enddatum des Intervalls. Alle sind voreingestellt, bevor dieser Dialog erstellt und angezeigt wird.

Die Ausnahme wird beim Bearbeiten des Anfangs- und Endintervalls ausgelöst. Angenommen, ich möchte das Enddatum des Intervalls bearbeiten. Alles funktioniert perfekt, bis ich das Datum auf das letzte Datum setze, das mir erlaubt ist. Wenn ich das mache und bestätige, scheint alles noch in Ordnung, aber wenn ich versuche, das Enddatum des Intervalls erneut zu bearbeiten, stürzt die Anwendung ab und die Ausnahme wird ausgelöst. (Das gleiche passiert, wenn ich das Intervall des Anfangsdatum bis zum letzten erlaubt Datum festgelegt und dann versuchen Sie es erneut zu bearbeiten.)

Hier das Protokoll von LogCat ist:

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) 

ich nach Antworten gesucht haben und versuchen, den ganzen Nachmittag eine Lösung zu finden. Jede Hilfe wird geschätzt.

Vielen Dank.

PS: Das ist die erste Frage, die ich hier stelle, also entschuldige ich mich, wenn etwas nicht stimmt. Ich werde gerne fehlende Informationen über das, was passiert, bereitstellen.

EDIT: Merkwürdigerweise, obwohl das Problem auf der Linie wirft, wenn ich versuche, die minDate zu setzen, scheint es tatsächlich zu sein, dass das Datum ist „größer“ als die maxDate. Der Grund dafür, dass ich daran glaube, ist, dass, wenn ich someTimeDuringDay2 - 1 statt someTimeDuringDay2 an den Konstruktor DatePickerDialog übergebe, das Problem weg ist. Aber dann "Tag" Feld in der DatePicker ist wirklich um eins kleiner als ich es will. Ich brauche es auf someTimeDuringDay2 eingestellt, wenn die DatePickerDialog angezeigt wird, nicht zu someTimeDuringDay2 - 1. Aber es scheint ein Problem zu haben, wenn das Datum dasselbe ist wie sein maxDate.

+0

, dass eine Menge ist Text, der Einfachheit halber, was ist Zeile 344? – Sam

+0

'dpd.getDatePicker(). SetMinDate (cal.getTimeInMillis());' - in der 'else' Klausel – zbr

+0

Ich bin mir nicht sicher, was Sie in Ihrem Code tun, aber die einzige Möglichkeit, die der Fehler für mich sinnvoll ist wenn das Datum von 'someTimeDuringYear/Month/Day2' vor' cal.getTimeInMillis() 'liegt (sogar um eine Millisekunde). Vergleichen Sie die Daten selbst mit 'Log.v (" Compare ", cal.compareTo (calendar.set (someTimeDuringYear2, ...));' – Sam

Antwort

27

Das Problem war, dass Stunden, Minuten, Sekunden und Millisekunden der Kalender, die ich die DatePicker ‚s für die Einstellung minDate und maxDate auf die Werte Korrespondenten eingestellt wurde unter Verwendung wurde zu welcher Zeit es war, als Calendar.getInstance() genannt wurde. Und als ich Tag, Monat und Jahr an den Konstruktor von DatePickerDialog übergab, waren die Daten die gleichen, aber die Millisekunden unterschieden sich. So konnte es vorkommen, dass die in maxDate eingestellten Millisekunden kleiner waren als die in der aktuellen DatePicker eingestellten Millisekunden, daher wurde das Datum, das die DatePicker anzeigen sollte, als größer als maxDate gewertet (obwohl es noch am selben Tag war) mit ein paar Millisekunden) ... Und ähnlich für minDate.

Ich hoffe, es ist verständlich.

Also half es, die Kalender auf die letzte Millisekunde des Tages zu setzen, wenn Sie sie für die Einstellung maxDate und die erste Millisekunde des Tages verwenden, wenn Sie sie für die Einstellung minDate verwenden.Wie so:

(. Nur ein Stück Code aus der else Klausel)

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

Hoffe, dass es jemandem nützlich sein wird.

Auch wenn jemand mit einer eleganteren Lösung kommt, lass es mich wissen.

+0

+1 Danke ... es funktioniert für mich ...:) –

+0

bedeuten total seltsame Weise ... gibt es einen anderen Weg .... bro? – Alpan

4

Um die obige Antwort zu verbessern, entschied ich mich, dies zu posten.

Wenn Sie setMaxDate() mehrmals aufrufen, sagen wir eine dynamische Änderung in onPrepareDialog(), müssen Sie sicherstellen, dass das neue maximale Jahr nicht dem vorherigen maximalen Jahr entspricht oder der neue maximale Tag dem alten maximalen Tag entspricht .

Klingt seltsam, aber das ist der Quellcode von 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(); 
} 

für mich Also rief ich setMaxDate() zweimal. Einmal mit einem Dummy-Wert, wobei die Jahre um +100 und ein zweites Mal um die tatsächlichen Felder, die ich möchte, versetzt sind. Hier

ist das kombinierte Ergebnis:

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

Dies ist, was ich für den gleichen Fehler haben, dass ich auf Datepicker zu bekommen. Als ich MaxDate und MinDate auf DatePicker einstellte, änderten sich die Millisekunden. Für meine Bewerbung spielte es keine Rolle, ob das Datum eine Sekunde war. Ich brauchte den Unterschied zwischen min und maxdates als zwei Tage.

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

Hoffe, das hilft jemandem. Dadurch bleibt das Datum zwischen den Grenzen liegen. Möglicherweise müssen Sie den Offset basierend auf Ihrer Anwendung ändern.

2

ich die gleichen Fehler, ich das Problem beheben, indem

dialog.getDatePicker().setCalendarViewShown(false); 

in der App Einstellung jeder war calenderview nicht erforderlich ist, das ist, was ich tat

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

ich die gleiche Ausnahme bekam, wenn Heute ist nicht in [minDate, maxDate]. Aber wenn ich meinen Code geändert habe, um setMinDate() vor setMaxDate() anzurufen, funktionierte es.

+1

Ich weiß nicht, was die Logik dahinter ist. Das hat für mich total funktioniert! Der Catch ist: Dieses Problem betrifft nur Jelly-Bean-Geräte, die Lollipop-Geräte verarbeiten. Keine Ahnung von anderen Android-Versionen! – sud007

+1

Gleiche Lösung ist Arbeit für mich auch. –

0

löste ich das ähnliche Problem, indem die Grenze der Kalender zu einem Jahr einstellen (ab dem heutigen Datum)

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

Hatte ähnliches Problem mit setMinDate, das es zu lösen:

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

funktioniert sehr gut in meinem Fall – Hiren

Verwandte Themen