roxrook
roxrook

Reputation: 13853

Why Joda DateTime gives different result than Java Date?

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

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

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.

What symbol should I use to parse a zone offset string?

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.

You do not need a 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

Online Demo

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

Adrian Shum
Adrian Shum

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

Related Questions