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 {
|
||||
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);
|
||||
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,
|
||||
Consumer<DateTimeFormatterBuilder> roundupParserConsumer) {
|
||||
if (format.contains("||") == false) {
|
||||
List<DateTimeFormatter> roundUpParsers = new ArrayList<>();
|
||||
for (DateTimeFormatter parser : this.parsers) {
|
||||
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
|
||||
builder.append(this.parsers.get(0));
|
||||
builder.append(parser);
|
||||
roundupParserConsumer.accept(builder);
|
||||
return Arrays.asList(builder.toFormatter(locale()));
|
||||
roundUpParsers.add(builder.toFormatter(locale()));
|
||||
}
|
||||
return roundUpParsers;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,14 @@ import java.time.Instant;
|
|||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
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.function.LongSupplier;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
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 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() {
|
||||
//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()));
|
||||
|
|
Loading…
Reference in New Issue