0
votes

I am aware that SimpleDateFormat.parse rely on the Calendar API which depends on local JVM timezone (computer's). Assume JVM timezone is IST.

SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
srcDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 21:58:25 

From the output it seems it converts from EST to IST(JVM local timezone).

SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
srcDateFormat.setTimeZone(TimeZone.getTimeZone("IST"));
Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 11:28:25 

It keeps time unmodified in this case. In this case I set timezone same as JVM local timezone.

Please help me to understand the behavior of the parse method. Nevertheless, I am curious to know the reason behind such behavior. I know that java.util.Date and java.text.SimpleDateFormat legacy classes are obsolete now.

References:

1
It's not about the parse() method. It's about the toString() method of Date, which always formats the date using the default timezone. Just like, even if you use a French number format to parse the string "1,23" to a double, and print the double, it will always be printed as 1.23, because the default way of formatting a double is to use the English format (i.e. using a dot and not a comma as decimal separator).JB Nizet
I think java.util.Date does not hold any timezone information. Your example is more related to Locale.Dhruv Kapatel
Which is precisely why its toString() method needs to choose a timezone to transform it to a string. And the chosen timezone is the default one. Just like the toString method has to choose a locale to transform the double to a string, and the chosen one is the English one.JB Nizet
If above point is true then in the 2nd scenario why it is not converted again to IST? There is no Timezone related information in the date string.Dhruv Kapatel
Well, the default timezone is IST, you parse the time 11:28:25 using the IST timezone, and when you print the date, thus using the default IST timezone, you get 11:28:25. That's the correct time, in the IST timezone. Not sure what else you think it should be nor why.JB Nizet

1 Answers

2
votes

First, you are correct that Date and SimpleDateFormat are legacy classes and now obsolete. So I recommend you don’t use them and use java.time, the modern Java date and time API, instead. Among many advantages it is much more explicit about conversions between time zones, which I would expect to help you understand what the code does.

Second, you are doing a number of things incorrectly or at least inadequately:

  1. Don’t store date-times as strings. Always store them as date-time objects in Java. When you do this, you will never need to convert a date-time string from one zone to another. Instant (a class from java.time) is a point in time and as far as I can see the one you should use here.
  2. Don’t rely in three letter time zone abbreviations. Very many of them are ambiguous, including both of IST and EST, and the latter isn’t a true time zone, so what you get at this time of year (when America/New_York zone uses EDT rather than EST), I don’t know.
  3. And repeating myself, use the modern classes, not the obsolete ones.

Out of curiosity what happened?

An old-fashioned Date represents a point in time independently of time zone (internally it stores its value as a count of milliseconds since the epoch, but this is an implementation detail that we need not know or concern ourselves with).

In your first example your string is parsed into a point in time that corresponds to 16:28:25 UTC, 21:58:25 in India, 12:28:25 in New York or 11:28:25 in Jamaica. I mention Jamaica because it’s one of the few places that happens to use Eastern Standard Time (EST) all year. Most of the locations that use EST only do so in winter, not at this time of year. When you look at the Date in your debugger, the debugger calls toString on the Date to get a string to show you. toString in turn uses the JVM’s time zone for generating the string. In your case it’s Asia/Kolkata, which is why you get 21:58:25.

In the second case the same string is parsed into a point in time that corresponds to 05:58:25 UTC, 11:28:25 in India, 01:58:25 in New York or 00:58:25 in Jamaica. Your debugger again calls toString, which again uses your JVM’s time zone and converts back into 11:28:25 IST. When you parse and print in the same time zone, you get the same time of day back.

Links