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

Extend the date rounding logic to be conditional #89693

Merged
merged 9 commits into from
Sep 5, 2022

Conversation

pgomulka
Copy link
Contributor

Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfYear, ClockHourOfAMPM and HourOfAmPM

closes #89096
closes #58986

Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfYear, ClockHourOfAMPM and HourOfAmPM

closes elastic#89096
closes elastic#58986
@pgomulka pgomulka added >bug :Core/Infra/Core Core issues without another label v8.5.0 v7.17.7 labels Aug 29, 2022
@pgomulka pgomulka self-assigned this Aug 29, 2022
@elasticsearchmachine elasticsearchmachine added the Team:Core/Infra Meta label for core/infra team label Aug 29, 2022
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@elasticsearchmachine
Copy link
Collaborator

Hi @pgomulka, I've created a changelog YAML for you.

Copy link
Contributor

@grcevski grcevski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I left one small remark about potential performance issue.

* without this logic, the rounding would result in a conflict as HOUR_OF_DAY would be missing, but CLOCK_HOUR_OF_AMPM would be provided
*/
private static final BiConsumer<DateTimeFormatterBuilder, DateTimeFormatter> DEFAULT_ROUND_UP = (builder, parser) -> {
if (parser.toString().contains(ChronoField.DAY_OF_YEAR.toString())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small comment here, since we might call this frequently enough and we don't know the cost of parser.toString(), do you mind extracting the parsed value into a local for the if conditionals?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea

Copy link
Contributor

@ChrisHegarty ChrisHegarty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pgomulka
Copy link
Contributor Author

pgomulka commented Sep 1, 2022

I just realised that we possibly want to add a week based year defaulting too. So that we support YYYY'W'ww[e] ([ ] means parse optional day of week). It might be a bit artificial though, because I don't think [] syntax is commonly used (I might be mistaken..) and we don't have a named formatter with day of week within startOptional/endOptional

assuming [] is rare and thus the only optional fields that could conflict are month of year and day of month, this logic could be simplified to just

 if(parserAsString.contains(ChronoField.MONTH_OF_YEAR.toString()) ){
          builder.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1L);
      }
      if(parserAsString.contains(ChronoField.DAY_OF_MONTH.toString()) ){
          builder.parseDefaulting(ChronoField.DAY_OF_MONTH, 1L);
      }

let me know what you think

@pgomulka
Copy link
Contributor Author

pgomulka commented Sep 1, 2022

@elasticmachine update branch

@grcevski
Copy link
Contributor

grcevski commented Sep 1, 2022

I just realised that we possibly want to add a week based year defaulting too. So that we support YYYY'W'ww[e] ([ ] means parse optional day of week). It might be a bit artificial though, because I don't think [] syntax is commonly used (I might be mistaken..) and we don't have a named formatter with day of week within startOptional/endOptional

assuming [] is rare and thus the only optional fields that could conflict are month of year and day of month, this logic could be simplified to just

 if(parserAsString.contains(ChronoField.MONTH_OF_YEAR.toString()) ){
          builder.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1L);
      }
      if(parserAsString.contains(ChronoField.DAY_OF_MONTH.toString()) ){
          builder.parseDefaulting(ChronoField.DAY_OF_MONTH, 1L);
      }

let me know what you think

I think that's a fair assumption. We don't have to make this more complicated at this point. I'd just put a comment that we don't handle the 'optional day of week' format, but adding day of month and month of year sound great!

@grcevski
Copy link
Contributor

grcevski commented Sep 1, 2022

Since we are backporting to 7.17, can we please backport to 8.4.1 too, it's the current release.

@pgomulka pgomulka added the v8.4.1 label Sep 1, 2022
@pgomulka pgomulka merged commit 8e517da into elastic:main Sep 5, 2022
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Sep 5, 2022
Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfYear, ClockHourOfAMPM and HourOfAmPM

closes elastic#89096
closes elastic#58986
pgomulka added a commit that referenced this pull request Sep 5, 2022
Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfMonth, MonthOfYear, ClockHourOfAMPM and HourOfAmPM

closes #89096
closes #58986
backports #89693
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Sep 5, 2022
Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfYear, ClockHourOfAMPM and HourOfAmPM

closes elastic#89096
closes elastic#58986
pgomulka added a commit that referenced this pull request Sep 5, 2022
Date rounding logic should take into account the fields that will be
parsed be a parser. If a parser has a DayOfYear field, the rounding logic
should not try to default DayOfMonth as it will conflict with DayOfYear

However the DateTimeFormatter does not have a public method to return
information of fields that will be parsed. The hacky workaround is
to rely on toString() implementation that will return a field info when
it was defined with textual pattern.

This commits introduced conditional logic for DayOfYear, ClockHourOfAMPM and HourOfAmPM

closes #89096
closes #58986
backports #89693
pgomulka added a commit that referenced this pull request Oct 4, 2022
in #89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes #90187
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Oct 4, 2022
in elastic#89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes elastic#90187

(cherry picked from commit 3f3a95e)
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Oct 4, 2022
in elastic#89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes elastic#90187

(cherry picked from commit 3f3a95e)

# Conflicts:
#	server/src/test/java/org/elasticsearch/common/time/DateFormattersTests.java
pgomulka added a commit that referenced this pull request Oct 4, 2022
in #89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes #90187

backports #90458
pgomulka added a commit that referenced this pull request Oct 4, 2022
* Fix date rounding for date math parsing (#90458)

in #89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes #90187
backport(#90458)
(cherry picked from commit 3f3a95e)
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Oct 13, 2022
…tic#90633)

in elastic#89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes elastic#90187

backports elastic#90458
pgomulka added a commit that referenced this pull request Oct 13, 2022
in #89693 the rounding logic was only applied when a field was present on a pattern. This is incorrect as for dates like "2020" we want to default to "2020-01-01T23:59:59.999..." when rounding is enabled.

This commit always applies monthOfYear or dayofMonth defaulting (when rounding enabled) except when the dayOfYear is set
closes #90187

backports #90458
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Core/Infra/Core Core issues without another label Team:Core/Infra Meta label for core/infra team v7.17.7 v8.4.1 v8.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug in JavaDateFormatter when using DOY Unable to parse certain dates due to AM/PM issues
5 participants