0

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
Estevão Jordão
  • 189
  • 1
  • 5
  • 20
  • possible duplicate of [Approach to convert from org.joda.time.DateTime to java.util.Calendar](http://stackoverflow.com/questions/363930/approach-to-convert-from-org-joda-time-datetime-to-java-util-calendar) – MaxZoom Sep 18 '15 at 17:54
  • The question is different, I'm asking how would be the best way to perform the conversion keeping the UTC Time Zone, since it is older version does not provide this support me – Estevão Jordão Sep 18 '15 at 18:22
  • I don't understand why you need to use the older version. Can you [edit] to explain further? – durron597 Sep 18 '15 at 18:22
  • Well, it seems that the version *without* the `toLocalDateTime()` is the correct one as it prints the actual correct time. Where is the problem? – RealSkeptic Sep 18 '15 at 18:41
  • I Need the Date with the UTC Time and not my current Time – Estevão Jordão Sep 18 '15 at 18:48
  • A `java.util.Date` does *not* have a time zone. It simply encapsulates the number of milliseconds since midnight, January 1st, 1970 **UTC**. As such, it is the most correct representation of the UTC time. If you want to print it in UTC, you can put a time zone in a date format. If you change it so that it prints the UTC time but still say "BRT" then it is incorrect. – RealSkeptic Sep 18 '15 at 18:50
  • I don't need the Time Zone, just the currect Time to TimeZone: UTC TIME : 18:19:51 DATE Convertion Direct Date: 15:19:51 DATE Time UTC with Parse 18:19:51 – Estevão Jordão Sep 18 '15 at 18:58
  • @EstevãoJordão So what you're saying is that your company is forcing you to use a library from Feb 2006, and no one has tried to update it in nine years? Perhaps now would be a good time, especially since Joda time is discouraged now in favor of `java.util.time` in Java 8. – durron597 Sep 18 '15 at 19:44
  • I know, it is very sad, I'm trying to see a process to update, but I want to have a pre Solution, any recommendation about the question ? – Estevão Jordão Sep 18 '15 at 19:48
  • Again, your date is incorrect, because it shows you 18:19:51 but has "BRT" next to it. This means that you have converted the date in a way that doesn't comply with the `Date` contract. You should convert in the second method, and print it with `UTC` time zone using a date formatter, and you'll see it's the correct time. – RealSkeptic Sep 18 '15 at 21:02
  • Hi @RealSkeptic , Could you please give a example ? A need a Date Object in return – Estevão Jordão Sep 18 '15 at 21:59
  • Do *not* use `parse` to try to convert. I only gave `parse` in my answer as an introduction to the `Date` class. It should *not* be used to convert from Joda time to `Date`. The method that should be used is what you have in your first line. So after the "Now in MEX" print, you should just have `javaDate = dateTime.toDate()`. – RealSkeptic Sep 19 '15 at 17:15
  • If I should not use the parse, how to keep the Time Zone in toDate ()? I added two new lines in Test, please see. The toLocalDateTime () method of the most current Joda, keep my Time Zone.I'm working on a system that will have several TimeZones and data will be saved in UTC in the database, I'm working with a convert to the JPA, which will take the TimeZone of a session bean and convert the UTC for this Time Zone. I'm sorry for the difficulty of understanding, but still can not see a solution in my turn without using the parse – Estevão Jordão Sep 22 '15 at 02:29

1 Answers1

6

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.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
  • Sorry, but there is still no clear how I should do this conversion being the BASE_FORMAT, is not suitable for DateTime, I updated again the question end UPDATE 2 – Estevão Jordão Sep 19 '15 at 17:14