Java – Joda Time – Convert UTC DateTime to Date – Using a Version 1.2.1.1 of Joda

datetimejavajodatimeutc

Good morning everyone.

I'd like to help you to see how I can accomplish the conversion of a org.joda.time.DateTime to java.util.Date using the 1.2.1.1 version of Joda Time.

Why Joda 1.2.1.1 ? Because currently I can only work with this version of Joda "unfortunately".

My Test>

    System.out.println("JODA Version : 2.8.2 - UTC TIME to Date " + new DateTime().withZone(DateTimeZone.UTC).toLocalDateTime().toDate());;
    System.out.println("JODA Version : 1.2.1.1 - UTC TIME to Date " + new DateTime().withZone(DateTimeZone.UTC).toDate());;


JODA Version : 2.8.2 - UTC TIME to Date Fri Sep 18 17:34:36 BRT 2015
JODA Version : 1.2.1.1 - UTC TIME to Date Fri Sep 18 14:34:36 BRT 2015

My problem being that in version 1.2.1.1 the Date is on my local settings and in this version there is no toLocalDateTime() method.

I would ask the help and experience of you to discover the best practices in order to perform this conversion in JODA Version: 1.2.1.1

How can I perform this conversion to the hour: minute: second in UTC this older version of JODA?

I researched a lot and saw some people talking to do so would be a good practice?

public  static Date converterDateTimeToUTCDate(final DateTime dateTime) throws ParseException {
    DateTime dat = dateTime.withZone(DateTimeZone.UTC);
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").parse(dat.toString("yyyy-MM-dd HH:mm:ss:SSS"));
}

public static void main(String[] args) throws ParseException {
    System.out.println("TODO DATE UTC TIME : " + new DateTime().withZone(DateTimeZone.UTC));
    System.out.println("TODO DATE Convertion Direct Date: " + new DateTime().withZone(DateTimeZone.UTC).toDate());

    Date converterUTCDateTimeToDate = converterDateTimeToUTCDate(new DateTime());

    System.out.println("TODO DATE UTC with Parse : " + converterUTCDateTimeToDate);

}

Result:

TODO DATE UTC TIME : 2015-09-18T22:33:57.353Z
TODO DATE Convertion Direct Date: Fri Sep 18 19:33:57 BRT 2015
TODO DATE UTC with Parse : Fri Sep 18 22:33:57 BRT 2015

EDIT
Why Joda 1.2.1.1 ? Because currently I can only work with this version of Joda "unfortunately".

I work in a company where there is a very long process to change the version of an API within the project and my project does not have this waiting time, to use a new version

UPDATE:

I looked and java Date has no TimeZone, this BRT is caught from my local machine in the toString () method of the class, I can consider that it is right to convert then?

UPDATE 2

I edited the example of my answer for an example:

See:

package joda;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class ConverterDateTimeToDate {
    public static final String BASE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS z";

    public static void main(String[] args) {

        // Different display time zones

        SimpleDateFormat formatUTC = new SimpleDateFormat( BASE_FORMAT );
        formatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));

        SimpleDateFormat formatBrazil = new SimpleDateFormat( BASE_FORMAT );
        formatBrazil.setTimeZone(TimeZone.getTimeZone("America/Sao_Paulo"));

        SimpleDateFormat formatCentralEurope = new SimpleDateFormat( BASE_FORMAT );
        formatCentralEurope.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));

        // Get a date in UTC

        String dateString = "2015-09-19 10:45:00.000 UTC";
        Date javaDate = null;
        try {
            DateTime dateTime = new DateTime().withZone(DateTimeZone.forID("America/Mexico_City"));
System.out.println("MEX TIME IN JODA : " + dateTime); //new Test
            System.out.println("MEX TIME IN JODA CONVERTER : " + dateTime.toDate()); // new Test
            System.out.println("Now in MEX Time Zone DateTime : " + dateTime);

            javaDate = formatUTC.parse(dateTime.toString(BASE_FORMAT));
        } catch (ParseException e) {
            e.printStackTrace(); // Shouldn't happen.
        }

        // Now let's print it in various time zones. It's the same date - 10:45 in UTC!

        System.out.println("In UTC:             " + formatUTC.format(javaDate));
        System.out.println("In Brazil:          " + formatBrazil.format(javaDate));
        System.out.println("In the Netherlands: " + formatCentralEurope.format(javaDate));

    }
}

My Out Put : in In UTC: 2015-09-19 12:10:56.731 CDT, Was the problem with my convertion ? Because my DateTime in System it's come this aways

My Output:

MEX TIME IN JODA : 2015-09-21T21:17:46.781-05:00
MEX TIME IN JODA CONVERTER : Mon Sep 21 23:17:46 BRT 2015
Now in MEX Time Zone DateTime : 2015-09-21T21:17:46.781-05:00
In UTC:             1732-01-11 02:17:46.781 UTC
In Brazil:          1732-01-10 23:17:46.781 BRT
In the Netherlands: 1732-01-11 03:17:46.781 CET

Best Answer

The correct way is to use toDate()

The method in the DateTime class, even in old JodaTime, is the correct one. Here is an explanation:


Explanation about how java.util.Date works

You seem to have a misconception about java.util.Date. It does not contain a time zone. It is a representation of a time offset since January 1970, 00:00 UTC.

When you print a Date object, your JVM takes your default time zone and shows you the Date at that time zone. So when you print dates, you should always use a DateFormat object if you want to look at them in a different time zone. For example, if you want to see what the date is in UTC, you have to use a date format with its time zone set to UTC. Here is an example:

public static final String BASE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS z";

public static void main(String[] args) {

    // Different display time zones

    SimpleDateFormat formatUTC = new SimpleDateFormat( BASE_FORMAT );
    formatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));

    SimpleDateFormat formatBrazil = new SimpleDateFormat( BASE_FORMAT );
    formatBrazil.setTimeZone(TimeZone.getTimeZone("America/Sao_Paulo"));

    SimpleDateFormat formatCentralEurope = new SimpleDateFormat( BASE_FORMAT );
    formatCentralEurope.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));

    // Get a date in UTC

    String dateString = "2015-09-19 10:45:00.000 UTC";
    Date javaDate = null;
    try {
        javaDate = formatUTC.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace(); // Shouldn't happen.
    }

    // Now let's print it in various time zones. It's the same date - 10:45 in UTC!

    System.out.println("In UTC:             " + formatUTC.format(javaDate));
    System.out.println("In Brazil:          " + formatBrazil.format(javaDate));
    System.out.println("In the Netherlands: " + formatCentralEurope.format(javaDate));

}

The output from this program is:

In UTC:             2015-09-19 10:45:00.000 UTC
In Brazil:          2015-09-19 07:45:00.000 BRT
In the Netherlands: 2015-09-19 12:45:00.000 CEST

You can see we printed the same date - and it shows up differently based on the time zone of the format.


Converting properly from Joda TimeStamp to java.util.Date

The same logic is true for Joda's DateTime object, but it's more complex, because it also includes a time zone, though it is not used for all operations. Internally, it also represents an offset from UTC.

When you use its toDate() method, it relies on that internal offset from UTC, thus it is giving you the correct Date object according to the java.util.Date contract.

Let's demonstrate that by replacing the way we get the date in the above program to:

DateTime jodaDateTime = new DateTime( 2015, 9, 19, 10, 45, 0, 0, DateTimeZone.UTC);

Date javaDate = jodaDateTime.toDate();

Now, running the same prints as before, again we get:

In UTC:             2015-09-19 10:45:00.000 UTC
In Brazil:          2015-09-19 07:45:00.000 BRT
In the Netherlands: 2015-09-19 12:45:00.000 CEST

So you see, if the Joda DateTime was appropriately set, then using its toDate gives you the correct Date object.


Showing that using toLocalDateTime() is wrong

Now, if we use your first method, the one you thought was correct, which only exists in Joda 2.0 and above, what will we get?

We change the code to:

DateTime jodaDateTime = new DateTime( 2015, 9, 19, 10, 45, 0, 0, DateTimeZone.UTC);
Date javaDate = jodaDateTime.toLocalDateTime().toDate();

The Joda DateTime is the same as before, we just added the toLocalDateTime() that exists only in Joda 2.

Assuming the default time zone on your system is BRT, you get the result:

In UTC:             2015-09-19 13:45:00.000 UTC
In Brazil:          2015-09-19 10:45:00.000 BRT
In the Netherlands: 2015-09-19 15:45:00.000 CEST

This is clearly not the correct date! The toLocalDateTime() part took your local time offset and added it to the date to make a "local" date. Which is good as long as you stay within Joda time constructs, but breaks the contract for java.util.Date because it sets the incorrect offset from UTC.


Conclusion

The old method you had in the old Joda is the best one to get an appropriate java.util.Date from an org.joda.time.DateTime. But you have to be very careful at how you print the java.util.Date because it will be printed by default in your default time zone.

One last advice: if you want to start the upgrade process in your company, don't bother with Joda time. Ask them to start upgrading the system to Java 8, which is currently the only Java version maintained by Oracle. Java 8 includes a proper Date/Time library and the creators of Joda recommend switching to using that.