Reputation: 13853
I tested Joda DateTime against java.util.Date
with UTC timezone, and I encountered an interesting case:
import org.joda.time.DateTime;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String dt = "2011-06-11T12:00:00Z";
String format = "yyyy-MM-dd'T'hh:mm:ss'Z'";
DateFormat df = new SimpleDateFormat(format);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = df.parse(dt);
DateTime joda = new DateTime(dt);
// Output Sat Jun 11 05:00:00 PDT 2011
System.out.println(joda.toDate());
// Output Fri Jun 10 17:00:00 PDT 2011
System.out.println(d);
}
}
I wonder is this a bug to either one or I missed something important here?
Upvotes: 5
Views: 652
Reputation: 79075
You are trying to parse Z
as a text literal 'Z'
, not as a time zone offset. Z
(probably, it's an abbreviation of Zulu
) specifies a zero time zone offset, +00:00
; therefore, use XXX
with the pattern in your date-time parsing/formatting object. Check 'Z'
is not the same as Z
to learn more about it.
You should use X
to parse the zone offset in an offset-date-time string that is not in the default format.
Example of zone offset format | Pattern |
---|---|
-08 |
X |
-0830 |
XX |
-08:30 |
XXX |
-08:30:15 |
XXXXX |
Check the documentation to learn more about it.
java.time
In March 2014, Java 8 introduced the modern, java.time
date-time API which supplanted the error-prone legacy java.util
date-time API. Any new code should use the java.time
API.
Also, shown below is a notice on the Joda-Time Home Page:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
DateTimeFormatter
Your date-time string, 2011-06-11T12:00:00Z
is in the default format (based on ISO 8601 standard) used by Instant#parse
. So, you do not need to use a DateTimeFormatter
explicitly.
You can even parse it into an OffsetDateTime
or a ZonedDateTime
directly (i.e. without using a DateTimeFormatter
explicitly).
Note: The java.util.Date
is not a true date object; it just represents the number of milliseconds from epoch (January 1, 1970, 00:00:00 GMT). The Date#toString
function uses the JVM's default time zone to form the date-time string.
Demo:
class Main {
public static void main(String[] args) {
String str = "2011-06-11T12:00:00Z";
Instant instant = Instant.parse(str);
OffsetDateTime odt = OffsetDateTime.parse(str);
ZonedDateTime zdt = ZonedDateTime.parse(str);
System.out.println(instant);
System.out.println(odt);
System.out.println(zdt);
}
}
Output:
2011-06-11T12:00:00Z
2011-06-11T12:00Z
2011-06-11T12:00Z
Note: For some reason, if you need an instance of java.util.Date
, let the java.time
API perform the heavy lifting of parsing your date-time string and you can get it using Date.from(instant)
.
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 2
Reputation: 40036
(Edit: a clearer and more correct answer)
I believe it is because JODA and Java Date Format is treating "12" in 12-hour presentation differently. One of them treat it as midnight, while the other treat it as noon.
Change your input to 2011-06-11T01:00:00Z
will prove my hypothesis.
It is because, you are creating JODA time using the constructor of DateTime, which in turns parse your String using ISO format, for which use 24-hour format : Default format used by JODA, while the DateFormat you used to construct your Java Date is using hh
for hour field, which means 12-hour format. Therefore they interpret "12" differently: 12-hour format treat it as mid-night, while 24-hour treat it as noon.
Easiest change is to change the format to yyyy-MM-dd'T'HH:mm:ss'Z'
which use 24-hour presentation, then both of them works fine.
Upvotes: 6