LANG-1116: DateUtilsTest.testLang530 fails for some timezones
This commit is contained in:
parent
cb83f7cb31
commit
bea1ae92aa
|
@ -22,6 +22,7 @@
|
|||
<body>
|
||||
|
||||
<release version="3.5" date="tba" description="tba">
|
||||
<action issue="LANG-1116" type="fix" dev="chas" due-to="Aaron Sheldon">DateUtilsTest.testLang530 fails for some timezones</action>
|
||||
<action issue="LANG-1114" type="fix" dev="britter" due-to="Andy Coates">TypeUtils.ParameterizedType#equals doesn't work with wildcard types</action>
|
||||
<action issue="LANG-1119" type="add" dev="britter" due-to="Loic Guibert">Add rotate(string, int) method to StringUtils</action>
|
||||
<action issue="LANG-1118" type="fix" dev="britter" due-to="Loic Guibert">StringUtils.repeat('z', -1) throws NegativeArraySizeException</action>
|
||||
|
|
|
@ -18,12 +18,12 @@ package org.apache.commons.lang3.time;
|
|||
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
|
@ -365,37 +365,21 @@ public class DateUtils {
|
|||
if (str == null || parsePatterns == null) {
|
||||
throw new IllegalArgumentException("Date and Patterns must not be null");
|
||||
}
|
||||
|
||||
SimpleDateFormat parser;
|
||||
if (locale == null) {
|
||||
parser = new SimpleDateFormat();
|
||||
} else {
|
||||
parser = new SimpleDateFormat("", locale);
|
||||
}
|
||||
|
||||
parser.setLenient(lenient);
|
||||
|
||||
final TimeZone tz = TimeZone.getDefault();
|
||||
final Locale lcl = locale==null ?Locale.getDefault() : locale;
|
||||
final ParsePosition pos = new ParsePosition(0);
|
||||
|
||||
for (final String parsePattern : parsePatterns) {
|
||||
|
||||
String pattern = parsePattern;
|
||||
|
||||
// LANG-530 - need to make sure 'ZZ' output doesn't get passed to SimpleDateFormat
|
||||
if (parsePattern.endsWith("ZZ")) {
|
||||
pattern = pattern.substring(0, pattern.length() - 1);
|
||||
FastDateParser fdp = new FastDateParser(parsePattern, tz, lcl, null, lenient);
|
||||
try {
|
||||
Date date = fdp.parse(str, pos);
|
||||
if (pos.getIndex() == str.length()) {
|
||||
return date;
|
||||
}
|
||||
pos.setIndex(0);
|
||||
}
|
||||
|
||||
parser.applyPattern(pattern);
|
||||
pos.setIndex(0);
|
||||
|
||||
String str2 = str;
|
||||
// LANG-530 - need to make sure 'ZZ' output doesn't hit SimpleDateFormat as it will ParseException
|
||||
if (parsePattern.endsWith("ZZ")) {
|
||||
str2 = str.replaceAll("([-+][0-9][0-9]):([0-9][0-9])$", "$1$2");
|
||||
}
|
||||
|
||||
final Date date = parser.parse(str2, pos);
|
||||
if (date != null && pos.getIndex() == str2.length()) {
|
||||
return date;
|
||||
catch(IllegalArgumentException iae) {
|
||||
}
|
||||
}
|
||||
throw new ParseException("Unable to parse the date: " + str, -1);
|
||||
|
|
|
@ -75,7 +75,7 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
*
|
||||
* @see java.io.Serializable
|
||||
*/
|
||||
private static final long serialVersionUID = 2L;
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
static final Locale JAPANESE_IMPERIAL = new Locale("ja","JP","JP");
|
||||
|
||||
|
@ -85,6 +85,7 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
private final Locale locale;
|
||||
private final int century;
|
||||
private final int startYear;
|
||||
private final boolean lenient;
|
||||
|
||||
// derived fields
|
||||
private transient Pattern parsePattern;
|
||||
|
@ -106,7 +107,7 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
* @param locale non-null locale
|
||||
*/
|
||||
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale) {
|
||||
this(pattern, timeZone, locale, null);
|
||||
this(pattern, timeZone, locale, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,11 +122,31 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
* @since 3.3
|
||||
*/
|
||||
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) {
|
||||
this(pattern, timeZone, locale, centuryStart, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a new FastDateParser.</p>
|
||||
*
|
||||
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible
|
||||
* pattern
|
||||
* @param timeZone non-null time zone to use
|
||||
* @param locale non-null locale
|
||||
* @param centuryStart The start of the century for 2 digit year parsing
|
||||
* @param lenient if true, non-standard values for Calendar fields should be accepted;
|
||||
* if false, non-standard values will cause a ParseException to be thrown {@link CalendaretLenient(boolean)}
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale,
|
||||
final Date centuryStart, final boolean lenient) {
|
||||
this.pattern = pattern;
|
||||
this.timeZone = timeZone;
|
||||
this.locale = locale;
|
||||
this.lenient = lenient;
|
||||
|
||||
final Calendar definingCalendar = Calendar.getInstance(timeZone, locale);
|
||||
|
||||
int centuryStartYear;
|
||||
if(centuryStart!=null) {
|
||||
definingCalendar.setTime(centuryStart);
|
||||
|
@ -336,6 +357,7 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
// timing tests indicate getting new instance is 19% faster than cloning
|
||||
final Calendar cal= Calendar.getInstance(timeZone, locale);
|
||||
cal.clear();
|
||||
cal.setLenient(lenient);
|
||||
|
||||
for(int i=0; i<strategies.length;) {
|
||||
final Strategy strategy= strategies[i++];
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
@ -268,4 +269,20 @@ public class DateFormatUtilsTest {
|
|||
String date = "2013-11-18T12:48:05Z";
|
||||
DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.parse(date);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLang530() throws ParseException {
|
||||
TimeZone save = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
final Date d = new Date();
|
||||
final String isoDateStr = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(d);
|
||||
final 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);
|
||||
}
|
||||
finally {
|
||||
TimeZone.setDefault(save);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue