使用SimpleDateFormat转换日期感到困惑

时间:2017-05-20 16:12:42

标签: java hashmap

我遇到日期转换问题。我使用以下程序,我期望输出:19.05.2017

但输出是:05.00.2017

有人可以帮忙吗?

String t = "Fri May 19 00:00:00 CEST 2017";
Date d = new SimpleDateFormat("EEE MMM DD hh:mm:ss zzzz YYYY", Locale.US).parse(t);
String s = new SimpleDateFormat("dd.mm.yyyy").format(d).toString();
System.out.println(s);

2 个答案:

答案 0 :(得分:1)

令人惊讶的结果。古老的班级SimpleDateFormat和朋友们充满了惊喜。这是一个消极的事情。

大写DD是一年中的某一天。小写hh是上午或下午(1到12)的小时。大写YYYY是基于周的年份(仅对周数有用)。所以你要求的日期是五月的一个星期五和一年的第十九天。显然这是不可能的。

解析的结果是Thu Jan 05 23:00:00 CET 2017。显然SimpleDateFormat选择给你一个星期五,并使用CEST暗示的2小时的区域偏移量,即使它所选择的日期不是在CEST(夏令时)所在的年份的时间使用。我不知道它是否只是给你基于一周的第一个星期五(第一周的第五周)。星期五0000时偏移GMT + 2等于周四23,GMT + 1,即CET。

接下来是格式化,05是预期的日期,但小写mm表示分钟。由于分钟数为0,因此您获得00。你得到了正确的一年。

我同意Sam’s answer您应该使用java.time中较新的类,而不是使用过时的类给您带来这样的惊喜:

    ZonedDateTime dt = ZonedDateTime.parse(t,
            DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US));
    String s = dt.format(DateTimeFormatter.ofPattern("dd.MM.uuuu"));

此代码为您提供了您所期望的19.05.2017。现代课程的一个好处是,如果你尝试用原始格式模式字符串进行解析,你将得到一个DateTimeParseException,这样你就会知道出错了。我当然更喜欢异常而不是错误的输出。

另一个好处是这些类尊重输入中的时区并在输出中使用它(除非您明确指示它们)。由于一些有趣的时区问题,他们永远不会在1月6日周五到1月5日星期四。

答案 1 :(得分:0)

您的输入日期是中欧夏令时,您的日期格式有点不对。试试

SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzzz yyyy");

您可能希望在输出日期格式上设置时区,以便以正确的当地时间获取日期。

理想情况下,您可以转到使用java.time样式,如下所示:

https://www.mkyong.com/java/java-convert-date-and-time-between-timezone/