SimpleDateFormat将字符串解析为错误的时间 [英] SimpleDateFormat parses a string to wrong time

查看:108
本文介绍了SimpleDateFormat将字符串解析为错误的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行以下代码:

SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");

    try{
        Date date = sdf.parse("03-28-2003 01:00:00");
        System.out.print(date.toString());
    }
    catch(Exception e){
        //do something
    }

分析的结果是这个日期:2003-03-28T02:00:00.000 + 0300

The result of the parsing is this date: 2003-03-28T02:00:00.000+0300

添加了一个小时.

当我将年/日/小时更改为任何其他有效数字时,我得到了正确的时间,没有添加额外的小时.如果我只更改分钟或秒,我仍然会增加小时数.

When I change the year/day/hour to any other valid number, I get the correct time, no extra hour is added. If I only change the minutes or the seconds I still get the added hour.

有人可以告诉我为什么会这样吗?

Can anyone tell me why this happens?

这与我的程序在UTC + 02:00所在的时区中应用夏令时有关.在此时区中,时钟在2003-03-28更改.这就是为什么要增加一个小时的原因,正如下面的评论和答案所建议的那样.

This is related to when daylight saving time is applied in the timezone my program runs on- UTC+02:00. In this timezone the clock changed on 2003-03-28. that's why an hour was added, as it was suggested by the comments and answer below.

我使用答案中建议的代码来解析我的日期,并且解析成功了!日期已正确解析,未添加额外的小时.

I used the code suggested in the answer to parse my date and the parsing worked! The date is parsed correctly, the extra hour isn't added.

推荐答案

由于不仅 SimpleDateFormat.parse()可能还取决于默认时间,因此要弄清楚代码的确切作用是很复杂的计算机的时区(在这种情况下,模式不包括时区), Date.toString()也取决于默认时区.但是,我了解到您想用UTC解释日期字符串,因此我将专注于正确地进行解析,而不必担心打印的内容.

Finding out exactly what your code does is complicated by the fact that not only SimpleDateFormat.parse() may depend on the default time zone of the computer (and does in this case where the pattern does not include time zone), also Date.toString() depends on the default time zone. However, I understand that you want to interpret the date string in UTC, so I will concentrate on getting the parsing right and not worry so much about what’s printed.

Feek在注释中是正确的,将 SimpleDateFormat 的时区设置为UTC即可获得所需的内容,例如:

Feek is correct in the comment that setting the time zone of the SimpleDateFormat to UTC will get you what you want, for example:

    sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

try 之前添加以下行:我在计算机上得到以下输出:

With this line added before try I get this output on my computer:

Fri Mar 28 02:00:00 CET 2003

凌晨2点.CET同意1个UTC,因此现在解析正确.

2 am. CET agrees with 1 UTC, so now the parsing is correct.

允许我补充一下,如果您可以使用Java 8日期和时间类,那么我发现相应的代码更加清晰:

Allow me to add that if you can use the Java 8 date and time classes, I find the corresponding code somewhat clearer:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");
    LocalDateTime dateTime = LocalDateTime.parse("03-28-2003 01:00:00", formatter);
    OffsetDateTime utcDateTime = dateTime.atOffset(ZoneOffset.UTC);
    System.out.println(utcDateTime);

重点并不是说它更短,而是您不容易对它的功能有所怀疑,也不容易引起时区或DST问题.另一个好处是输出也如预期的那样:

The point is not that it’s shorter, but that you don’t get easily in doubt about what it does and don’t easily get time zone or DST problems. An added benefit is that the output is also as expected:

2003-03-28T01:00Z

现在看来,时间是正确的( Z 表示Z或Zulu或UTC时区,它有多个名称).

Now it’s evident that the time is correct (Z means Z or Zulu or UTC time zone, it’s got more than one name).

如果由于某种原因您绝对需要一个老式的 java.util.Date 对象,那并不困难:

If for some reason you absolutely need an oldfashioned java.util.Date object, that is not difficult:

    Date date = Date.from(utcDateTime.toInstant());

此日期与从 sdf.parse()获得的日期相同,且具有UTC时区.

This gives the same date as we got from sdf.parse() with UTC time zone.

这篇关于SimpleDateFormat将字符串解析为错误的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆