Java和Joda-Time:日期错误值 [英] Java and Joda-Time: date wrong value

查看:67
本文介绍了Java和Joda-Time:日期错误值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试解析一个 Joda-Time 时,我得到了错误的日期像这样的字符串日期:

I'm getting a wrong date in Joda-Time when I try to parse a string date like this:

2013-11-20 18:20:00 +01:00

2013-11-20 18:20:00 +01:00

我希望获得以下日期: Wed Nov 20 19:20:00 CET 2013 但我得到: Wed Nov 20 18:20:00 CET 2013

I'm expecting to obtain the following date: Wed Nov 20 19:20:00 CET 2013 but I'm getting: Wed Nov 20 18:20:00 CET 2013

我正在使用Joda-Time,这是我的代码:

I'm using Joda-Time and this is my code:

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();

推荐答案

期望

您的期望是错误的.

Expectations

Your expectation is wrong.

"+ 01:00"表示时间比 > UTC /GMT.因此,调整为UTC意味着要减去一个小时(17:20)而不是加一个(19:20).

The "+01:00" means that time is one hour ahead of UTC/GMT. So, adjusting to UTC means subtracting an hour (17:20) rather than adding (19:20).

"+ 01:00"与说欧洲中部时间(CET),表示比世界标准时间(UTC)/格林尼治标准时间(GMT)提前一小时.所以...

The "+01:00" has the same effect as saying CET (Central European Time), meaning one hour ahead of UTC/GMT. So…

2013-11-20 18:20:00 +01:00 = Wed Nov 20 18:20:00 CET 2013

...这是两种表示同一时间,同一小时的不同方式.

…those are two different ways of stating the same time, same hour.

当我在美国西海岸时间在此处运行您的代码时,我得到…(注意相同的时间)

When I run your code here in United States west coast time, I get… (note the same hours)

temp: 2013-11-20T09:20:00.000-08:00
date: Wed Nov 20 09:20:00 PST 2013

j.u.日期混乱

正如 Stroboskop的答案所述,您可能会被java.util.Date所迷惑.对象本身具有时区信息.但这是 toString()的实现方法使用默认时区来呈现要显示的文本.令人困惑.避免使用java.util.Date/Calendar类的众多原因之一.相反,Joda-Time DateTime 对象确实知道自己的时区.

j.u.Date Confusion

As the answer by Stroboskop said, you may be fooled by java.util.Date. The object itself does not have time zone information. Yet it's implementation of the toString() method uses the default time zone in rendering the text to be displayed. Confusing. One of many reasons to avoid using the java.util.Date/Calendar classes. In contrast, Joda-Time DateTime objects do indeed know their own time zone.

您真正的问题太普遍了:忽略时区.如果未指定时区,则使用默认时区.如您在上面看到的,我的默认时区与您的默认时区不同,因此在运行相同的代码时得到的结果不同.

Your real problem is an all too common one: Ignoring time zones. By not specifying a time zone, your default time zone was used. As you can see above, my default time zone is different than yours, so I got different results while running the same code.

更好的做法是始终指定您的时区.如果要UTC/GMT,请这样说.如果要CET,请这样说. (实际上,请不要使用CET这样的三字母代码,因为它们没有标准化并且具有重复-使用时区名称,例如 Europe/Prague Europe/Paris .)在解析该字符串时,请指定要在新的DateTime对象中合并的时区.

A better practice is to always specify your time zone. If you want UTC/GMT, say so. If you want CET, say so. (Actually, don't use the three-letter code like CET as they are not standardized and have duplicates – use a time zone name such as Europe/Prague or Europe/Paris.) When parsing that string, specify the time zone to be incorporated within the new DateTime object.

这是一些示例代码,显示了在解析时如何指定时区.请注意对 withZone() .

Here is some example code showing how to specify the time zone while parsing. Note the call to withZone().

请注意,所有三个解析的结果在Universe的时间轴中是同一时刻.为此,我的代码自 Unix时代备份每个DateTime以来的毫秒数转储到控制台.目的.通常,我尝试不使用也不考虑毫秒数.但是这里使用毫秒-自纪元证明了这一点.

Note that the result of all three parsings is the same moment in the time line of the Universe. To make that point, my code dumps to the console the milliseconds since the Unix Epoch backing each DateTime object. Usually I try to not use nor think about the milliseconds-since-epoch. But here the use of milliseconds-since-epoch proves a point.

// © 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() );

运行时…(请注意,无论此代码在您的计算机上还是在我的计算机上运行,​​我们都得到相同的结果!)

When run… (Note that whether this code runs on your computer or mine, we both get the same results!)

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

这篇关于Java和Joda-Time:日期错误值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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