简体   繁体   中英

Java and Joda-Time: date wrong value

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

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

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.

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).

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

juDate 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.

Specify 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.

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.

Example Code

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

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

Dump to console…

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

Standard question: what time zone are you in? CET?

I assume the parsed DateTime is correct? What timezone does it have?

Bear in mind that Date doesn't have timezones. I'm not even sure if it actually considers Timezone.getDefault().

So, in short it looks like you have a timezone different from +1 and that's why your time is moved by one hour.

-- edit -- hold on. why do you even expect 19:20? The text says 18:20 +1, Joda parses this just like that and Date drops the timezone. That's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM