2017-01-23 61 views
2

我运行下面的代码: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

一个小时添加。

当我将年/日/小时更改为任何其他有效的号码时,我会得到正确的时间,不会增加额外的小时。如果我只改变分钟或秒数,我仍然可以获得新增的小时数。

谁能告诉我为什么会发生这种情况?

编辑:

这与夏令时在我的程序运行时导通UTC + 02的时区适用于:00。 在这个时区,时钟在2003-03-28更改。这就是为什么要增加一小时的原因,正如下面的评论和回答所建议的那样。

我使用了答案中建议的代码来解析我的日期和解析工作!日期正确解析,额外的小时不被添加。

+0

我得到这个输出'Fri Mar 28 01:00:00 CET 2003'。这可能是一个CET!= CEST问题。 –

+0

试试这个sdf.setTimeZone(TimeZone.getTimeZone(“GMT”)); – Feek

+0

谢谢,我现在得到正确的时间,假设给定的日期是在当地时间..但在我的情况下,日期已在GMT时区给我,所以我不能使用它..我只需要将字符串解析为日期对象。 – mormayr

回答

1

发现你的代码确实做了很复杂的事实,不仅SimpleDateFormat.parse()可能取决于计算机的默认时区(并且在这种情况下,模式不包括时区),也取决于Date.toString()默认时区。不过,我知道你想用UTC来解释日期字符串,所以我将专注于解析正确的解析,而不必太担心打印的内容。

Feek公司是在注释正确的SimpleDateFormat的时区设置为UTC会得到你想要的东西,例如:

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

这一行添加try之前,我在我的电脑上这个输出:

Fri Mar 28 02:00:00 CET 2003 

2 am。 CET同意1 UTC,所以现在解析是正确的。

请允许我补充一点,如果你可以使用Java 8日期和时间里,我发现了对应的代码更为清楚:

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问题。另外一个好处是,产量也预期:

2003-03-28T01:00Z 

现在,显而易见的是,时间是正确的(Z意味着Z或祖鲁语或UTC时区,它有多个名称)。

如果由于某种原因,你绝对需要一个老派java.util.Date对象,这并不难:

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

这让我们从sdf.parse()与UTC时间得到了相同的日期。