a dateformatter can be created with a list of parsers which are iterated during parsing and the first one that passes will return a parsed date. DateMathParser should do the same, when created based on a list of non-rounding parsers it should also iterate over all of them - it is at the moment only taking first element closing #62207
This commit is contained in:
parent
6e071580ff
commit
d87268a264
|
@ -105,18 +105,30 @@ class JavaDateFormatter implements DateFormatter {
|
||||||
} else {
|
} else {
|
||||||
this.parsers = Arrays.asList(parsers);
|
this.parsers = Arrays.asList(parsers);
|
||||||
}
|
}
|
||||||
//this is when the RoundUp Formatter is created. In further merges (with ||) it will only append this one to a list.
|
|
||||||
List<DateTimeFormatter> roundUp = createRoundUpParser(format, roundupParserConsumer);
|
List<DateTimeFormatter> roundUp = createRoundUpParser(format, roundupParserConsumer);
|
||||||
this.roundupParser = new RoundUpFormatter(format, roundUp) ;
|
this.roundupParser = new RoundUpFormatter(format, roundUp) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is when the RoundUp Formatters are created. In further merges (with ||) it will only append them to a list.
|
||||||
|
* || is not expected to be provided as format when a RoundUp formatter is created. It will be splitted before in
|
||||||
|
* <code>DateFormatter.forPattern</code>
|
||||||
|
* JavaDateFormatter created with a custom format like <code>DateFormatter.forPattern("YYYY")</code> will only have one parser
|
||||||
|
* It is however possible to have a JavaDateFormatter with multiple parsers. For instance see a "date_time" formatter in
|
||||||
|
* <code>DateFormatters</code>.
|
||||||
|
* This means that we need to also have multiple RoundUp parsers.
|
||||||
|
*/
|
||||||
private List<DateTimeFormatter> createRoundUpParser(String format,
|
private List<DateTimeFormatter> createRoundUpParser(String format,
|
||||||
Consumer<DateTimeFormatterBuilder> roundupParserConsumer) {
|
Consumer<DateTimeFormatterBuilder> roundupParserConsumer) {
|
||||||
if (format.contains("||") == false) {
|
if (format.contains("||") == false) {
|
||||||
|
List<DateTimeFormatter> roundUpParsers = new ArrayList<>();
|
||||||
|
for (DateTimeFormatter parser : this.parsers) {
|
||||||
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
|
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
|
||||||
builder.append(this.parsers.get(0));
|
builder.append(parser);
|
||||||
roundupParserConsumer.accept(builder);
|
roundupParserConsumer.accept(builder);
|
||||||
return Arrays.asList(builder.toFormatter(locale()));
|
roundUpParsers.add(builder.toFormatter(locale()));
|
||||||
|
}
|
||||||
|
return roundUpParsers;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,14 @@ import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
|
import java.time.format.ResolverStyle;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.LongSupplier;
|
import java.util.function.LongSupplier;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class JavaDateMathParserTests extends ESTestCase {
|
public class JavaDateMathParserTests extends ESTestCase {
|
||||||
|
@ -38,6 +42,47 @@ public class JavaDateMathParserTests extends ESTestCase {
|
||||||
private final DateFormatter formatter = DateFormatter.forPattern("date_optional_time||epoch_millis");
|
private final DateFormatter formatter = DateFormatter.forPattern("date_optional_time||epoch_millis");
|
||||||
private final DateMathParser parser = formatter.toDateMathParser();
|
private final DateMathParser parser = formatter.toDateMathParser();
|
||||||
|
|
||||||
|
|
||||||
|
public void testRoundUpParserBasedOnList() {
|
||||||
|
DateFormatter formatter = new JavaDateFormatter("test", new DateTimeFormatterBuilder()
|
||||||
|
.appendPattern("uuuu-MM-dd")
|
||||||
|
.toFormatter(Locale.ROOT),
|
||||||
|
new DateTimeFormatterBuilder()
|
||||||
|
.appendPattern("uuuu-MM-dd'T'HH:mm:ss.S").appendZoneOrOffsetId().toFormatter(Locale.ROOT)
|
||||||
|
.withResolverStyle(ResolverStyle.STRICT),
|
||||||
|
new DateTimeFormatterBuilder()
|
||||||
|
.appendPattern("uuuu-MM-dd'T'HH:mm:ss.S").appendOffset("+HHmm", "Z").toFormatter(Locale.ROOT)
|
||||||
|
.withResolverStyle(ResolverStyle.STRICT));
|
||||||
|
Instant parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00.0+0000", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(0L));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMergingOfMultipleParsers() {
|
||||||
|
//date_time has 2 parsers, date_time_no_millis has 4. Parsing with rounding should be able to use all of them
|
||||||
|
DateFormatter formatter = DateFormatter.forPattern("date_time||date_time_no_millis");
|
||||||
|
//date_time 2 parsers
|
||||||
|
Instant parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00.0+00:00", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(0L));
|
||||||
|
|
||||||
|
|
||||||
|
parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00.0+0000", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(0L));
|
||||||
|
|
||||||
|
//date_time_no_millis 4 parsers
|
||||||
|
parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00+00:00", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(999L));//defaulting millis
|
||||||
|
|
||||||
|
parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00+0000", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(999L));//defaulting millis
|
||||||
|
|
||||||
|
parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00UTC+00:00", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(999L));//defaulting millis
|
||||||
|
|
||||||
|
// this one is actually still using parser number 3. I don't see a combination to use parser number 4
|
||||||
|
parsed = formatter.toDateMathParser().parse("1970-01-01T00:00:00", () -> 0L, true, (ZoneId) null);
|
||||||
|
assertThat(parsed.toEpochMilli(), equalTo(999L));//defaulting millis
|
||||||
|
}
|
||||||
|
|
||||||
public void testOverridingLocaleOrZoneAndCompositeRoundUpParser() {
|
public void testOverridingLocaleOrZoneAndCompositeRoundUpParser() {
|
||||||
//the pattern has to be composite and the match should not be on the first one
|
//the pattern has to be composite and the match should not be on the first one
|
||||||
DateFormatter formatter = DateFormatter.forPattern("date||epoch_millis").withLocale(randomLocale(random()));
|
DateFormatter formatter = DateFormatter.forPattern("date||epoch_millis").withLocale(randomLocale(random()));
|
||||||
|
|
Loading…
Reference in New Issue