0

I have date-time in persistent storage received from an external system. I need to use this and set as a Date type for a java library routine. This messes up the same to be set under the current jvm timezone. I understand that an offset may not necessarily corresponding timezone, but, this is messing up a lot of things.

eg:

2020-08-14T08:59:34.961+05:30

Sample code:

String dateFromDatabase = "2020-08-14T08:59:34.961+05:30";
SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date tempDate=outputDateFormat.parse(dateFromDatabase);
System.out.println( tempDate );

Sample output:

Thu Aug 13 23:29:34 EDT 2020

Expected output:

it should not return the EDT based datetime

How can I keep my date with the correct offset?

Any suggestions/ recommendations on how to achieve this?

Thanks

DataRiver
  • 188
  • 1
  • 8
  • 21
  • 1
    use the not-so-new `java.time` [package](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/time/package-summary.html): `ZonedDateTime.parse(dateFromDatabase)` –  Mar 19 '21 at 15:18
  • @user15244370 Yes, i tried that, but, it does not give me the Date type which is what I need to pass it to the library routine... Any step to convert to Date type is a problem. – DataRiver Mar 19 '21 at 15:23
  • `Date` is just an instant in time - if you print it (`toString`) you will get its representation using the actual default `TimeZone` - so the *library* is probably also using it (try, for testing, changing the `TimeZone.setDefault(TimeZone.getTimeZone(zonedDate.getZone())` (which probably may mess up somewhere else in code) –  Mar 19 '21 at 15:26
  • As i understood you want to parse `2020-08-14T08:59:34.961+05:30 ` and keep the time as is like `08:59:34.961`, does that right? – Montaser Sobaih Mar 19 '21 at 16:42
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead just use `OffsetDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Mar 19 '21 at 18:29

1 Answers1

1

The java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). It means that irrespective of the location in the world, a Date object represents the same number (milliseconds from the epoch). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value. In order to print the date-time in a different timezone, we set the timezone to SimpleDateFormat and obtain the formatted string from it.

If you do not like the output like Thu Aug 13 23:29:34 EDT 2020, which is the string returned by Date#toString in your timezone (and will be different in different timezones), there are two options:

  1. Represent the Date in milliseconds (as described above, it will be the same at any location in the world) obtained using Date#getTime.
  2. Keep the original string, 2020-08-14T08:59:34.961+05:30 as it is because it already represents the date-time in the ISO8601 format.

Note that the java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.

A demo of the modern date-time API:

import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;

public class Main {

    public static void main(String args[]) {
        String dateFromDatabase = "2020-08-14T08:59:34.961+05:30";
        ZonedDateTime zdt = ZonedDateTime.parse(dateFromDatabase);
        System.out.println(zdt);

        // If at all you need java.util.Date, you can get it from Instant
        Instant instant = zdt.toInstant();
        Date date = Date.from(instant);
    }
}

Output:

2020-08-14T08:59:34.961+05:30

Learn more about the modern date-time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110