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

Add support for ordinal date values in AS::TimeZone.iso8601 #41779

Merged
merged 1 commit into from
Jun 28, 2021

Conversation

steventux
Copy link
Contributor

Summary

Date._iso8601 will attempt to parse certain values as ordinal date strings eg. '21087' is parsed as 28th March 2021.
ActiveSupport::TimeZone.iso8601 should provide similar support for ordinal values as Ruby stdlib in Date._iso8601.

Add support for values which parse as year and day of year eg. { year: 2021, yday: 87 } and attempt to generate a valid date with Date.ordinal. This will sanitize the :yday part of the parsed value for the corresponding year.

Other Information

See #41764 (comment) for suggestion which led to this PR.

@rails-bot
Copy link

rails-bot bot commented Jun 26, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@rails-bot rails-bot bot added the stale label Jun 26, 2021
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]

exception = assert_raises(ArgumentError) do
zone.iso8601("12936")
Copy link
Member

Choose a reason for hiding this comment

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

Rather than remove this it’d be good to see a test for what now happens when this value is parsed.

Copy link
Contributor Author

@steventux steventux Jun 28, 2021

Choose a reason for hiding this comment

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

@ghiculescu No problem, 12936 is another invalid value - actually coming from a real-world case that led me to make this PR. I can revert to using this value as the existing test will work, or test both this and 21367 as invalid ordinal values but that is sort of proving the same point twice.
I changed to 21367 as it was closer to the boundary of a valid/invalid ordinal - the 367 ending produces a yday date part of 367 which makes it invalid. Perhaps it would have been better to have left the original invalid value in place?

Copy link
Member

Choose a reason for hiding this comment

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

Nah that makes sense, thanks for the explanation.

@rails-bot rails-bot bot removed the stale label Jun 26, 2021
@ghiculescu
Copy link
Member

I think this needs a changelog entry.

@steventux steventux force-pushed the add-support-for-iso8601-dates branch from 5537522 to 6c08376 Compare June 28, 2021 15:32
A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
and `:yday` fragments returned from `Date._iso8601`.

As requested by [Andrew White](https://github.com/rails/rails/pull/41764#issuecomment-808863720)
Copy link
Member

Choose a reason for hiding this comment

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

I think you can remove this line. Better to focus on how it impacts Rails users. So maybe:

Suggested change
As requested by [Andrew White](https://github.com/rails/rails/pull/41764#issuecomment-808863720)
```ruby
twz = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].iso8601("21087")
twz.to_a[0, 6] == [0, 0, 0, 28, 03, 2021]
```

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ghiculescu Thank you for the suggestion - amended.

@steventux steventux force-pushed the add-support-for-iso8601-dates branch from 6c08376 to 1c5a236 Compare June 28, 2021 15:47
@ghiculescu ghiculescu added the ready PRs ready to merge label Jun 28, 2021
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]

twz = zone.iso8601("21087")
assert_equal [0, 0, 0, 28, 03, 2021], twz.to_a[0, 6]
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you change this to match the assertion style in other tests, e.g.

twz = zone.iso8601("21087")
assert_equal Time.utc(2021, 3, 28, 0, 0, 0), twz.time
assert_equal zone, twz.zone 

That way we ensure nothing funny happens to fractional seconds

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pixeltrix thanks for the review - amended.

Date._iso8601 will attempt to parse certain args as ordinal dates eg. '21087' => 2021-03-28. Add ActiveSupport::TimeZone.iso8601 support for these
ordinal values to be consistent with Date._iso8601 and raise ArgumentError where the day of year is invalid.
@steventux steventux force-pushed the add-support-for-iso8601-dates branch from 1c5a236 to 21ca4a4 Compare June 28, 2021 17:01
@pixeltrix pixeltrix merged commit 21243aa into rails:main Jun 28, 2021
@pixeltrix
Copy link
Contributor

@steventux thanks 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
activesupport ready PRs ready to merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants