Как сопоставить исторически точное местное время в Java при изменении правил часового пояса?

У меня есть база данных, содержащая временные метки UTC (GMT+0). Вот в чем проблема: они ссылаются на выставление счетов в штате Индиана.

Как некоторые могут знать, Индиана...

  • до 2006 года вообще не соблюдали летнее время (большая часть штата была EST в течение всего года).
  • в 2006 году проголосовали за то, чтобы остаться EST, но начать соблюдать летнее время с остальной частью США.
  • пересмотрел свои правила в 2007 году; Федеральное правительство США пересмотрело летнее время, чтобы изменить правила начала и окончания

Поскольку временные метки в этой базе данных относятся к действиям правительства по выставлению счетов, на самом деле необходимо, чтобы временные метки UTC сообщались как местное время, которое является исторически точным, чтобы сохранить точность аудита. Таким образом, есть три сценария, которые применимы исключительно к Индиане: метки времени до 2006 года используют совершенно другой набор правил часового пояса, чем между 2006-2007 годами, а после 2007 года используется совершенно другой набор правил часового пояса. Вы можете себе представить, что эта база данных включает в себя действия для локалей, отличных от Индианы, и поэтому все становится еще сложнее.

Календарь Java и API TimeZone не содержат классов, которые позволяют программисту создавать объекты с более чем одним набором правил часового пояса, и поэтому их нельзя использовать для правильного сопоставления временных меток UTC с исторически точным местным временем, если конкретный применимый часовой пояс правила когда-нибудь меняются.

Я думал о способах решения проблемы сопоставления с исторически точным местным временем в регионах с изменением правил часового пояса...

  • База данных может быть обновлена, чтобы метки времени UTC могли храниться вместе со смещением местного времени и смещением летнего времени. Проблема здесь в том, что размер базы данных немного увеличивается, и если существующая база данных велика, то для обновления всех таблиц может потребоваться длительный автономный цикл обслуживания.

  • База данных может быть обновлена ​​таким образом, чтобы конкретный объект TimeZone, соответствующий этой конкретной временной метке, сохранялся с каждой временной меткой. Хотя я думаю, что объекты TimeZone довольно легкие, я вижу, что это более гибко, чем выше, но все же менее желательно, поскольку требует сохранения объекта для каждой временной метки.

  • Можно разработать собственный API, который создает соответствующий объект TimeZone из базы данных исторически точных правил для интересующих локалей. Это решение заменяет повышенные требования к хранилищу двух предыдущих решений необходимостью дополнительной обработки. Каждая отметка времени, которую необходимо отображать, будет означать создание нового объекта... или, по крайней мере, сопряжение с соответствующим объектом из пула объектов. Кроме того, это означает создание и администрирование базы данных часовых поясов.

Ограничения API времени и календаря Java сделали поиск элегантного решения этой проблемы действительно более сложным, чем должно быть (вы не можете, например, запросить существующий объект SimpleTimeZone и спросить его, каким правилам перехода на летнее время он следует без написания некоторых действительно грязный код).

Я просто хотел бы спросить, сталкивался ли кто-нибудь с такой ситуацией раньше и как они с этим справились.


person scottb    schedule 10.02.2013    source источник
comment
Я не знаю Java, но уверен, что он использует базу данных часовых поясов Олсона ( о чем свидетельствует содержимое пакета Debian tzdata-java). Если да, то вам не о чем беспокоиться. База данных Olson обрабатывает все исторические правила и должна предоставить вам правильное местное время.   -  person Celada    schedule 11.02.2013
comment
Очень грустно, что нам приходится упорно трудиться, чтобы вычищать дерьмо политиков.   -  person irreputable    schedule 11.02.2013


Ответы (1)


База данных часовых поясов, которую вы описываете, уже существует. Она называется базой данных Олсона zoneinfo, верна для всех дат после 1970 года и доступна в Интернете.

Более того, собственные API даты и времени Java используют эту базу данных. Вы можете загрузить произвольный часовой пояс, используя java.util.TimeZone.getTimeZone(), и получить смещения или выполнить преобразования, используя этот объект (например, используя TimeZone.getOffset(long). Например, вы загрузите зону "America/Indiana/Indianapolis" для преобразования даты и времени в Индиане.

Единственное, что вы не можете легко сделать с базой данных TimeZone, — это на самом деле запросить правила, которые она использует. Для этого, я считаю, вам придется копаться в файлах tz напрямую. Однако в большинстве случаев достаточно просто получить смещения для указанных дат.

person Community    schedule 11.02.2013
comment
и в Индиане есть несколько зон: stackoverflow.com/questions /4065641/ - person irreputable; 11.02.2013
comment
Правильно; зона Индианаполиса - один из восьми вариантов. - person ; 11.02.2013
comment
Можете ли вы показать пример, как выполнить преобразование или получить смещение часового пояса для определенного момента в истории, то есть для определенного времени? - person Suma; 18.03.2016