Commit 4604c15f authored by Ricki Hirner's avatar Ricki Hirner

Better matching of time zone IDs

parent ec7bfbc4
......@@ -11,7 +11,7 @@ cache:
test:
script:
- (cd /sdk/emulator; ./emulator @test -no-audio -no-window & wait-for-emulator.sh)
- (mkdir -p apk && cd apk && wget -q https://f-droid.org/repo/org.dmfs.tasks_481.apk && adb install org.dmfs.tasks_481.apk)
- (mkdir -p apk && cd apk && wget -nc -q https://f-droid.org/repo/org.dmfs.tasks_481.apk && adb install org.dmfs.tasks_481.apk)
- ./gradlew check connectedCheck
artifacts:
paths:
......
......@@ -8,16 +8,13 @@
package at.bitfire.ical4android
import net.fortuna.ical4j.data.CalendarBuilder
import net.fortuna.ical4j.model.*
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.TimeZone
import net.fortuna.ical4j.model.component.VTimeZone
import net.fortuna.ical4j.model.parameter.Value
import net.fortuna.ical4j.model.property.DateListProperty
import net.fortuna.ical4j.model.property.ExDate
import net.fortuna.ical4j.model.property.RDate
import java.io.StringReader
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
......@@ -30,12 +27,27 @@ import java.util.*
*/
object DateUtils {
/**
* global ical4j time zone registry used for event/task processing
*/
@JvmField
val tzRegistry = TimeZoneRegistryFactory.getInstance().createRegistry()!!
// time zones
/**
* For a given time zone ID taken from an iCalendar resource, find the matching
* Android time zone ID (if possible):
* 1. Use a case-insensitive match ("EUROPE/VIENNA" will return "Europe/Vienna",
* 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
* @param tzID time zone ID to be converted into Android time zone ID
* @return best matching Android time zone ID
*/
@JvmStatic
fun findAndroidTimezoneID(tzID: String): String {
val availableTZs = SimpleTimeZone.getAvailableIDs()
......@@ -46,38 +58,21 @@ object DateUtils {
// if that doesn't work, try to find something else that matches
if (deviceTZ == null)
for (availableTZ in availableTZs)
if (availableTZ.contains(tzID, true) || tzID.contains(availableTZ, true)) {
if (availableTZ.contains(tzID) || tzID.contains(availableTZ)) {
deviceTZ = availableTZ
Constants.log.warning("Couldn't find system time zone \"$tzID\", assuming $deviceTZ")
break
}
// if that doesn't work, use UTC as fallback
// if that doesn't work, use device default as fallback
if (deviceTZ == null) {
val defaultTZ = TimeZone.getDefault().id!!
Constants.log.warning("Couldn't find system time zone \"$tzID\", using system default ($defaultTZ) as fallback")
deviceTZ = defaultTZ
}
return deviceTZ
}
/**
* @param timezoneDef VTIMEZONE definition
* @return parsed VTimeZone
* @throws IllegalArgumentException when the timezone definition can't be parsed
*/
@JvmStatic
fun parseVTimeZone(timezoneDef: String): VTimeZone {
val builder = CalendarBuilder(tzRegistry)
try {
val cal = builder.build(StringReader(timezoneDef))
return cal.getComponent(VTimeZone.VTIMEZONE) as VTimeZone
} catch (e: Exception) {
throw IllegalArgumentException("Couldn't parse timezone definition")
}
}
// recurrence sets
......
......@@ -26,8 +26,10 @@ object MiscUtils {
val tz = date!!.timeZone ?: return
val tzID = tz.id ?: return
val deviceTzID = DateUtils.findAndroidTimezoneID(tzID)
if (tzID != deviceTzID)
if (tzID != deviceTzID) {
Constants.log.warning("Android doesn't know time zone \"$tzID\", storing event in time zone \"$deviceTzID\"")
date.timeZone = DateUtils.tzRegistry.getTimeZone(deviceTzID)
}
}
}
......
......@@ -17,6 +17,9 @@ public class TestDateUtils {
@Test
public void testTimeZoneRegistry() {
assertNotNull(DateUtils.tzRegistry.getTimeZone("Europe/Vienna"));
// https://github.com/ical4j/ical4j/issues/207
// assertNotNull(DateUtils.tzRegistry.getTimeZone("EST"));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment