Commons Lang
  1. Commons Lang
  2. LANG-538

DateFormatUtils.format does not correctly change Calendar TimeZone in certain situations

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.4
    • Fix Version/s: 2.5
    • Component/s: lang.time.*
    • Labels:
      None
    • Environment:

      Sun JDK6, RHEL 5.3

      Description

      If a Calendar object is constructed in certain ways a call to Calendar.setTimeZone does not correctly change the Calendars fields. Calling Calenar.getTime() seems to fix this problem. While this is probably a bug in the JDK, it would be nice if DateFormatUtils was smart enough to detect/resolve this problem.

      For example, the following unit test fails:

        public void testFormat_CalendarIsoMsZulu() {
          final String dateTime = "2009-10-16T16:42:16.000Z";
      
          // more commonly constructed with: cal = new GregorianCalendar(2009, 9, 16, 8, 42, 16)
          // for the unit test to work in any time zone, constructing with GMT-8 rather than default locale time zone
          GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-8"));
          cal.clear();
          cal.set(2009, 9, 16, 8, 42, 16);
      
      
          FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT"));
          assertEquals("dateTime", dateTime, format.format(cal));
        }
      

      However, this unit test passes:

        public void testFormat_CalendarIsoMsZulu() {
          final String dateTime = "2009-10-16T16:42:16.000Z";
          GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-8"));
          cal.clear();
          cal.set(2009, 9, 16, 8, 42, 16);
          cal.getTime();
      
          FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT"));
          assertEquals("dateTime", dateTime, format.format(cal));
        }
      

        Issue Links

          Activity

          Jeff Peterson created issue -
          Henri Yandell made changes -
          Field Original Value New Value
          Fix Version/s 3.0 [ 12311714 ]
          Fix Version/s 2.x [ 12313695 ]
          Henri Yandell made changes -
          Component/s lang.time.* [ 12313196 ]
          Hide
          Henri Yandell added a comment -

          I think this is due to FastDateFormat's:

          if (mTimeZoneForced)

          { calendar = (Calendar) calendar.clone(); calendar.setTimeZone(mTimeZone); }

          If I call getTime() before that, then the code works. If however I wait until after that to call getTime(), it does not work. The calendar before and after report themselves to be equal, and their toString contains the same information in both cases, yet something must not be getting lazy-initialized and then lost in the clone.

          Show
          Henri Yandell added a comment - I think this is due to FastDateFormat's: if (mTimeZoneForced) { calendar = (Calendar) calendar.clone(); calendar.setTimeZone(mTimeZone); } If I call getTime() before that, then the code works. If however I wait until after that to call getTime(), it does not work. The calendar before and after report themselves to be equal, and their toString contains the same information in both cases, yet something must not be getting lazy-initialized and then lost in the clone.
          Henri Yandell committed 891542 (2 files)
          Reviews: none

          Fixing LANG-538 - you need to call getTime() on a calendar sometimes to get it in the right state, otherwise the timezone gets out of whack.

          Hide
          Henri Yandell added a comment -

          Thanks for the report Jeff. I've inserted a getTime() into FastDateFormat that fixes your test case, and hopefully extends to the general problem.

          svn ci -m "Fixing LANG-538 - you need to call getTime() on a calendar sometimes to get it in the right state, otherwise the timezone gets out of whack. " src
          Sending src/java/org/apache/commons/lang3/time/FastDateFormat.java
          Sending src/test/org/apache/commons/lang3/time/FastDateFormatTest.java
          Transmitting file data ..
          Committed revision 891542.

          Show
          Henri Yandell added a comment - Thanks for the report Jeff. I've inserted a getTime() into FastDateFormat that fixes your test case, and hopefully extends to the general problem. svn ci -m "Fixing LANG-538 - you need to call getTime() on a calendar sometimes to get it in the right state, otherwise the timezone gets out of whack. " src Sending src/java/org/apache/commons/lang3/time/FastDateFormat.java Sending src/test/org/apache/commons/lang3/time/FastDateFormatTest.java Transmitting file data .. Committed revision 891542.
          Henri Yandell made changes -
          Status Open [ 1 ] Closed [ 6 ]
          Resolution Fixed [ 1 ]
          Henri Yandell committed 892161 (1 file)
          Reviews: none

          Switching from getTime() to getTimeInMillis() per Sebb's report that it still fixes LANG-538 and is going to be lighter weight

          Niall Pemberton committed 904941 (2 files)
          Reviews: none

          Port LANG-538 to 2.x branch - need to call getTime() on a calendar sometimes to get it in the right state, otherwise the timezone gets out of whack.

          Niall Pemberton made changes -
          Fix Version/s 2.5 [ 12314743 ]
          Fix Version/s 3.0 [ 12311714 ]
          Mark Thomas made changes -
          Workflow jira [ 12479673 ] Default workflow, editable Closed status [ 12602604 ]
          Hide
          Christian P. MOMON added a comment -

          Hi. This bug is existing in version 3.3.1. The "assertEquals("dateTime", dateTime, format.format(cal));" from the test above returns the following error:
          org.junit.ComparisonFailure: dateTime expected:<2009-10-16T[16]:42:16.000Z> but was:<2009-10-16T[08]:42:16.000Z>

          Reproduced whit Sun Java version: 1.6.0_45 and 1.7.0_21 on Fedora 17 (Linux 3.9.10-100.fc17.i686.PAE).

          I will try to clone this issue.

          Show
          Christian P. MOMON added a comment - Hi. This bug is existing in version 3.3.1. The "assertEquals("dateTime", dateTime, format.format(cal));" from the test above returns the following error: org.junit.ComparisonFailure: dateTime expected:<2009-10-16T [16] :42:16.000Z> but was:<2009-10-16T [08] :42:16.000Z> Reproduced whit Sun Java version: 1.6.0_45 and 1.7.0_21 on Fedora 17 (Linux 3.9.10-100.fc17.i686.PAE). I will try to clone this issue.
          Christian P. MOMON made changes -
          Link This issue is a clone of LANG-916 [ LANG-916 ]

            People

            • Assignee:
              Unassigned
              Reporter:
              Jeff Peterson
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development