JDK и joda-time dateformatter: как учесть переход на летнее время

@Jon Skeet, я загрузил Joda-Time, как вы рекомендовали, Разбор / форматирование даты с помощью TimeZone и SimpleDateFormat дает разные результаты при переключении на летнее время и добавил его в мой проект Java EE / JSF, попытался использовать DateTime и DateTimeFormatter, и они возвращают тот же результат, что и JDK 6 (см. Ниже), так как сейчас здесь, в часовом поясе EST (США / Восток), летнее время.

ЗАКАЗ № 0739 Дата поездки 11.11.2011 по 12.11.2011 клиент № 1004

Дата / время поездки: 11.11.2011 17:00 Дата / время отчета: 11.11.2011 16:45 Возвращение Дата / время: 13.11.2011 02: 00:00

Код выглядит следующим образом:

public String getDateFromDateTime (Date date, Boolean display) throws ParseException {

    /*
     * SimpleDateFormat working as designed, but pf_ordersController.selected.returnDateTime displaying incorrect date/time
     * 
     * see below from /orders/pf_View.xhtml
     * pf_ordersController.selected.returnDateTime (displayed on JSF page) = 11/13/2011 02:00 AM
     * 
     * ORDER #  0739  Trip Date 11/11/2011 to 11/12/2011  Customer # 1004
     * 
     * Trip Date/Time: 11/11/2011 05:00 PM  Report Date/Time: 11/11/2011 04:45 PM   Return Date/Time: 11/13/2011 02:00 AM
     * 
     * orders.returnDateTime (stored in database) = 11/12/2011 21:00:00 (9:00 PM)
     * SimpleDateFormat converts orders.returnDateTime to 11/12/2011 (working as designed)
     * 
     * https://stackoverflow.com/questions/2356672/date-parsing-formating-with-timezone-and-simpledateformat-problem-around-dst-swi
     * 
    DateFormat formatter;
    String myDate;

    if (display)
        formatter = new SimpleDateFormat("MM/dd/yyyy");
    else
        formatter = new SimpleDateFormat("yyyy-MM-dd");

    myDate = formatter.format(date);
     * 
     */

    DateTimeFormatter dtFormatter;

    if (display)
        dtFormatter = DateTimeFormat.forPattern("MM/dd/yyyy");
    else
        dtFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");

    DateTime dt = new DateTime(date);
    String myDate = dt.toString(dtFormatter);

    System.out.println("OrderDisplayUtil.java:getDateFromDateTime(" + date + ", " + display + "): " + "myDate = " + myDate);

    return myDate;

}

Пожалуйста помоги. Спасибо.


person Howard    schedule 13.11.2011    source источник
comment
Как сказал Ориен, нам нужно знать, как вы получили свой вклад. Я не против, будь то модульный тест или короткое, но законченное консольное приложение, но кое-что, что я могу запустить в любом случае :)   -  person Jon Skeet    schedule 13.11.2011
comment
@JonSkeet, спасибо за быстрый ответ. Я только что подтвердил, что SimpleDateFormat работает так, как задумано, потому что дата / время проблемы - это Orders.returnDateTime, который передается этому методу getDateFromDateTime (Orders.returnDateTime, ...). Orders.returnDateTime = 2011-11-12 21:00:00, но мой код JSF / контроллера по какой-то причине отображает 2011-11-13 02:00:00. Я буду продолжать смотреть на это. Кстати, спасибо, что дали мне знать, как мне задавать вопросы; Я уверен, вы уже можете сказать, что я здесь новичок. :)   -  person Howard    schedule 13.11.2011
comment
Дополнительные рекомендации по правильному вопросу см. На странице tinyurl.com/so-hints. Похоже, в вашем коде происходит много преобразований. Изолируйте их один за другим и определите точно, в чем проблема.   -  person Jon Skeet    schedule 13.11.2011
comment
@JonSkeet, ты прав, у меня много конверсий, и мне интересно, не слишком ли это для JSF. У меня есть tripDateTime, reportDateTime и returnDateTime. Я, наконец, решил использовать Joda-Time (DateTime) для возврата отформатированной строки даты, поскольку значение returnDateTime является правильным при передаче его в bean-компонентах, но JSF xhtml вообще НЕ отображал правильное значение. Компонент возвращает отформатированную строку даты в JSF xhtml, и это решает мою проблему. Еще раз спасибо за ваши ответы.   -  person Howard    schedule 14.11.2011


Ответы (1)


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

@Test
public void testGetDateFromDateTime() {
    DateTimeZone timezone = DateTimeZone.forID("US/Eastern");
    Date date = new DateTime(2011, 11, 11, 17, 0, 0, 0, timezone).toDate();

    String formattedDate = unitUnderTest.getDateFromDateTime(date, true);

    Assert.assertEquals(formattedDate, "11/11/2011");
}

Ваша проблема в том, что вы явно не указываете часовой пояс, в котором хотите отформатировать дату. В этом случае Java будет использовать часовой пояс, установленный в операционной системе, в которой запущена JVM. Так, например, если вы хотите отформатировать дату / время 2011/11/11 16:45 из США / Востока в системе, работающей в Сингапуре, используя часовой пояс +08: 00. Система интерпретирует дату / время как 06:00 2011/11/12, что представляет собой тот же самый момент времени. Затем система использует форматер и выдаст «12.11.2011».

Давайте решим эту проблему, указав часовой пояс, который вы хотите использовать:

public String getDateFromDateTime(Date date, Boolean display) {

    DateTimeFormatter dtFormatter;

    if (display)
        dtFormatter = DateTimeFormat.forPattern("MM/dd/yyyy");
    else
        dtFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");

    DateTimeZone timeZone = DateTimeZone.forID("US/Eastern");
    DateTime dt = new DateTime(date, timeZone);
    String myDate = dt.toString(dtFormatter);

    return myDate;
}

Также обратите внимание, что 6 ноября в США закончилось летнее время.

person orien    schedule 13.11.2011
comment
спасибо за ответ / ответ и модификацию кода / рекомендацию. Как я упоминал выше для JonSkeet, я узнал, что SimpleDateFormat работает так, как задумано; Мне нужно отладить логику JSF / контроллера и подтвердить, почему Orders.returnDateTime не является правильной датой / временем для этой записи / строки заказов. В любом другом месте этот Orders.returnDateTime отображается правильно, но не тогда, когда я показываю дату через OrdersController.selected.returnDateTime; xhtml работает так же, как и для других строк, но не для этой. Следует ли мне обновить вопрос здесь, поскольку я неправильно сформулировал ранее? еще раз спасибо. - person Howard; 13.11.2011
comment
о, я забыл упомянуть, прямо сейчас целевые конечные пользователи, скорее всего, будут использовать это веб-приложение за сетевым брандмауэром для моей семьи. Значения даты и времени всегда будут основаны на персонале, использующем веб-приложение в офисе, поэтому localDateTime на данный момент соответствует требованиям. Честно говоря, я не могу придумать варианта использования, в котором это бизнес-требование должно было бы учитывать TimeZone. Еще раз спасибо. - person Howard; 13.11.2011