Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat behaves inconsistently

See the following piece of code:

String timeString = "1980-01-01T14:00:00+0300";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date2 = sdf.parse(timeString);

// sdf.getCalendar().get(Calendar.ZONE_OFFSET);
System.out.println(sdf.format(date2));

now, I'm in a country that has +2h offset, +1 daylight savings(at the moment). If I run this code as it is, it will print

1980-01-01T13:00:00+0200

If I uncomment the line asking about the calendar's offset, the output of the program is

1980-01-01T14:00:00+0300

Any idea why is that happening, and how can I get a consistent output?

To avoid any more unclear things: Since I'm handling some legacy code, java 8 is not an option. And yes, the key point here is WHY, and not what are the workarounds? And there are 2 WHYs:

  1. Why do i pass a +0300 TZ and by default i receive a +0200 one? (SimpleDateFormat should always use TimeZone.getDefault unless otherwise specified).
  2. Why does it give a different answer just because I call a getter on it's calendar instance.
like image 664
Eduard Korenschi Avatar asked Jul 03 '15 11:07

Eduard Korenschi


1 Answers

The problem is, that Calendar#get is not a simple getter, it looks like this:

public int  get(int field)
{
    complete();
    return internalGet(field);
}

where complete does this, according to the Javadoc:

Fills in any unset fields in the calendar fields. First, the computeTime() method is called if the time value (millisecond offset from the Epoch) has not been calculated from calendar field values. Then, the computeFields() method is called to calculate all calendar field values.

I looked up the source here, but the code is the same for the latest Java version too.

like image 168
meskobalazs Avatar answered Sep 21 '22 07:09

meskobalazs