2

I have the below code:

DateFormat df = new SimpleDateFormat("M/d/yy h:mm a z");
df.setLenient(false);
System.out.println(df.parse("6/29/2012 5:15 PM IST"));

Assuming I now set my PC's timezone to Pacific Time (UTC-7 for PDT), this prints

Fri Jun 29 08:15:00 PDT 2012

Isn't PDT 12.5 hours behind IST (Indian Standard Time)? This problem does not occur for any other timezone - I tried UTC, PKT, MMT etc instead of IST in the date string. Are there two ISTs in Java by any chance?

P.S: The date string in the actual code comes from an external source, so I cannot use GMT offset or any other timezone format.

Vasan
  • 4,810
  • 4
  • 20
  • 39
  • There are several ISTs as far as I know. Judging by the time difference (9 hours), you've probably got Israel Standard Time. – biziclop Jun 29 '12 at 15:38
  • @biziclop I thought about this. But what veered me away from that was the below: `System.out.println(TimeZone.getTimeZone("IST").getRawOffset());` This prints 19800000, or 5.5 hours, which suggests that it is indeed Indian Standard Time. Or is it picking up the first of many timezones with the same ID "IST"? If so, how can something be an "ID" if it is the same for many things? – Vasan Jun 29 '12 at 15:41
  • @esej It's more likely to be an ambiguity in the timezone abbreviations: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations – biziclop Jun 29 '12 at 15:43
  • Looking at the [source code](http://www.docjar.com/html/api/sun/util/calendar/TzIDOldMapping.java.html) it seems that IST is India... – assylias Jun 29 '12 at 15:50
  • 1
    @Vasan it's not really an ID and `SimpleDateFormat` is a strange beast, it's very likely that it isn't using `TimeZone.getTimeZone()` at all. – biziclop Jun 29 '12 at 15:52

4 Answers4

11

The abberviated names of timezone are ambiguous and have been deprecated for Olson names for timezones. The following works consistently as there may be be differences in the way parse() and getTimezone() behaves.

SimpleDateFormat sdf = new SimpleDateFormat("M/d/yy h:mm a Z");
TimeZone istTimeZone = TimeZone.getTimeZone("Asia/Kolkata");
Date d = new Date();
sdf.setTimeZone(istTimeZone);
String strtime = sdf.format(d);
rnk
  • 2,394
  • 1
  • 19
  • 19
6

Sorry, I have to write an answer for this, but try this code:

public class Test {

    public static void main(String[] args) throws ParseException {
        DF df = new DF("M/d/yy h:mm a z");
        String [][] zs = df.getDateFormatSymbols().getZoneStrings();
        for( String [] z : zs ) {
            System.out.println( Arrays.toString( z ) );
        }
    }

    private static class DF extends SimpleDateFormat {
        @Override
        public DateFormatSymbols getDateFormatSymbols() {
            return super.getDateFormatSymbols();
        }

        public DF(String pattern) {
            super(pattern);
        }
    }

}

You'll find that IST appears several times in the list and the first one is indeed Israel Standard Time.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • 1
    Thank you, that is quite helpful. I suppose then that I'd have to do something weird like stripping the timezone from the date string before parsing it. The timezone part I can then pass to TimeZone.getTimeZone() to get the actual timezone (I suppose even that isn't guaranteed to work always!). It is all getting patchy now, damn you DateFormat! – Vasan Jun 29 '12 at 16:16
  • @Vasan Well, DateFormat isn't the only culprit here, the basic problem is that the time zone acronyms aren't unique. In hindsight that was a daft idea. :) – biziclop Jun 29 '12 at 18:06
4

Not an answer but see the output + code below - it does seem that parse treats IST differently from TimeZone.getTimeZone("IST")...

Fri Jun 29 16:15:00 BST 2012
Fri Jun 29 12:45:00 BST 2012
Fri Jun 29 12:45:00 BST 2012
*BST = London

public static void main(String[] args) throws InterruptedException, ParseException {
    DateFormat fmt1 = new SimpleDateFormat("M/d/yy h:mm a Z");
    Date date = fmt1.parse("6/29/2012 5:15 PM IST");
    System.out.println(date);

    DateFormat fmt2 = new SimpleDateFormat("M/d/yy h:mm a");
    fmt2.setTimeZone(TimeZone.getTimeZone("IST"));
    System.out.println(fmt2.parse("6/29/2012 5:15 PM"));

    DateFormat fmt3 = new SimpleDateFormat("M/d/yy h:mm a");
    fmt3.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
    System.out.println(fmt3.parse("6/29/2012 5:15 PM"));
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Yes, it's exactly what I said. `SimpleDateFormat` is a strange beast and doesn't play by the rules. It has its own time zone data array and uses whatever comes first in it. – biziclop Jun 29 '12 at 16:07
0

It is because of IST will have multiple meanings like Irish Standard Time, Isreal Standrad Time, Indian Standard Time.

Ref: https://www.timeanddate.com/time/zones/

Use setTimezone() method specifically to set the timezone.

Ex: parser.setTimeZone(TimeZone.getTimeZone("specify timezone in detail here"));

Sumanth
  • 1
  • 1