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 iso8601 and rfc3339 parsing to timezones #28272

Merged
merged 4 commits into from Mar 3, 2017

Conversation

pixeltrix
Copy link
Contributor

Adds Time.rfc3339, ActiveSupport::TimeZone.rfc3339 and ActiveSupport::TimeZone.iso8601 plus rfc3339 aliases to xmlschema for consistency when dealing with RFC 3339 timestamps in a Rails application.

Previous to this you would have to do things like this to get RFC 3339 timestamps into a particular timezone, e.g:

"2000-01-01T00:00:00Z".in_time_zone("Hawaii")

Also this doesn't enforce strict compliance with RFC 3339 - invalid dates or missing components will return nil instead of raising and error. We already have ActiveSupport::TimeZone.parse and ActiveSupport::TimeZone.strptime so adding these methods seem a natural fit - especially when converting a large number of timestamps, e.g:

zone = Time.find_zone("Hawaii")
zone.rfc3339("2000-01-01T00:00:00Z")

Added rfc3339 aliases to xmlschema since DateTime has them and using time format names consistently within an application is better.

@pixeltrix pixeltrix force-pushed the add-iso8601-and-rfc3339-parsing branch from 416720f to 901be2e Compare March 3, 2017 20:32
@pixeltrix pixeltrix changed the title Add iso8601 and rfc3339 parsing Add iso8601 and rfc3339 parsing to timezones Mar 3, 2017
#
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
#
# If the the time or offset components are missing then an +ArgumentError+
Copy link
Member

Choose a reason for hiding this comment

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

There is an extra "the" here. 😊

# Time.zone = 'Hawaii' # => "Hawaii"
# Time.zone.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
# If the the time components are missing then they will be set to zero.
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

# Time.zone = 'Hawaii' # => "Hawaii"
# Time.zone.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
# If the the time or zone components are missing then an +ArgumentError+
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

@pixeltrix
Copy link
Contributor Author

@robin850 thanks - my eyes are getting old 👴

Previously there was no way to get a ISO 8601 timestamp into a specific
timezone without either using `parse` or chaining methods. The new method
allows parsing directly into the timezone, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.iso8601("1999-12-31T14:00:00Z")
    => Fri, 31 Dec 1999 14:00:00 HST -10:00

If the timestamp is a ISO 8601 date (YYYY-MM-DD) then the time is set
to midnight, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.iso8601("1999-12-31")
    => Fri, 31 Dec 1999 00:00:00 HST -10:00

This new method has stricter semantics than the current `parse` method
and will raise an `ArgumentError` instead of returning nil, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.iso8601("foobar")
    ArgumentError: invalid date
    >> Time.zone.parse("foobar")
    => nil
Previously there was no way to get a RFC 3339 timestamp
into a specific timezone without either using `parse` or
chaining methods. The new method allows parsing directly
into the timezone, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.rfc3339("1999-12-31T14:00:00Z")
    => Fri, 31 Dec 1999 14:00:00 HST -10:00

This new method has stricter semantics than the current
`parse` method and will raise an `ArgumentError`
instead of returning nil, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.rfc3339("foobar")
    ArgumentError: invalid date
    >> Time.zone.parse("foobar")
    => nil

It will also raise an `ArgumentError` when either the
time or offset components are missing, e.g:

    >> Time.zone = "Hawaii"
    => "Hawaii"
    >> Time.zone.rfc3339("1999-12-31")
    ArgumentError: invalid date
    >> Time.zone.rfc3339("1999-12-31T14:00:00")
    ArgumentError: invalid date
The `Time.xmlschema` and consequently its alias `iso8601` accepts
timestamps without a offset in contravention of the RFC 3339
standard. This method enforces that constraint and raises an
`ArgumentError` if it doesn't.
For naming consistency when using the RFC 3339 profile
of ISO 8601 in applications.
@pixeltrix pixeltrix force-pushed the add-iso8601-and-rfc3339-parsing branch from 6c63cfd to f0aeecd Compare March 3, 2017 21:53
@pixeltrix pixeltrix merged commit de17d9e into master Mar 3, 2017
@pixeltrix pixeltrix deleted the add-iso8601-and-rfc3339-parsing branch March 3, 2017 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants