From 1b85d8ba9e7bea6e4c7742b57bf71c38f1bf0a27 Mon Sep 17 00:00:00 2001 From: Henri Yandell Date: Thu, 17 Dec 2009 07:21:25 +0000 Subject: [PATCH] Applying 'fix' for LANG-530. DateUtils.parseDate now protects the common use case of FastDateFormat ZZ output, namely ZZ on the end of the pattern, from being passed to SimpleDateFormat as is. Use of ZZ elsewhere in the pattern isn't protected and will want to consider emulating the String changes made in this patch. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@891572 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/commons/lang3/time/DateUtils.java | 23 +++++++++++++++---- .../commons/lang3/time/DateUtilsTest.java | 9 ++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/java/org/apache/commons/lang3/time/DateUtils.java b/src/java/org/apache/commons/lang3/time/DateUtils.java index 6581638af..8cb019e06 100644 --- a/src/java/org/apache/commons/lang3/time/DateUtils.java +++ b/src/java/org/apache/commons/lang3/time/DateUtils.java @@ -290,14 +290,29 @@ public class DateUtils { SimpleDateFormat parser = null; ParsePosition pos = new ParsePosition(0); for (int i = 0; i < parsePatterns.length; i++) { + + String pattern = parsePatterns[i]; + + // LANG-530 - need to make sure 'ZZ' output doesn't get passed to SimpleDateFormat + if (parsePatterns[i].endsWith("ZZ")) { + pattern = pattern.substring(0, pattern.length() - 1); + } + if (i == 0) { - parser = new SimpleDateFormat(parsePatterns[0]); + parser = new SimpleDateFormat(pattern); } else { - parser.applyPattern(parsePatterns[i]); // cannot be null if i != 0 + parser.applyPattern(pattern); // cannot be null if i != 0 } pos.setIndex(0); - Date date = parser.parse(str, pos); - if (date != null && pos.getIndex() == str.length()) { + + String str2 = str; + // LANG-530 - need to make sure 'ZZ' output doesn't hit SimpleDateFormat as it will ParseException + if (parsePatterns[i].endsWith("ZZ")) { + str2 = str.replaceAll("([-+][0-9][0-9]):([0-9][0-9])$", "$1$2"); + } + + Date date = parser.parse(str2, pos); + if (date != null && pos.getIndex() == str2.length()) { return date; } } diff --git a/src/test/org/apache/commons/lang3/time/DateUtilsTest.java b/src/test/org/apache/commons/lang3/time/DateUtilsTest.java index c742db20c..8198bf05f 100644 --- a/src/test/org/apache/commons/lang3/time/DateUtilsTest.java +++ b/src/test/org/apache/commons/lang3/time/DateUtilsTest.java @@ -1156,6 +1156,15 @@ public class DateUtilsTest extends TestCase { // restore default time zone TimeZone.setDefault(defaultZone); } + + // http://issues.apache.org/jira/browse/LANG-520 + public void testLang520() throws ParseException { + Date d = new Date(); + String isoDateStr = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(d); + Date d2 = DateUtils.parseDate(isoDateStr, new String[] { DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern() }); + // the format loses milliseconds so have to reintroduce them + assertEquals("Date not equal to itself ISO formatted and parsed", d.getTime(), d2.getTime() + d.getTime() % 1000); + } /** * Tests various values with the ceiling method