【问题标题】:Old Date Formatting incompatible with Java 8 ZonedDateTime API旧日期格式与 Java 8 ZonedDateTime API 不兼容
【发布时间】:2017-10-20 14:30:37
【问题描述】:

我正在将旧的日期格式代码更新到 Java 8 并尝试 ZonedDateTime API

日期格式与 Javascript Date 对象格式相同,例如: -

2017 年 5 月 25 日星期四 10:00:00 GMT+1200(新西兰标准时间)

我之前使用的是以下格式 -

EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'

此格式无法使用 DateTimeFormatter.ofPattern 方法解析日期字符串。

代码如下:

public static final String DATE_FORMAT = "EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'";

public static void main(String[] args) throws ParseException {
    String sDate = "Thu May 25 2017 10:00:00 GMT+1200 (New Zealand Standard Time)";
    parseDate(sDate);
}

private static void parseDate(String sDate) throws ParseException {

    // works
    DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
    Date oldDate = dateFormat.parse(sDate);

    //FIXME: can't parse?!
    ZonedDateTime newDate = ZonedDateTime.parse(
           sDate, DateTimeFormatter.ofPattern(DATE_FORMAT)); // <- this is the line 25!
}

这是我可以编译和运行的完整代码供参考 - https://gist.github.com/bhabanism/470e03db54981ad6ddedbba316dcaa9a

这在第 25 行失败:

线程“主”java.time.format.DateTimeParseException 中的异常: 文本“2017 年 5 月 25 日星期四 10:00:00 GMT+1200(新西兰标准时间)” 无法解析:无法从中获取 ZonedDateTime 时间访问器:{HourOfAmPm=10, MilliOfSecond=0, MinuteOfHour=0, OffsetSeconds=43200, MicroOfSecond=0, NanoOfSecond=0, SecondOfMinute=0},ISO,Pacific/Auckland 解析为 2017-05-25 类型 java.time.format.Parsed

注意,我不能改变日期的输入格式,它必须是

2017 年 5 月 25 日星期四 10:00:00 GMT+1200(新西兰标准时间)

我当然可以修改格式化程序

EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'

【问题讨论】:

    标签: java date datetime java-8


    【解决方案1】:

    您的格式字符串中似乎一直存在错误。小写hh 是上午或下午的小时,范围从 1 到 12。由于您的字符串中没有 AM/PM,我怀疑这从来都不是您想要的,我想知道错误是如何被忽视的。

    大写 HH 表示一天中的小时,从 0 到 23:

    public static final String DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z '('zzzz')'";
    

    有了这个改变,新旧的解析方式都可以在我的电脑上运行。

    Locale.ENGLISH 添加到两个格式化程序时,就是这样。您可能也想这样做。

    我得到的结果是

    Thu May 25 00:00:00 CEST 2017
    2017-05-25T10:00+12:00[Pacific/Auckland]
    

    由于 CEST 比 UTC 早 2 小时,因此这是同一时间点,只是呈现方式不同。

    【讨论】:

    • 谢谢,这行得通!貌似这个bug存在很久了,不知道有多少单元测试一直通过!
    • 所以你一定会写一个失败的。乐于助人。
    • 刚想起来,为hh 写一个失败的测试并不是那么简单。解析,比如说,17 小时或 0 小时可能会给出预期的结果,而宽松的SimpleDateFormat。你可以setLenient(false) 它应该会失败。您可以尝试在 0 到 12 点之外的一个小时格式化,它会将其折叠到该时间间隔内。
    • 是的,会试试的
    • 对于以小写hh 失败的测试,请解析小时为12 的字符串。 SimpleDateFormat 将假定为上午 12 点并解析为 00。
    猜你喜欢
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    相关资源
    最近更新 更多