How to map to historically accurate local times in Java when time zone rules change?
Asked Answered
B

1

8

I have a database that contains UTC (GMT+0) timestamps. Here is the problem: they refer to billing activity that occurred in the state of Indiana.

As some may know, Indiana ...

  • did not observe Daylight Savings Time at all prior to 2006 (most of the state was EST all year long).
  • voted in 2006 to remain EST, but to begin observing Daylight Savings time with the rest of the U.S.
  • revised it's rules in 2007; the U.S. Federal Government revised Daylight Savings Time so that the start and end rules changed

Because the timestamps in this database refer to government billing activity, it is actually necessary to have the UTC timestamps reported as local times that are historically accurate in order to preserve auditing accuracy. There are therefore three scenarios that apply uniquely to Indiana: timestamps before 2006 use a completely different set of timezone rules than those between 2006-2007, and those after 2007 use yet another completely different set of timezone rules. You can imagine that this database includes activity for locales other than Indiana, and so things get even more complicated.

The Java Calendar and TimeZone API does not contain any classes that allow the programmer to create objects with more than one set of timezone rules and so they cannot be used for the correct mapping of UTC timestamps to historically accurate local times if the particular, applicable timezone rules ever change.

I've thought about ways to address the problem of mapping to historically accurate local times in locales with changing timezone rules...

  • The database could be updated so that UTC timestamps could be stored along with the local time offset and a daylight savings offset. The problem here is that the size of the database increases a bit and if the existing database is large, then updating all the tables may require an extended offline maintenance cycle.

  • The database could be updated so that the particular TimeZone object appropriate to that particular timestamp is stored with each timestamp. Although I think that TimeZone objects are pretty lightweight, I see this is more flexible than the above but still less desirable as it requires persisting an object for every timestamp.

  • A custom API can be developed that builds an appropriate TimeZone object from a database of historically accurate rules for the locales of interest. This solution replaces the increased storage requirement of the previous two solutions with the need for additional processing. Every timestamp that needed to be displayed would mean creating a new object ... or at least pairing with an appropriate object from an object pool. Plus, it means creating and administering a timezone database.

The limitations of the Java Time and Calendar API have made finding an elegant solution to this problem really harder than it should be (you can't, for example, query an existing SimpleTimeZone object and ask it what Daylight Savings Rules it follows without writing some really messy code).

I'd just like to ask if anyone else has dealt with a situation like this before and how they've handled it.

Bearberry answered 10/2, 2013 at 23:51 Comment(2)
I don't know Java, but I'm pretty sure it uses the Olson timezone database (as evidenced by the contents of the tzdata-java Debian package). If so, you don't have anything to worry about. The Olson database handles all of the historical rules and should give you the correct local time.Philanthropic
It is so sad that we have to work hard to clean up politicians' craps.Mcphail
H
2

The time zone database you are describing already exists. It's called the Olson zoneinfo database, it's correct for all dates after 1970, and it's available online.

Better yet, Java's native date-and-time APIs use this database. You can load an arbitrary time zone using java.util.TimeZone.getTimeZone(), and get offsets or perform conversions using this object (e.g, using TimeZone.getOffset(long). For instance, you'd load the "America/Indiana/Indianapolis" zone to convert dates and times in Indiana.

The one thing you can't do easily with the TimeZone database is actually query the rules it's using. For that, I believe you'd have to dig into the tz files directly. In most cases, though, just getting offsets for specified dates should be sufficient.

Hyper answered 11/2, 2013 at 0:0 Comment(3)
and there are multiple zones inside Indiana: #4066141Mcphail
Right; the Indianapolis zone is one of eight options.Hyper
Can you show some example how to perform conversion or get a timezone offset for some particular moment in history - i.e. for some given time?Sodality

© 2022 - 2024 — McMap. All rights reserved.