Author: sebb
Date: Sun Mar 1 17:59:34 2015
New Revision: 1663140
URL: http://svn.apache.org/r1663140
Log:
LANG-1061 FastDateParser error - timezones not handled correctly
Added:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
Modified:
commons/proper/lang/trunk/src/changes/changes.xml
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
Modified: commons/proper/lang/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/changes/changes.xml?rev=1663140&r1=1663139&r2=1663140&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/lang/trunk/src/changes/changes.xml [utf-8] Sun Mar 1
17:59:34 2015
@@ -22,6 +22,7 @@
<body>
<release version="3.4" date="tba" description="tba">
+ <action issue="LANG-1061" type="fix" dev="sebb"
due-to="dmeneses">FastDateParser error - timezones not handled
correctly</action>
<action issue="LANG-1087" type="fix" dev="britter" due-to="Renat
Zhilkibaev">NumberUtils#createNumber() returns positive BigDecimal when
negative Float is expected</action>
<action issue="LANG-1081" type="fix" dev="britter" due-to="Jonathan
Baker">DiffBuilder.append(String, Object left, Object right) does not do a
left.equals(right) check</action>
<action issue="LANG-1055" type="fix" dev="britter" due-to="Jonathan
Baker">StrSubstitutor.replaceSystemProperties does not work
consistently</action>
Modified:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/time/FastDateParser.java?rev=1663140&r1=1663139&r2=1663140&view=diff
==============================================================================
---
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
(original)
+++
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
Sun Mar 1 17:59:34 2015
@@ -780,7 +780,8 @@ public class FastDateParser implements D
}
final StringBuilder sb= new StringBuilder();
- sb.append("(GMT[+\\-]\\d{0,1}\\d{2}|[+\\-]\\d{2}:?\\d{2}|");
+ sb.append("(GMT[+-]\\d{1,2}:\\d{2}").append('|');
+ sb.append("[+-]\\d{4}").append('|');
for(final String id : tzNames.keySet()) {
escapeRegex(sb, id, false).append('|');
}
Added:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java?rev=1663140&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
(added)
+++
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
Sun Mar 1 17:59:34 2015
@@ -0,0 +1,118 @@
+package org.apache.commons.lang3.time;
+
+import static org.junit.Assert.*;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Compare FastDateParser with SimpleDateFormat
+ */
+@RunWith(Parameterized.class)
+public class FastDateParserSDFTest {
+
+ @Parameters(name= "{index}: {0} {1} {2}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object [][]{
+ // General Time zone tests
+ {"z yyyy", "GMT 2010", Locale.UK, true}, // no offset
specified, but seems to be allowed
+ {"z yyyy", "GMT-123 2010", Locale.UK, false},
+ {"z yyyy", "GMT-1234 2010", Locale.UK, false},
+ {"z yyyy", "GMT-12:34 2010", Locale.UK, true},
+ {"z yyyy", "GMT-1:23 2010", Locale.UK, true},
+ // RFC 822 tests
+ {"z yyyy", "-1234 2010", Locale.UK, true},
+ {"z yyyy", "-12:34 2010", Locale.UK, false},
+ {"z yyyy", "-123 2010", Locale.UK, false},
+ // year tests
+ { "MM/dd/yyyy", "01/11/12", Locale.UK, true},
+ { "MM/dd/yy", "01/11/12", Locale.UK, true},
+ });
+ }
+
+ private final String format;
+ private final String input;
+ private final Locale locale;
+ private final boolean valid;
+
+ public FastDateParserSDFTest(String format, String input, Locale locale,
boolean valid) {
+ this.format = format;
+ this.input = input;
+ this.locale = locale;
+ this.valid = valid;
+ }
+
+ @Test
+ public void testOriginal() throws Exception {
+ final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+ final TimeZone timeZone = TimeZone.getDefault();
+ final DateParser fdf = new FastDateParser(format, timeZone, locale);
+ checkParse(locale, sdf, fdf, input);
+ }
+
+ @Test
+ public void testUpperCase() throws Exception {
+ final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+ final TimeZone timeZone = TimeZone.getDefault();
+ final DateParser fdf = new FastDateParser(format, timeZone , locale);
+ checkParse(locale, sdf, fdf, input.toUpperCase(locale));
+ }
+
+ @Test
+ @Ignore // not currently supported
+ public void testLowerCase() throws Exception {
+ final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+ final TimeZone timeZone = TimeZone.getDefault();
+ final DateParser fdf = new FastDateParser(format, timeZone , locale);
+ checkParse(locale, sdf, fdf, input.toLowerCase(locale));
+ }
+
+ private void checkParse(final Locale locale, final SimpleDateFormat sdf,
final DateParser fdf, final String formattedDate) throws ParseException {
+ Date expectedTime=null;
+ Class<?> sdfE = null;
+ try {
+ expectedTime = sdf.parse(formattedDate);
+ if (!valid) {
+ // Error in test data
+ throw new RuntimeException("Test data error: expected SDF
parse to fail, but got " + expectedTime);
+ }
+ } catch (ParseException e) {
+ if (valid) {
+ // Error in test data
+ throw new RuntimeException("Test data error: expected SDF
parse to succeed, but got " + e);
+ }
+ sdfE = e.getClass();
+ }
+ Date actualTime = null;
+ Class<?> fdfE = null;
+ try {
+ actualTime = fdf.parse(formattedDate);
+ if (!valid) {
+ // failure in test
+ fail("Expected FDP parse to fail, but got " + actualTime);
+ }
+ } catch (ParseException e) {
+ if (valid) {
+ // failure in test
+ fail("Expected FDP parse to succeed, but got " + e);
+ }
+ fdfE = e.getClass();
+ }
+ if (valid) {
+ assertEquals(locale.toString()+" "+formattedDate
+"\n",expectedTime, actualTime);
+ } else {
+ assertEquals(locale.toString()+" "+formattedDate + " expected same
Exception ", sdfE, fdfE);
+ }
+ }
+}