0

We are converting database date into required user timezone. But if we format using jodatime in string format we are getting correct date and if we parse string to get date object we are getting wrong time. Here is my code. I tried jodatime parser and java date

public class Test {

    public static void main(String[] args) {
        String dateF = "01/19/2019 at 07:35 PM (UTC)";
        String dateFormat = "MM/dd/yyyy 'at' hh:mm a (zzz)";
        long time = 1603305000;
        String timeZone = "Etc/UTC";
        Locale locale=new Locale("en", "US");
        DateTimeFormatter dateFormatter = null;

        if (locale.equals(Locale.FRENCH)) {
            dateFormatter = DateTimeFormat.forPattern(dateFormat).withLocale(locale);
        } else {
            dateFormatter = DateTimeFormat.forPattern(dateFormat).withLocale(null);

        }

        if (true) {
            dateFormatter = dateFormatter.withZone(DateTimeZone.forID(timeZone));
        }
        // Old Logic using Java Time
        DateFormat format3 = new SimpleDateFormat(dateFormat, locale);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        if(true)
            format3.setTimeZone(TimeZone.getTimeZone(timeZone));

        DateTime jodatime = new DateTime(time);
        try {
            System.out.println(dateFormatter.print(jodatime));
            System.out.println("timezone converted Date : " + format3.parse(dateFormatter.print(jodatime)));

            System.out.println("dateFormatter.parseDateTime converted Date : " + dateFormatter.parseDateTime(dateFormatter.print(jodatime)).toDate());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Correct date in Formatted string 01/19/1970 at 01:21 PM (UTC)

We are getting a wrong result after parsing timezone converted Date : Mon Jan 19 18:51:00 IST 1970

dateFormatter.parseDateTime converted Date : Mon Jan 19 18:51:00 IST 1970

Correct date in Formatted Date : Mon Jan 19 01:21:00 UTC 1970

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
paresh
  • 351
  • 1
  • 3
  • 12
  • 4
    Why are you using `SimpleDateFormat` when you're using Joda-Time? Why are you using the deprecated Joda-Time, and not the Java Time API? – Andreas Jan 22 '19 at 06:36
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 22 '19 at 06:47
  • FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. – Basil Bourque Jan 22 '19 at 06:48
  • According to [Epoch Unix Time Stamp Converter](https://www.unixtimestamp.com/index.php) Unix time 1603305000 is equivalent to 10/21/2020 @ 6:30pm (UTC). Are you sure you want 01/19/1970 at 01:21 PM (UTC)? – Ole V.V. Jan 22 '19 at 08:46
  • Mon Jan 19 18:51:00 IST 1970 agrees with 01/19/1970 at 01:21 PM (UTC). If I assume that IST means India Standard Time (it can have other meanings). Both times you are printing a `java.util.Date` object, and a `Date` object hasn’t got a time zone, so you shouldn’t expect it to be converted to the required user time zone. – Ole V.V. Jan 22 '19 at 08:53

1 Answers1

2

Avoid legacy date-time classes

You are using terrible old classes bundled with the earliest versions of Java. These have been supplanted entirely by the modern java.time classes.

You are also apparently mixing those legacy classes with classes from the Joda-Time library. Firstly, that mixing is ill-advised. Secondly, Joda-Time is now in maintenance-mode, with its creators advising migration to java.time. Actually, both Joda-Time and java.time projects are led by the same man, Stephen Colebourne, with the first project having been the inspiration and education for the second.

Smart objects, not dumb strings

We are converting database date

Then avoid all the string manipulations you are doing.

As of JDBC 4.2, you can directly exchange java.time objects with your database. For a moment, meaning a column of a type akin to the SQL-standard TIMESTAMP WITH TIME ZONE, use OffsetDateTime class.

myPreparedStatement.setObject( … , myOffsetDateTime ) ;

…and…

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Most databases store moments in UTC. You may want to adjust into a time zone for presentation to users. Apply a ZoneId to get a ZonedDateTime object.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Generate text in a certain format by using DateTimeFormatter object. Either specify a custom formatting pattern or automatically localize by calling ofLocalized… methods.

All of this has been covered many many many times on Stack Overflow already. Search to learn more.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154