diff options
author | Sunik Kupfer <kupfer@bitfire.at> | 2022-11-09 14:38:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-09 14:38:03 +0300 |
commit | 2964f7e48f0fdb8a339d8d84db6b33672f101c12 (patch) | |
tree | 1ca0a24d85490a70a21f20c5ec8f9d849ce8cfee | |
parent | c2ba1161292c8f8d5d9b23c9e96b07002cfb666d (diff) |
* find best matching android tzID straight away, so startTz won't be null later on
* Replace bestMatchingAndroidTzId by explicit code
* Add comments
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
3 files changed, 29 insertions, 28 deletions
diff --git a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt index 9f593ea..b4823c1 100644 --- a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt +++ b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt @@ -216,11 +216,12 @@ abstract class AndroidEvent( } else /* !allDay */ { // use DATE-TIME values - val startTz = row.getAsString(Events.EVENT_TIMEZONE)?.let { tzId -> - DateUtils.ical4jTimeZone(tzId) - } + + // check time zone ID (calendar apps may insert no or an invalid ID) + val startTzId = DateUtils.findAndroidTimezoneID(row.getAsString(Events.EVENT_TIMEZONE)) + val startTz = DateUtils.ical4jTimeZone(startTzId) val dtStartDateTime = DateTime(tsStart).apply { - if (startTz != null) { + if (startTz != null) { // null if there was not ical4j time zone for startTzId, which should not happen, but technically may happen if (TimeZones.isUtc(startTz)) isUtc = true else @@ -228,7 +229,6 @@ abstract class AndroidEvent( } } event.dtStart = DtStart(dtStartDateTime) - AndroidTimeUtils.androidifyTimeZone(event.dtStart) // because it may have an ical4j timezone ID that is not available in Android // Android events MUST have duration or dtend [https://developer.android.com/reference/android/provider/CalendarContract.Events#operations]. // Assume 1 hour if missing (should never occur, but occurs). diff --git a/src/main/java/at/bitfire/ical4android/util/AndroidTimeUtils.kt b/src/main/java/at/bitfire/ical4android/util/AndroidTimeUtils.kt index ec4388a..2bf3671 100644 --- a/src/main/java/at/bitfire/ical4android/util/AndroidTimeUtils.kt +++ b/src/main/java/at/bitfire/ical4android/util/AndroidTimeUtils.kt @@ -54,8 +54,8 @@ object AndroidTimeUtils { */ fun androidifyTimeZone(date: DateProperty?) { if (DateUtils.isDateTime(date) && date?.isUtc == false) { - val tzID = date.timeZone?.id - date.timeZone = bestMatchingTzId(tzID) + val tzID = DateUtils.findAndroidTimezoneID(date.timeZone?.id) + date.timeZone = DateUtils.ical4jTimeZone(tzID) } } @@ -71,11 +71,11 @@ object AndroidTimeUtils { // periods (RDate only) val periods = (dateList as? RDate)?.periods if (periods != null && periods.size > 0 && !periods.isUtc) { - val tzID = periods.timeZone?.id + val tzID = DateUtils.findAndroidTimezoneID(periods.timeZone?.id) - // Won't work until resolved in ical4j (https://github.com/ical4j/ical4j/discussions/568) + // Setting the time zone won't work until resolved in ical4j (https://github.com/ical4j/ical4j/discussions/568) // DateListProperty.setTimeZone() does not set the timeZone property when the DateList has PERIODs - dateList.timeZone = bestMatchingTzId(tzID) + dateList.timeZone = DateUtils.ical4jTimeZone(tzID) return // RDate can only contain periods OR dates - not both, bail out fast } @@ -84,22 +84,12 @@ object AndroidTimeUtils { val dates = dateList.dates if (dates != null && dates.size > 0) { if (dates.type == Value.DATE_TIME && !dates.isUtc) { - val tzID = dates.timeZone?.id - dateList.timeZone = bestMatchingTzId(tzID) + val tzID = DateUtils.findAndroidTimezoneID(dates.timeZone?.id) + dateList.timeZone = DateUtils.ical4jTimeZone(tzID) } } } - private fun bestMatchingTzId(tzID: String?): TimeZone? { - val bestMatchingTzId = DateUtils.findAndroidTimezoneID(tzID) - return if (tzID == bestMatchingTzId) { - DateUtils.ical4jTimeZone(tzID) - } else { - Ical4Android.log.warning("Android doesn't know time zone ${tzID ?: "\"null\" (floating)"}, setting default time zone $bestMatchingTzId") - DateUtils.ical4jTimeZone(bestMatchingTzId) - } - } - /** * Returns the time-zone ID for a given date or date-time that should be used to store it * in the Android calendar provider. diff --git a/src/main/java/at/bitfire/ical4android/util/DateUtils.kt b/src/main/java/at/bitfire/ical4android/util/DateUtils.kt index 6c0060e..2962cd3 100644 --- a/src/main/java/at/bitfire/ical4android/util/DateUtils.kt +++ b/src/main/java/at/bitfire/ical4android/util/DateUtils.kt @@ -39,15 +39,15 @@ object DateUtils { // time zones /** - * For a given time zone ID taken from an iCalendar resource, find the matching - * Android time zone ID (if possible): + * Find the best matching Android (= available in system and Java timezone registry) + * time zone ID for a given arbitrary time zone ID: * * 1. Use a case-insensitive match ("EUROPE/VIENNA" will return "Europe/Vienna", - * assuming "Europe/Vienna") is available in Android + * assuming "Europe/Vienna") is available in Android. * 2. Find partial matches (case-sensitive) in both directions, so both "Vienna" - * and "MyClient: Europe/Vienna" will return "Europe/Vienna". This shouldn't be - * case-sensitive, because that would (for instance) return "EST" for "Westeuropäische Sommerzeit" - * 3. If nothing can be found, use the system default time zone + * and "MyClient: Europe/Vienna" will return "Europe/Vienna". This shouln't be + * case-insensitive, because that would for instance return "EST" for "Westeuropäische Sommerzeit". + * 3. If nothing can be found or [tzId] is `null`, return the system default time zone. * * @param tzID time zone ID to be converted into Android time zone ID * @@ -95,6 +95,17 @@ object DateUtils { @Suppress("DEPRECATION") @UsesThreadContextClassLoader + /** + * Loads a time zone from the ical4j time zone registry (which contains the + * VTIMEZONE definitions). + * + * All Android time zone IDs plus some other time zones should be available. + * However, the possibility that the time zone is not available in ical4j should + * be handled. + * + * @param id time zone ID (like `Europe/Vienna`) + * @return the ical4j time zone (VTIMEZONE), or `null` if no VTIMEZONE is available + */ fun ical4jTimeZone(id: String): TimeZone? = tzRegistry.getTimeZone(id) /** |