diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7f1fdf334..6ba92b626 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -22,7 +22,7 @@
- Fix parsing edge cases in FastDateParser
+
diff --git a/src/main/java/org/apache/commons/lang3/time/FastDateParser.java b/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
index 2d469a6b3..d704f69ca 100644
--- a/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
+++ b/src/main/java/org/apache/commons/lang3/time/FastDateParser.java
@@ -744,13 +744,9 @@ public class FastDateParser implements DateParser, Serializable {
/**
* A strategy that handles a timezone field in the parsing pattern
*/
- static class TimeZoneStrategy extends Strategy {
- private static final String RFC_822_TIME_ZONE = "[+-]\\d{4}";
- private static final String GMT_OPTION= "GMT[+-]\\d{1,2}:\\d{2}";
- // see http://www.iana.org/time-zones and http://cldr.unicode.org/translation/timezones
- static final String TZ_DATABASE= "(?:\\p{L}[\\p{L}\\p{Mc}\\p{Nd}\\p{Zs}\\p{P}&&[^-]]*-?\\p{Zs}?)*";
- private static final String VALID_TZ = "((?iu)"+RFC_822_TIME_ZONE+"|"+GMT_OPTION+"|"+TZ_DATABASE+")";
-
+ private static class TimeZoneStrategy extends Strategy {
+
+ private final String validTimeZoneChars;
private final SortedMap tzNames= new TreeMap(String.CASE_INSENSITIVE_ORDER);
/**
@@ -781,6 +777,9 @@ public class FastDateParser implements DateParser, Serializable {
TimeZoneStrategy(final Locale locale) {
final String[][] zones = DateFormatSymbols.getInstance(locale).getZoneStrings();
for (final String[] zone : zones) {
+ if (zone[ID].startsWith("GMT")) {
+ continue;
+ }
final TimeZone tz = TimeZone.getTimeZone(zone[ID]);
if (!tzNames.containsKey(zone[LONG_STD])){
tzNames.put(zone[LONG_STD], tz);
@@ -796,7 +795,16 @@ public class FastDateParser implements DateParser, Serializable {
tzNames.put(zone[SHORT_DST], tz);
}
}
- }
+ }
+
+ final StringBuilder sb= new StringBuilder();
+ 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('|');
+ }
+ sb.setCharAt(sb.length()-1, ')');
+ validTimeZoneChars= sb.toString();
}
/**
@@ -804,7 +812,7 @@ public class FastDateParser implements DateParser, Serializable {
*/
@Override
boolean addRegex(final FastDateParser parser, final StringBuilder regex) {
- regex.append(VALID_TZ);
+ regex.append(validTimeZoneChars);
return true;
}
@@ -817,8 +825,8 @@ public class FastDateParser implements DateParser, Serializable {
if(value.charAt(0)=='+' || value.charAt(0)=='-') {
tz= TimeZone.getTimeZone("GMT"+value);
}
- else if(value.regionMatches(true, 0, "GMT", 0, 3)) {
- tz= TimeZone.getTimeZone(value.toUpperCase());
+ else if(value.startsWith("GMT")) {
+ tz= TimeZone.getTimeZone(value);
}
else {
tz= tzNames.get(value);
diff --git a/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java b/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
index 284579dec..36c232c94 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/FieldUtilsTest.java
@@ -24,8 +24,8 @@ import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import static org.junit.Assert.*;
@@ -146,36 +146,26 @@ public class FieldUtilsTest {
FieldUtils.getField(PublicChild.class, " ", true);
}
- private Field[] allPublicChildFields() {
- Class super PublicChild> parentClass = PublicChild.class.getSuperclass();
- final Field[] fieldsParent = parentClass.getDeclaredFields();
- assertArrayEquals(fieldsParent, FieldUtils.getAllFields(parentClass));
-
- final Field[] fieldsPublicChild = PublicChild.class.getDeclaredFields();
- return ArrayUtils.addAll(fieldsPublicChild, fieldsParent);
- }
-
- private Field[] allIntegerFields() {
- final Field[] fieldsNumber = Number.class.getDeclaredFields();
- assertArrayEquals(Number.class.getDeclaredFields(), FieldUtils.getAllFields(Number.class));
- final Field[] fieldsInteger = Integer.class.getDeclaredFields();
- return ArrayUtils.addAll(fieldsInteger, fieldsNumber);
- }
-
@Test
public void testGetAllFields() {
assertArrayEquals(new Field[0], FieldUtils.getAllFields(Object.class));
- assertArrayEquals(allIntegerFields(), FieldUtils.getAllFields(Integer.class));
-
- assertArrayEquals(allPublicChildFields(), FieldUtils.getAllFields(PublicChild.class));
+ final Field[] fieldsNumber = Number.class.getDeclaredFields();
+ assertArrayEquals(fieldsNumber, FieldUtils.getAllFields(Number.class));
+ final Field[] fieldsInteger = Integer.class.getDeclaredFields();
+ assertArrayEquals(ArrayUtils.addAll(fieldsInteger, fieldsNumber), FieldUtils.getAllFields(Integer.class));
+ assertEquals(5, FieldUtils.getAllFields(PublicChild.class).length);
}
@Test
public void testGetAllFieldsList() {
- assertEquals(Collections.emptyList(), FieldUtils.getAllFieldsList(Object.class));
- assertEquals(Arrays.asList(allIntegerFields()), FieldUtils.getAllFieldsList(Integer.class));
-
- assertEquals(Arrays.asList(allPublicChildFields()), FieldUtils.getAllFieldsList(PublicChild.class));
+ assertEquals(0, FieldUtils.getAllFieldsList(Object.class).size());
+ final List fieldsNumber = Arrays.asList(Number.class.getDeclaredFields());
+ assertEquals(fieldsNumber, FieldUtils.getAllFieldsList(Number.class));
+ final List fieldsInteger = Arrays.asList(Integer.class.getDeclaredFields());
+ final List allFieldsInteger = new ArrayList(fieldsInteger);
+ allFieldsInteger.addAll(fieldsNumber);
+ assertEquals(allFieldsInteger, FieldUtils.getAllFieldsList(Integer.class));
+ assertEquals(5, FieldUtils.getAllFieldsList(PublicChild.class).size());
}
@Test
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
index 75ca3428c..bdf5e27f8 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateParserSDFTest.java
@@ -27,6 +27,7 @@ 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;
@@ -137,11 +138,13 @@ public class FastDateParserSDFTest {
}
@Test
+ @Ignore // not currently supported
public void testLowerCase() throws Exception {
checkParse(input.toLowerCase(locale));
}
@Test
+ @Ignore // not currently supported
public void testLowerCasePP() throws Exception {
checkParsePosition(input.toLowerCase(locale));
}
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
index c2a387f48..b75d0861e 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.Serializable;
-import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -31,7 +30,6 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
-import java.util.regex.Pattern;
import org.apache.commons.lang3.SerializationUtils;
import org.junit.Assert;
@@ -262,21 +260,21 @@ public class FastDateParserTest {
@Test
public void testTzParses() throws Exception {
// Check that all Locales can parse the time formats we use
- for(final Locale locale : Locale.getAvailableLocales()) {
- final FastDateParser fdp= new FastDateParser("yyyy/MM/dd z", TimeZone.getDefault(), locale);
+ for(final Locale locale : Locale.getAvailableLocales()) {
+ final FastDateParser fdp= new FastDateParser("yyyy/MM/dd z", TimeZone.getDefault(), locale);
- for(final TimeZone tz : new TimeZone[]{NEW_YORK, REYKJAVIK, GMT}) {
- final Calendar cal= Calendar.getInstance(tz, locale);
- cal.clear();
- cal.set(Calendar.YEAR, 2000);
- cal.set(Calendar.MONTH, 1);
- cal.set(Calendar.DAY_OF_MONTH, 10);
- final Date expected= cal.getTime();
+ for(final TimeZone tz : new TimeZone[]{NEW_YORK, REYKJAVIK, GMT}) {
+ final Calendar cal= Calendar.getInstance(tz, locale);
+ cal.clear();
+ cal.set(Calendar.YEAR, 2000);
+ cal.set(Calendar.MONTH, 1);
+ cal.set(Calendar.DAY_OF_MONTH, 10);
+ final Date expected= cal.getTime();
- final Date actual = fdp.parse("2000/02/10 "+tz.getDisplayName(locale));
- Assert.assertEquals("tz:"+tz.getID()+" locale:"+locale.getDisplayName(), expected, actual);
- }
- }
+ final Date actual = fdp.parse("2000/02/10 "+tz.getDisplayName(locale));
+ Assert.assertEquals("tz:"+tz.getID()+" locale:"+locale.getDisplayName(), expected, actual);
+ }
+ }
}
@@ -642,19 +640,4 @@ public class FastDateParserTest {
}
}
- @Test
- public void testTimeZoneStrategyPattern() {
- Pattern tz = Pattern.compile(FastDateParser.TimeZoneStrategy.TZ_DATABASE);
- Assert.assertFalse(tz.matcher("GMT-1234").matches());
-
- for (Locale locale : Locale.getAvailableLocales()) {
- final String[][] zones = DateFormatSymbols.getInstance(locale).getZoneStrings();
- for (final String[] zone : zones) {
- for (String zoneExpr : zone) {
- Assert.assertTrue(locale.getDisplayName() + ":" + zoneExpr, tz.matcher(zoneExpr).matches());
- }
- }
- }
- }
-
}