Расчет продолжительности времени с помощью Joda-Time

Я пытаюсь использовать Joda-Time, чтобы узнать продолжительность времени между двумя моментами времени, где каждая точка указана в своем локальном часовом поясе.

E.g. :

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime utc1 = ny.withZone(DateTimeZone.UTC);
DateTime utc2 = la.withZone(DateTimeZone.UTC);        
Period period = new Period(utc1, utc2);

Теперь я хочу знать, учитывает ли это летнее время и високосные годы ... Кроме того, является ли использование «Периода» правильным способом Joda-Time для достижения этого? Спасибо ;)


person bloodcell    schedule 13.02.2011    source источник


Ответы (2)


Предоставленный вами код будет работать и учитывать часовые пояса, но вам не нужно выполнять преобразование в UTC. Этот код проще и делает то же самое (используя Duration вместо Period):

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
Duration duration = new Interval(ny, la).toDuration();
person Russ Hayward    schedule 13.02.2011

В зависимости от того, как вы его используете, приведенный выше код может оказаться не очень хорошей идеей.

Все конструкторы DateTime, которые принимают int для года/месяца/дня/часа и т. д., уязвимы для переходных периодов перехода на летнее время (DST), и в этом случае Joda-time выдает исключение. Поэтому, если час во время перехода является возможным входом в ваше приложение, оно не будет выполнено:

DateTime ny = new DateTime(2011, 3, 13, 2, 0, 0, 0, DateTimeZone.forID("America/New_York"));

Exception in thread "main" java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 2011-03-13T07:00:00.000
at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:143)
at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:119)
at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:254)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:223)
at org.joda.time.DateTime.<init>(DateTime.java:264)

Точно так же вы столкнетесь с другой проблемой осенью, когда невозможно определить, о каком часе идет речь *, так как в заданном часовом поясе будет 2 * 2 часа. Методы DateTime withHourOfday и withTime подвержены той же проблеме, а также анализу даты и времени как строк с часовыми поясами, на которые влияет переход на летнее время.

Возможные обходные пути включают

  • создание экземпляра с любым часовым поясом с фиксированным смещением (например, UTC)
  • разбор такой же, как строка с часовым поясом UTC
  • создание экземпляра действительного времени в местном часовом поясе (например, полночь) и использование plusHours для продвижения вперед до желаемого времени
  • иметь охрану (if-оператор) для защиты от второго часа даты перехода
  • поймать исключение и проверить, когда произойдет следующий переход (используя DateTimeZone.nextTransition), и соответственно переместиться назад/вперед
person fcarlsen    schedule 01.04.2011