当我尝试解析这样的字符串日期时,我在Joda-Time收到了错误的日期:
2013-11-20 18:20:00 +01:00
我希望获得以下日期:
Wed Nov 20 19:20:00 CET 2013
但我得到了:
Wed Nov 20 18:20:00 CET 2013
我正在使用Joda-Time,这是我的代码:
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
DateTime temp = formatter.parseDateTime(dateString);
Date date = temp.toDate();
答案 0 :(得分:6)
你的期望是错误的。
“+01:00”表示UTC / GMT的时间提前一小时。因此,调整为UTC意味着减去一小时(17:20)而不是添加(19:20)。
“+01:00”与CET (Central European Time)具有相同的效果,这意味着比UTC / GMT提前一小时。所以......
2013-11-20 18:20:00 +01:00
= Wed Nov 20 18:20:00 CET 2013
......这是同一时间同一时间陈述的两种不同方式。
当我在美国西海岸时间运行你的代码时,我得到......(注意同一时间)
temp: 2013-11-20T09:20:00.000-08:00
date: Wed Nov 20 09:20:00 PST 2013
正如the answer by Stroboskop所说,你可能会受到java.util.Date的愚弄。对象本身不具有时区信息。然而,toString()
方法的实现使用默认时区来呈现要显示的文本。混乱。避免使用java.util.Date/Calendar类的众多原因之一。相比之下,Joda-Time DateTime对象确实知道他们自己的时区。
您真正的问题是一个非常常见的问题:忽略时区。如果未指定时区,则使用默认时区。如您所见,我的默认时区与您的不同,因此在运行相同代码时得到的结果不同。
更好的做法是始终指定您的时区。如果你想要UTC/GMT
,请说明。如果你想要CET
,请说明。 (实际上,不要使用像CET
这样的三字母代码,因为它们没有标准化并且有重复 - 使用时区名称,例如 Europe / Prague 或 Europe / Paris 。)解析该字符串时,请指定要合并到新DateTime对象中的时区。
以下是一些示例代码,说明如何在解析时指定时区。请注意对withZone()
的调用。
请注意,所有三个解析的结果都是Universe时间线中的相同时刻。为了说明这一点,我的代码将自Unix Epoch支持每个DateTime对象以来的毫秒转储到控制台。通常我会尝试不使用也不考虑毫秒以来的时间。但是这里使用毫秒 - 自 - 时代证明了一点。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
// Time Zone list… http://joda-time.sourceforge.net/timezones.html (not quite up-to-date, read page for details)
DateTime dateTimeInUtc = formatter.withZone( DateTimeZone.UTC ).parseDateTime( dateString );
DateTime dateTimeInPrague = formatter.withZone( DateTimeZone.forID( "Europe/Prague" ) ).parseDateTime(dateString);
DateTime dateTimeInVancouver = formatter.withZone( DateTimeZone.forID( "America/Vancouver" ) ).parseDateTime(dateString);
转储到控制台...
System.out.println( "dateTimeInUtc: " + dateTimeInUtc + " … In Milliseconds since Unix Epoch: " + dateTimeInUtc.getMillis() );
System.out.println( "dateTimeInPrague: " + dateTimeInPrague + " … In Milliseconds since Unix Epoch: " + dateTimeInPrague.getMillis() );
System.out.println( "dateTimeInVancouver: " + dateTimeInVancouver + " … In Milliseconds since Unix Epoch: " + dateTimeInVancouver.getMillis() );
运行时...(请注意,无论此代码是在您的计算机上还是我的计算机上运行,我们都会得到相同的结果!)
dateTimeInUtc: 2013-11-20T17:20:00.000Z … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInPrague: 2013-11-20T18:20:00.000+01:00 … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInVancouver: 2013-11-20T09:20:00.000-08:00 … In Milliseconds since Unix Epoch: 1384968000000
答案 1 :(得分:2)
标准问题:你在哪个时区? CET
我假设解析的DateTime是正确的?它有什么时区?
请记住,Date没有时区。我甚至不确定它是否真的考虑了Timezone.getDefault()。
所以,简而言之,看起来你的时区与+1不同,这就是为什么你的时间会被移动一小时。
- 编辑 - 坚持,稍等。为什么你甚至期待19:20?文字说18:20 +1,Joda解析这个就像那样,而Date则删除了时区。就是这样。