Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow parsing timezone without fully provided time backport(#50178) #50740

Merged
merged 3 commits into from
Jan 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -883,9 +916,28 @@ public void testParsingMissingTimezone() {
}

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"))) {
Expand All @@ -904,6 +956,12 @@ private void assertSameDate(String input, String format) {
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);

Expand Down