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