Joda Time вычитает 24 часа из экземпляра MutableDateTime, я хотел бы знать, почему - PullRequest
5 голосов
/ 28 октября 2010

Я не понимаю, почему MutableDateTime.setDate() устанавливает время на "вчера" (см. В журнале метки времени - это 20:28).Этот часовой пояс связан?Нужно ли что-то устанавливать в форматере?

Я ожидаю, что после вызова setDate с "27.10.2010" дата будет такой же, как и проанализированная дата 00:00 EDT 10/27 /10 вместо 20:28 EDT 26.10.10.Это 24 часа назад от «сейчас».

Что мне здесь не хватает, или как мне отредактировать код, чтобы получить желаемый результат?Я новичок в Joda Time и хотел бы разгадать эту загадку.

DateTimeFormatter dateFormatterJ = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTimeFormatter timestampFormatJ = DateTimeFormat.forPattern("HH:mm zzz MM/dd/yy");

MutableDateTime startDate = new MutableDateTime();

log.info("parsed date " + 
    timestampFormatJ.print(dateFormatterJ.parseMutableDateTime(startDateString)));

startDate.setDate((dateFormatterJ.parseMutableDateTime(startDateString)));

log.info("startDate: " + timestampFormatJ.print(startDate));

В этом случае startDateString - это просто "27.10.2010".

здесьвывод журнала:

10-27 20:28:55 INFO parsed date: 00:00 EDT 10/27/10
10-27 20:28:55 INFO startDate: 20:28 EDT 10/26/10

Спасибо

Ответы [ 2 ]

4 голосов
/ 28 октября 2010

Простой ответ будет, потому что Javadoc говорит так.

public void setDate (ReadableInstant instant)

Установите дату из другого момента. Временная часть этого объекта не будет затронута.

Параметры: Instant - момент, с которого копируется дата, часть времени игнорируется

Броски: IllegalArgumentException - если объектявляется недействительнымобъект является недействительным

Когда Джода говорит «Дата», это означает человеческое значение слова Дата.«Часть этого значения год-месяц-день», а не логический эквивалент java.util.Date.(весь смысл joda в том, чтобы ввести некоторую естественную, разумную семантику в обработку даты и времени.)

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос «как исправить», просто выполните:

MutableDateTime startDate = new MutableDateTime(dateFormatterJ.parseMutableDateTime(startDateString));

Или, конечно, вручную обнулить временные доли, конечно.

РЕДАКТИРОВАТЬ 2: Хм, я, видимо, не читал достаточно внимательно, это только половина ответа.Будет проверять.

РЕДАКТИРОВАТЬ 3: ну, это меня так напугало, что я потратил минуту на его поиск.

public void setDate(final ReadableInstant instant) {
    long instantMillis = DateTimeUtils.getInstantMillis(instant);
    Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
    DateTimeZone zone = instantChrono.getZone();
    if (zone != null) {
        instantMillis = zone.getMillisKeepLocal(**DateTimeZone.UTC**, instantMillis);
    }
    setDate(instantMillis);
}

По какой-то причине, это сворачивает ваше абсолютное время в UTC доустановка даты.Таким образом, вы даете ему 27.10.2010 00:00 ПО ВОСТОЧНОМУ ВРЕМЕНИ, и оно устанавливает абсолютную величину времени на количество миллисекунд, представляющих 27.10.2010 00:00 UTC, что, конечно, только в 6 или 7 часов вечера до,Затем он находит значение даты EDT, равное 10/26.

Не могу сказать, было ли это каким-то намерением, или это ошибка, которая была там в течение 2 лет или что-то еще.)

2 голосов
/ 29 октября 2010

При разборе строки, которая не содержит смещения по Гринвичу или идентификатора часового пояса, вы должны сделать одно из трех:

  • ничего не делать и принять, что строка проанализирована по умолчаниючасовой пояс
  • укажите часовой пояс для разбора, используя withZone() в форматере
  • используйте parseLocalDate() вместо parseMutableDateTime()

Последний являетсяпредпочтительное решение, так как оно правильно анализирует фактически введенные данные, которые представляли собой дату без времени, смещения или зоны.

Использование parseLocalDate() в тестовом коде правильно анализирует дату.

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