strict_date_optional_time changes to have optional minute part. It already allowed optional second and fraction of second part. This allows parsing 2018-01-01T00+01 , 2018-01-01T00:00+01 , 2018-01-01T00:00:00+01 , 2018-01-01T00:00:00.000+01 It won't allow parsing a timezone without an hour part as this is not allowed by iso8601 spec closes #49351
This commit is contained in:
parent
9d1567b13b
commit
e95b0c447f
|
@ -108,31 +108,31 @@ public class DateFormatters {
|
|||
private static final DateTimeFormatter STRICT_DATE_OPTIONAL_TIME_FORMATTER = new DateTimeFormatterBuilder()
|
||||
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
|
||||
.optionalStart()
|
||||
.appendLiteral('T')
|
||||
.optionalStart()
|
||||
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendLiteral(':')
|
||||
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendLiteral(':')
|
||||
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendFraction(NANO_OF_SECOND, 1, 9, true)
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.appendLiteral(',')
|
||||
.appendFraction(NANO_OF_SECOND, 1, 9, false)
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.appendZoneOrOffsetId()
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.append(TIME_ZONE_FORMATTER_NO_COLON)
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.appendLiteral('T')
|
||||
.optionalStart()
|
||||
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendLiteral(':')
|
||||
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendLiteral(':')
|
||||
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
|
||||
.optionalStart()
|
||||
.appendFraction(NANO_OF_SECOND, 1, 9, true)
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.appendLiteral(',')
|
||||
.appendFraction(NANO_OF_SECOND, 1, 9, false)
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.appendZoneOrOffsetId()
|
||||
.optionalEnd()
|
||||
.optionalStart()
|
||||
.append(TIME_ZONE_FORMATTER_NO_COLON)
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.optionalEnd()
|
||||
.toFormatter(Locale.ROOT)
|
||||
.withResolverStyle(ResolverStyle.STRICT);
|
||||
|
|
|
@ -46,9 +46,42 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
|
|||
protected boolean enableWarningsCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void testTimezoneParsing() {
|
||||
/** this testcase won't work in joda. See comment in {@link #testPartialTimeParsing()}
|
||||
* assertSameDateAs("2016-11-30T+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
*/
|
||||
assertSameDateAs("2016-11-30T00+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T00+0100", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T00+01:00", "strict_date_optional_time", "strict_date_optional_time");
|
||||
}
|
||||
|
||||
public void testPartialTimeParsing() {
|
||||
/*
|
||||
This does not work in Joda as it reports 2016-11-30T01:00:00Z
|
||||
because StrictDateOptionalTime confuses +01 with an hour (which is a signed fixed length digit)
|
||||
assertSameDateAs("2016-11-30T+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
ES java.time implementation does not suffer from this,
|
||||
but we intentionally not allow parsing timezone without an time part as it is not allowed in iso8601
|
||||
*/
|
||||
assertJavaTimeParseException("2016-11-30T+01","strict_date_optional_time");
|
||||
|
||||
assertSameDateAs("2016-11-30T12+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00:00+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00:00.000+01", "strict_date_optional_time", "strict_date_optional_time");
|
||||
|
||||
//without timezone
|
||||
assertSameDateAs("2016-11-30T", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00:00", "strict_date_optional_time", "strict_date_optional_time");
|
||||
assertSameDateAs("2016-11-30T12:00:00.000", "strict_date_optional_time", "strict_date_optional_time");
|
||||
}
|
||||
|
||||
// date_optional part of a parser names "strict_date_optional_time" or "date_optional"time
|
||||
// means that date part can be partially parsed.
|
||||
public void testPartialParsing() {
|
||||
public void testPartialDateParsing() {
|
||||
assertSameDateAs("2001", "strict_date_optional_time_nanos", "strict_date_optional_time");
|
||||
assertSameDateAs("2001-01", "strict_date_optional_time_nanos", "strict_date_optional_time");
|
||||
assertSameDateAs("2001-01-01", "strict_date_optional_time_nanos", "strict_date_optional_time");
|
||||
|
@ -883,9 +916,28 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private void assertSamePrinterOutput(String format, ZonedDateTime javaDate, DateTime jodaDate) {
|
||||
DateFormatter dateFormatter = DateFormatter.forPattern(format);
|
||||
JodaDateFormatter jodaDateFormatter = Joda.forPattern(format);
|
||||
|
||||
assertSamePrinterOutput(format, javaDate, jodaDate, dateFormatter, jodaDateFormatter);
|
||||
}
|
||||
|
||||
private void assertSamePrinterOutput(String format, ZonedDateTime javaDate, DateTime jodaDate, Locale locale) {
|
||||
DateFormatter dateFormatter = DateFormatter.forPattern(format).withLocale(locale);
|
||||
DateFormatter jodaDateFormatter = Joda.forPattern(format).withLocale(locale);
|
||||
|
||||
assertSamePrinterOutput(format, javaDate, jodaDate, dateFormatter, jodaDateFormatter);
|
||||
}
|
||||
|
||||
private void assertSamePrinterOutput(String format,
|
||||
ZonedDateTime javaDate,
|
||||
DateTime jodaDate,
|
||||
DateFormatter dateFormatter,
|
||||
DateFormatter jodaDateFormatter) {
|
||||
String javaTimeOut = dateFormatter.format(javaDate);
|
||||
String jodaTimeOut = jodaDateFormatter.formatJoda(jodaDate);
|
||||
|
||||
assertThat(jodaDate.getMillis(), is(javaDate.toInstant().toEpochMilli()));
|
||||
String javaTimeOut = DateFormatter.forPattern(format).format(javaDate);
|
||||
String jodaTimeOut = Joda.forPattern(format).formatJoda(jodaDate);
|
||||
|
||||
if (JavaVersion.current().getVersion().get(0) == 8 && javaTimeOut.endsWith(".0")
|
||||
&& (format.equals("epoch_second") || format.equals("epoch_millis"))) {
|
||||
|
@ -904,6 +956,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
|
|||
assertSameDate(input, format, jodaFormatter, javaFormatter);
|
||||
}
|
||||
|
||||
private void assertSameDate(String input, String format, Locale locale) {
|
||||
DateFormatter jodaFormatter = Joda.forPattern(format).withLocale(locale);
|
||||
DateFormatter javaFormatter = DateFormatter.forPattern(format).withLocale(locale);
|
||||
assertSameDate(input, format, jodaFormatter, javaFormatter);
|
||||
}
|
||||
|
||||
private void assertSameDate(String input, String format, DateFormatter jodaFormatter, DateFormatter javaFormatter) {
|
||||
DateTime jodaDateTime = jodaFormatter.parseJoda(input);
|
||||
|
||||
|
|
Loading…
Reference in New Issue