Расчет продолжительности времени с Joda-Time - PullRequest
4 голосов
/ 13 февраля 2011

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

например. :

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 для достижения этой цели? Спасибо;)

Ответы [ 2 ]

10 голосов
/ 13 февраля 2011

Код, который вы предоставили, будет работать и учитывать часовые пояса, но вам не нужно выполнять преобразование в 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();
4 голосов
/ 01 апреля 2011

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

Все конструкторы DateTime, которые принимают целые числа для года / месяца / дня / часа и т. Д., Уязвимы к переходным периодам перехода на летнее время (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 уязвимы для той же проблемы, а также для синтаксического анализа дат и времени как строк с часовыми поясами, на которые влияет DST.

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

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