8

我有一个包含 UTC (GMT+0) 时间戳的数据库。这是问题所在:它们指的是发生在印第安纳州的计费活动。

有些人可能知道,印第安纳...

  • 在 2006 年之前根本没有遵守夏令时(该州的大部分地区全年都是美国东部标准时间)。
  • 2006 年投票决定保留美国东部标准时间,但开始与美国其他地区一起遵守夏令时
  • 2007年修改了规则;美国联邦政府修改了夏令时,因此开始和结束规则发生了变化

由于此数据库中的时间戳指的是政府计费活动,因此实际上有必要将 UTC 时间戳报告为历史上准确的本地时间,以保持审计准确性。因此,印第安纳州特有三种情况:2006 年之前的时间戳使用与 2006-2007 之间完全不同的时区规则集,而 2007 年之后的时间戳使用另一组完全不同的时区规则。您可以想象,该数据库包含印第安纳州以外地区的活动,因此事情变得更加复杂。

Java 日历和时区 API 不包含任何允许程序员创建具有一组以上时区规则的对象的类,因此如果特定的适用时区,它们不能用于将 UTC 时间戳正确映射到历史准确的本地时间规则永远改变。

我已经考虑过如何解决在时区规则不断变化的语言环境中映射到历史准确当地时间的问题......

  • 可以更新数据库,以便可以将 UTC 时间戳与本地时间偏移量和夏令时偏移量一起存储。这里的问题是数据库的大小增加了一点,如果现有数据库很大,那么更新所有表可能需要延长离线维护周期。

  • 可以更新数据库,以便与每个时间戳一起存储适合该特定时间戳的特定 TimeZone 对象。尽管我认为 TimeZone 对象非常轻量级,但我认为这比上述更灵活,但仍然不太理想,因为它需要为每个时间戳保留一个对象。

  • 可以开发自定义 API,从感兴趣区域设置的历史准确规则数据库中构建适当的 TimeZone 对象。该解决方案以需要额外处理的方式取代了前两种解决方案增加的存储需求。需要显示的每个时间戳都意味着创建一个新对象……或者至少与对象池中的适当对象配对。另外,这意味着创建和管理时区数据库。

Java 时间和日历 API 的局限性使得为这个问题找到一个优雅的解决方案比它应该做的要困难得多(例如,你不能查询现有的 SimpleTimeZone 对象并询问它遵循什么夏令时规则而不编写一些真的很乱的代码)。

我只是想问问有没有其他人以前处理过这样的情况以及他们是如何处理的。

4

1 回答 1

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.

于 2013-02-11T00:00:55.310 回答