URI Builder gibt falschen Kalendareintrag aus

  • Antworten:7
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 9

08.11.2019, 14:40:54 via Website

Hi zusammen,

bin etwas am verzweifeln, vielleicht gibt es hier einen Experten für mein Problem.

String[] projection = new String[] {
        CalendarContract.Instances.EVENT_ID,            // 0
        CalendarContract.Instances.TITLE,               // 1
        CalendarContract.Instances.BEGIN,               // 2
        CalendarContract.Instances.END,                 // 3
 }

Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);

Calendar tomorrow = Calendar.getInstance();
tomorrow.add(Calendar.DATE, 1);
tomorrow.set(Calendar.HOUR_OF_DAY, 0);
tomorrow.set(Calendar.MINUTE, 0);
tomorrow.set(Calendar.SECOND, 0);
tomorrow.set(Calendar.MILLISECOND, 0);

ContentResolver cr = context.getContentResolver();

long startMillis = today.getTimeInMillis();
long endMillis = tomorrow.getTimeInMillis();

Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, startMillis);
ContentUris.appendId(builder, endMillis);

Cursor cur = null;
cur =  cr.query(builder.build(),
       projection,
       null,
       null,
       CalendarContract.Instances.BEGIN + " ASC");

if (cur.moveToFirst()) {
  do {
    String eventStart = Long.toString(cur.getLong(2));

      } while ( cur.moveToNext());
}

cur.close();

Wenn ich nun die Startzeit und Endzeit logge, erhalte ich:
Startzeit 1572476400000
Endzeit 1572562800000

In dem Cursor taucht aber eine Instanz von einem Event auf (Geburtstag) mit der Startzeit (Instances.BEGIN) von 1572393600000, also vor der Startzeit.

Wo liegt mein Fehler?

— geändert am 08.11.2019, 14:42:17

Diskutiere mit!
  • Forum-Beiträge: 2.284

09.11.2019, 08:24:45 via Website

Bei einer Stunden Unterschied wäre auch nicht-Beachtung von Sommer-Winter-Zeit eine mögliche Fehlerquelle. Wobei wir ja aktuell aber bei Normalzeit sind, Sommerzeit ist ja vorbei.
Auch das sollte bei Nutzung der korrekten Locale aber automatisch lösen.

Andere Möglichkeit wäre die neue Java Time API zu nutzen - JSR-310
Die ist seit Java 8 Standard und für Android gibt es einen Backport vom Guru Jake Wharton höchstpersönlich.
Sollte besser mit Zeitzonen-Spezifika umgehen. Ist aber eine Umgewöhnung :-)

https://github.com/JakeWharton/ThreeTenABP

— geändert am 09.11.2019, 08:27:27

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 9

09.11.2019, 14:45:02 via Website

Danke für die Antwort. Das war auch schon meine Vermutung und laut Foren gibt es da scheinbar einen Bug. Leider finde ich trotzdem nicht die Ursache des Problems. Dein Vorschlag führte leider auch nicht zum Ziel:

Calendar tomorrow = Calendar.getInstance(TimeZone.getDefault());

Meine Vermutung ist, dass der Filter einen Fehler macht:

 Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
            ContentUris.appendId(builder, startMillis);
            ContentUris.appendId(builder, endMillis);

Ich habe auch bei der Instanz folgende Felder geprüft, alle gaben die Zeitzone 0 zurück:

     CalendarContract.Instances.EVENT_TIMEZONE,          
     CalendarContract.Instances.CALENDAR_TIME_ZONE,      
     CalendarContract.Instances.EVENT_END_TIMEZONE,

Es gibt natürlich noch den "dirty way", einfach den Zeitraum bei der query einen Tag nach vorne und hinten zu verlängern und danach über eine if Bedingung zu prüfen. Aber den Fehler zu finden wäre natürlich schöner.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 9

09.11.2019, 14:53:24 via Website

Wie könnte man denn die Sommer- Winterzeit in der query überprüfen? :)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 852

09.11.2019, 17:46:39 via Website

Hallo mit Sommer Winter Zeit hat das nichts zu tun.

Wir haben Zone +1 im Sommer +2
0 ist London, dein Kalender arbeitet mit der Default Zone 0 wie du ja schon festgestellt hast.

addier eine Stunde dazu
ContentUris.appendId(builder, startMillis+60*60*1000);

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 9

10.11.2019, 09:53:20 via Website

Hi Jokel,

ich habe deinen Rat befolgt, komme aber irgendwie auf keinen grünen Zweig. Habe mal versucht das ganze zu visualisieren.

Die Ausgangslage, so wie die Termine im Kalender eingetragen sind:

image
Bisher wurde die Abfrage wie folgt gemacht:

Single Events Filter über DTSTART

  String selection = "(( " + CalendarContract.Events.DTSTART + " >= "
            + startMillis + " ) AND ( "
            + CalendarContract.Events.DTSTART + " <= "
            + endMillis + " ))";

  cursor = context.getContentResolver().query(
            CalendarContract.Events.CONTENT_URI,
            projection,
            selection,
            null,
            CalendarContract.Events.DTSTART + " ASC");

Recurring Events Filter über BEGIN, keine Selection

   Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
        ContentUris.appendId(builder, startMillis);
        ContentUris.appendId(builder, endMillis);

   cur =  cr.query(builder.build(),
                projection,
                null,
                null,
                CalendarContract.Instances.BEGIN + " ASC");

Resultat bei folgenden Konfigurationen:

Calendar today = Calendar.getInstance();
today.set(2019,9,30,0,0);
Calendar tomorrow = Calendar.getInstance();
tomorrow.set(2019,9,30,23,59);

Calendar today = Calendar.getInstance();
today.set(2019,9,30,0,0);
Calendar tomorrow = Calendar.getInstance();
tomorrow.set(2019,9,31,0,0);

Calendar today = Calendar.getInstance();
today.set(2019,9,31,0,0);
Calendar tomorrow = Calendar.getInstance();
tomorrow.set(2019,9,31,23,59);

image

Wenn ich zu allen startMillis und endMillis 60*60*1000 addiere:

image

Ich erhalte also nie das richtige Ergebnis :(

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 852

11.11.2019, 07:19:16 via Website

Hallo
Eigentlich funktioniert es ja ohne der Stunde dazu zu addieren. Nur die Sekunden stimmen nicht.
Das liegt daran, du holst dir ja die Instanz von dem aktuellen System Kalender Objekt mit der aktuellen System Uhr. Dann setzt du das Objekt mit „set“ auf deinen Gewünschten Tag. Die System Uhr läuft aber weiter und es dauert etwas bis der Provider das speichert. Mit dem setzen hast du warscheinlich auch die System Zeit verändert.

Erstelle dir echte neue Kalender Objekte mit „new“ setze dort das Datum, Zeit , Zeitzone.
Kannst dir ja die Zeitzone aus den aktuellen Kalender Objekt holen und in das echte neue Objekt speichern.

Hilfreich?
Diskutiere mit!