What I am trying to do is a basic alarm app on Android. When I set date and time via UI (say 2012-09-26 at 14:37) I want the alarm go off at that time regardless of the timezone. That setting is serialized as two separate values – date value and offset from the beginning of the day in milliseconds.
I also made a mistake of using Joda library for date/time manipulation. The API confused me by looking very similar to .NETs DateTime API, but still suffering from the same duality issue as default Java framework APIs, where the object value is in UTC, but its properties are in local time (this concept blows my mind btw). It also seems to have trouble picking up Android’s time zone change automatically.
This is a summary of what I have:
// part of reminder class
public DateTime getNextAlarm()
{
DateTime now = DateTime.now();
DateTime next = date.withMillisOfDay(time);
while (next.compareTo(now) <= 0)
next = next.plusDays(repeat);
return next;
}
// inside worker thread
workerEnabled = true;
while (workerEnabled)
{
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
workerEnabled = false;
return;
}
DateTimeZone tz = DateTimeZone.forTimeZone(TimeZone.getDefault());
if (nextAlarm != null && nextAlarm.withZoneRetainFields(tz).compareTo(new DateTime(tz)) < 0)
{
nextAlarm = reminder.getNextAlarm();
// perform alarm action
}
}
Everything is fine and dandy until I try to switch timezones while app is running (after the setting was made). This is where the weird stuff begins. I can’t even describe what exactly is wrong other than that not matter what I do it doesn’t work right.
I guess what I am looking for is a general direction on how to do timezone-independent math in Java/Android either in Joda or standard APIs.
As it turns out Jodatime does not handle timezone changes on Android. Restarting application helps, but that solution doesn’t work for a background service running all the time. I ended up rewriting code using Calendar/Date API even though it is ugly and painful.