【问题标题】:JDK and joda-time dateformatter: how to consider day light savings timeJDK 和 joda-time 日期格式:如何考虑夏令时
【发布时间】:2011-12-27 21:50:03
【问题描述】:

@Jon Skeet,我按照您在Date parsing/formatting with TimeZone and SimpleDateFormat give different results around DST switch 中的建议下载了 Joda-Time,并将其添加到我的 Java EE / JSF 项目中,尝试使用 DateTime 和 DateTimeFormatter,它们返回的结果与 JDK 6 (见下文),因为现在是美国东部标准时间时区(美国/东部)的夏令时。

订单号 0739 行程日期 2011 年 11 月 11 日至 2011 年 11 月 12 日 客户号 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;

}

请帮忙。谢谢。

【问题讨论】:

  • 正如 orien 所说,我们需要知道您是如何获得输入的。我不介意它是以单元测试的形式还是一个简短但完整的控制台应用程序的形式,但我可以以任何一种方式运行:)
  • @JonSkeet,感谢您的快速回复。我刚刚确认 SimpleDateFormat 正在按设计工作,因为问题日期/时间是 Orders.returnDateTime,它传递给此方法 getDateFromDateTime(Orders.returnDateTime, ...)。 Orders.returnDateTime = 2011-11-12 21:00:00,但由于某种原因,我的 JSF/控制器代码显示为 2011-11-13 02:00:00。我会继续看这个。顺便说一句,谢谢你让我知道我应该如何提问;我敢肯定,您已经可以说我是这里的新手。 :)
  • 有关提出好问题的更多建议,请参阅tinyurl.com/so-hints。听起来您的代码中有 很多 次转换。将它们一一隔离,然后准确地找出问题所在。
  • @JonSkeet,你说得对,我确实有很多转换,我想知道这对 JSF 来说是否太多了。我有一个tripDateTime、reportDateTime 和returnDateTime。我最终决定使用 Joda-Time (DateTime) 返回格式化的日期字符串,因为在 bean 中传递它时 returnDateTime 值是正确的,但是 JSF xhtml 根本没有显示正确的值。 bean 将格式化的日期字符串返回给 JSF xhtml,这解决了我的问题。再次感谢您的回复。

标签: java jodatime date-format simpledateformat


【解决方案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 日结束。

【讨论】:

  • 感谢您的回答/响应和代码修改/推荐。正如我在上面对 JonSkeet 提到的,我了解到 SimpleDateFormat 正在按设计工作。我需要调试我的 JSF/控制器逻辑并确认为什么 Orders.returnDateTime 不是此订单记录/行的正确日期/时间。在其他任何地方,这个 Orders.returnDateTime 都正确显示,但当我通过 OrdersController.selected.returnDateTime 显示日期时却没有; xhtml 的工作方式与其他行的设计相同,但不适用于这一行。我应该在这里更新问题,因为我之前说错了吗?再次感谢。
  • 哦,我忘了说,现在,目标最终用户很可能会为我的家人在网络防火墙后面使用这个 Web 应用程序。日期/时间值将始终基于在办公室使用 Web 应用程序的人员,因此 localDateTime 目前满足要求。老实说,我想不出这个业务需求需要考虑 TimeZone 的用例。再次感谢。
猜你喜欢
  • 2011-04-29
  • 2018-02-04
  • 2014-05-19
  • 2012-09-08
  • 1970-01-01
  • 2011-08-14
  • 2013-09-22
  • 1970-01-01
  • 2016-02-13
相关资源
最近更新 更多