Я пытаюсь разобрать строки datetime и создать объекты Joda DateTime.Обработка сдвига смещения часового пояса и переход на летнее время с помощью Joda
Мои данные получены из устаревшей базы данных, в которой хранятся строки времени и времени, не указав часовой пояс/смещение. Хотя временная шкала/смещение строк даты и времени не сохраняется, это бизнес-правило унаследованной системы, в которой все данные хранятся в Восточном времени. К сожалению, у меня нет полномочий обновлять то, как устаревший DB хранит строки времени.
Таким образом, я разбираю строки datetime, используя часовой пояс JODA «США/Восток».
Этот подход вызывает исключение незаконногоInstance, когда строка dateTime попадает в течение часа, который «исчезает», когда включена летняя экономия.
Я создал следующий примерный код, чтобы продемонстрировать это поведение и показать предлагаемое обходное решение.
public class FooBar {
public static final DateTimeZone EST = DateTimeZone.forID("EST");
public static final DateTimeZone EASTERN = DateTimeZone.forID("US/Eastern");
public static final DateTimeFormatter EST_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(EST);
public static final DateTimeFormatter EASTERN_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(EASTERN);
public static void main(String[] args) {
final String[] listOfDateTimeStrings = {"2014-03-09 02:00:00.000", "2014-03-08 02:00:00.000"};
System.out.println(" *********** 1st attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
final DateTime dateTime = DateTime.parse(dateTimeString, EASTERN_FORMATTER);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
System.out.println(" *********** 2nd attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
final DateTime dateTime = DateTime.parse(dateTimeString, EST_FORMATTER);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
System.out.println(" *********** 3rd attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
DateTime dateTime = DateTime.parse(dateTimeString, EST_FORMATTER);
dateTime = dateTime.withZone(EASTERN);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
}
Выход производства:
*********** 1st attempt *********** Cannot parse "2014-03-09 02:00:00.000": Illegal instant due to time zone offset transition (America/New_York) 2014-03-08T02:00:00.000-05:00 *********** 2nd attempt *********** 2014-03-09T02:00:00.000-05:00 2014-03-08T02:00:00.000-05:00 *********** 3rd attempt *********** 2014-03-09T03:00:00.000-04:00 2014-03-08T02:00:00.000-05:00
В "3-й попытки" я получить ожидаемый результат: первый DateTime имеет смещение -04: 00. так как он попадает в первый час DST на 2015 год. Вторая временная метка имеет смещение -05: 00, поскольку оно выходит за пределы DST.
Is безопасно сделать это:
DateTime dateTime = DateTime.parse(dateTimeString, A_FORMATTER_WITH_TIME_ZONE_A);
dateTime = dateTime.withZone(TIME_ZONE_B);
Я тестировал этот код с несколькими различными комбинациями даты и времени строк и часовых поясов (и до сих пор он работает для всех тестов), но я задавался вопросом, может ли кто-нибудь, у кого больше опыта Джоды, увидеть что-то неправильное/опасное в этом подходе.
Или, альтернативно: есть ли лучший способ справиться с переходом с часовым поясом с Джодой?
+1 Замечательный письменный вопрос с одним незначительным исключением: _ «Является ли код ... безопасным в использовании?» _ Что вы подразумеваете под «безопасным»? Если вы проверите его с достаточными случаями краев, приведет ли оно к ожидаемому и желаемому поведению? Вам нужно будет более подробно описать то, что вы спрашиваете конкретно. –
@JimGarrison спасибо за указатели; Я обновил конец вопроса, надеюсь, теперь он более конкретный. –
Когда вы говорите: «все данные хранятся в EST», вы буквально означаете, что все они хранятся в UTC-5 - Eastern * Standard * Time, или вы имеете в виду, что они хранятся в Восточном времени, что является UTC-5 (EST) для части года и UTC-4 (EDT) для другой части? Потому что вы также сказали: «Когда переход на летнее время включен в часовой пояс EST», я думаю, вы имеете в виду «Восточное время», а не «EST». (Переход на летнее время * не применяется * в стандартное время.) –