Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 2964f7e4 authored by Sunik Kupfer's avatar Sunik Kupfer Committed by GitHub
Browse files

find best matching android tzID straight away (#66)



* 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: default avatarRicki Hirner <hirner@bitfire.at>
parent c2ba1161
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -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).
+7 −17
Original line number Diff line number Diff line
@@ -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.
+17 −6
Original line number Diff line number Diff line
@@ -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)

    /**