JDK和joda-time dateformatter:如何考虑日光节省时间

时间:2011-11-13 03:46:48

标签: java jodatime date-format simpledateformat

@Jon Skeet,我按照你推荐的Date parsing/formatting with TimeZone and SimpleDateFormat give different results around DST switch下载了Joda-Time,并将它添加到我的Java EE / JSF项目中,尝试使用DateTime和DateTimeFormatter,它们返回的结果与JDK相同6(见下文),因为它现在是EST时区(美国/东部)的Day Light Saving。

订单#0739旅行日期11/11/2011至 11/12/2011 客户#1004

旅行日期/时间:11/11/2011 05:00 PM 报告日期/时间:11/11/2011 04:45 PM 返回日期/时间: 11/13/2011 02:00 AM

代码如下:

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;

}

请帮忙。感谢。

1 个答案:

答案 0 :(得分: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的操作系统上设置时区。例如,如果您想使用+08:00时区在新加坡运行的系统上格式化美国/东部的日期/时间2011/11/11 16:45。系统会将日期/时间解释为2011/11/12 06:00,它代表完全相同的时刻。然后系统将使用格式化程序并给出'11 / 12/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;
}

另请注意,美国夏令时于11月6日结束。