Giter Site home page Giter Site logo

arnau / iso8601 Goto Github PK

View Code? Open in Web Editor NEW
75.0 5.0 16.0 522 KB

Ruby parser to work with ISO8601 dateTimes and durations — http://en.wikipedia.org/wiki/ISO_8601

License: MIT License

Ruby 99.40% Nix 0.60%
ruby datetime durations iso8601 interval date time

iso8601's Introduction

ISO8601

New maintainer wanted

Version 0.9.0 is not compatible with previous versions. Atoms and Durations changed their interface when treating base dates so it is only applied when computing the Atom length (e.g. #to_seconds). As a consequence, it is no longer possible to do operations like DateTime + Duration.

Version 1.0.0 will lock public interfaces.

Check the changelog if you are upgrading from an older version.

ISO8601 is a simple implementation of the ISO 8601 (Data elements and interchange formats — Information interchange — Representation of dates and times) standard.

Build status

Build Status Gem Version

Supported versions

  • MRI 2.5, 2.6, 2.7

Documentation

Check the rubydoc documentation. Or take a look to the implementation notes:

Testing

Install a Ruby version. E.g. you can install Ruby 2.7 with:

$ nix-shell

Then

$ bundle install
$ bundle exec rake

Contributing

Contributors

Please see CONTRIBUTING.md

License

Arnau Siches under the MIT License

iso8601's People

Contributors

alexdilley avatar arnau avatar dependabot-preview[bot] avatar dependabot[bot] avatar gitter-badger avatar kachick avatar nbeyer avatar njlynch avatar ollym avatar pelle avatar porras avatar tas50 avatar utkarsh2102 avatar walterbrebels avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

iso8601's Issues

Clean Duration

Clean Duration interface. And sanitise its arithmetics.

DateTime.new fails to parse YYYY-MM-DDThh:mmZ format

Following test case failed
expect { ISO8601::DateTime.new('2015-01-17T10:30Z') }.to_not raise_error
error
expected no Exception, got #<NoMethodError: undefined method div' for "Z":String> with backtrace:`
YYYY-MM-DDThh:mmZ seems to be the valid ISO8601 format

Problem with minute offsets when the time is only specified to the hour

Currently, DateTime raises an UnknownPattern error when parsing timezone offsets with the format YYYY-MM-DDThh+[hh]:[mm] or YYYY-MM-DDThh+[hh][mm]. I couldn't find anything on the ISO8601 wiki page that indicates those formats would be disallowed or invalid. Is this intentional or is it a bug?

2.1.5 :001 > ISO8601::DateTime.new("2015-04-13T20+00")
 => #<ISO8601::DateTime:0x007ffdfeab06e0 @original="2015-04-13T20+00", @date_time=#<DateTime: 2015-04-13T20:00:00+00:00 ((2457126j,72000s,0n),+0s,2299161j)>, @second=0.0>
2.1.5 :003 >   ISO8601::DateTime.new("2015-04-13T20+00:00")
ISO8601::Errors::UnknownPattern: Unknown pattern 20+00:00

Empty strings are not handled correctly

zendesk(dev)> ISO8601::DateTime.new("")
NoMethodError: undefined method `empty?' for nil:NilClass
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/iso8601-0.5.1/lib/iso8601/dateTime.rb:93:in `parse_date'
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/iso8601-0.5.1/lib/iso8601/dateTime.rb:72:in `parse'
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/iso8601-0.5.1/lib/iso8601/dateTime.rb:26:in `initialize'
    from (irb):2:in `new'
    from (irb):2
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:47:in `start'
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:8:in `start'
    from /opt/boxen/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.19/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:20:in `require'
    from script/rails:20:in `<main>'

should be raising a ISO8601::Errors::UnknownPattern exception.

Hash function has to be improved.

Current hash function of ISO8601::DateTime has some issues due to only looking at seconds and fraction seconds part and that causes following

2.1.5 :004 > ISO8601::DateTime.new('2014') == ISO8601::DateTime.new('2015')
 => true

There are many other cases which fall through this.

A possible fix I could see is
[self.to_time.to_f, self.class].hash
or even add little more variables to it.

Repeating intervals

Add support for repeating intervals

Rnn/<interval>
R/<interval>

Example: R5/2008-03-01T13:00:00Z/P1Y2M10DT2H30M

Clarification on to_date method of DateTime class

I would like to know what type of object to expect when we call to_date method on DateTime object.
I was hoping that will be ISO8601::Date object but seeing some different results.
For instance if I call new on Date object "ISO8601::Date.new('2014-05-02')" I can call weeks method on it and returns correct results but I do same with DateTime class and to_date method get an error

2.1.5 :001 > require 'iso8601'
 => true
2.1.5 :002 > ISO8601::Date.new('2014-W05').week
 => 5
2.1.5 :003 > ISO8601::DateTime.new('2014-05-02').to_date.week
NoMethodError: undefined method `week' for #<Date: 2014-05-02 ((2456780j,0s,0n),+0s,2299161j)>
    from (irb):3
    from /Users/DR029931/.rvm/rubies/ruby-2.1.5/bin/irb:11:in `<main>'

Just wanted some clarification for my understanding.

-00 and -00:00 are accepted as timezone

Based on iso8601 standard for UTC1 "−00:00" or "−00" are not valid formats but currently when we pass it to ISO8601::DateTime class these values are accepted and then get converted into +00:00.
Is this an issue or intended behaviour?

Converting ISO8601::DateTime back to a standard ::DateTime

The docs don't mention how to convert an ISO8601::DateTime back to a standard Rails ::DateTime (I was expecting something like #to_datetime)

Am I missing something obvious? :) Does ISO8601::DateTime quack so much like ::DateTime that I can use them interchangeably?

Thanks!

Weeks not supported in durations?

1.9.3p194 :009 > ISO8601::Duration.new('P1W1D')
ISO8601::Errors::UnknownPattern: The pattern “” is not allowed in this implementation of ISO8601.
    from /Users/joe/.rvm/gems/ruby-1.9.3-p194@ruby-duration/gems/iso8601-0.2/lib/iso8601/duration.rb:136:in `valid_pattern?'
    from /Users/joe/.rvm/gems/ruby-1.9.3-p194@ruby-duration/gems/iso8601-0.2/lib/iso8601/duration.rb:9:in `initialize'
    from (irb):9:in `new'
    from (irb):9
    from /Users/joe/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

Any particular reason for that?

Improve the +/- function of the ISO8601::DateTime

Currently there is an issue with the library if I try to use floating point calculations with the DateTime object due to format restructing fraction_second to precision of 2 it cases some errors
Example:

2.1.5 :001 > require 'iso8601'
 => true
2.1.5 :002 > date1 = ISO8601::DateTime.new('2014')
 => #<ISO8601::DateTime:0x007f91519fd7d0 @original="2014", @date_time=#<DateTime: 2014-01-01T00:00:00+00:00 ((2456659j,0s,0n),+0s,2299161j)>, @second=0.0>
2.1.5 :003 > date1 + 0.1 - 0.1
 => #<ISO8601::DateTime:0x007f91519c67f8 @original="2013-12-31T23:59:59.99+00:00", @date_time=#<DateTime: 2013-12-31T23:59:59+00:00 ((2456658j,86399s,990000000n),+0s,2299161j)>, @second=59.99>
2.1.5 :004 > date1 == (date1 + 0.1 - 0.1)
 => false
2.1.5 :005 >

I am thinking since we allow fraction_second in @seconds for the class if use same from arithmetic calculations that will fix the issue with such cases. OR
We can say strictly that in library we only support fraction_second upto 2 digits and then fix seconds to have the same precision.

Time intervals

Add support for time intervals:

<start>/<end>
<start>/<duration>
<duration>/<end>

Examples:

Start and end, such as "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
Start and duration, such as "2007-03-01T13:00:00Z/P1Y2M10DT2H30M"
Duration and end, such as "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"

Error working with durations

This should work... right? I tried various permutations but they all yield this missing #round error

a = ISO8601::DateTime.new('2014-05-06T10:11:12.5')
dur = ISO8601::Duration.new('P2M')
offset = a + dur
NoMethodError: undefined method `round' for #<ISO8601::Duration:0x007ffa65502cd0>
        from /Users/peterabramowitsch/.rvm/gems/ruby-2.1.1/gems/iso8601-0.8.5/lib/iso8601/date_time.rb:33:in `+'
        from (irb):20
        from /Users/peterabramowitsch/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'

Add time interval `#union`

Add TimeInterval#union to merge two intervals. And consider if they need to intersect or not. If not, the behaviour could be unexpected (?)

Time#hash not working

In theory this should be fine, but for some reason def_delegator is causing the hash method to fail.

ISO8601::Time.new('T10:30').to_time.hash == ISO8601::Time.new('T10:30').to_time.hash # => true
ISO8601::Time.new('T10:30').hash == ISO8601::Time.new('T10:30').hash # => false

Not sure why...

DateTime doen't support timezone offset format ±[hh][mm]

Currently, DateTime has an issue parsing timezone offset format ±[hh][mm].

irb(main):036:0> ISO8601::DateTime.new("2015-03-19T20:35:58Z")
=> #<ISO8601::DateTime:0x007fa75bb4f820 @original="2015-03-19T20:35:58Z", @date_time=#<DateTime: 2015-03-19T20:35:58+00:00 ((2457101j,74158s,0n),+0s,2299161j)>, @second=58.0>
irb(main):037:0> ISO8601::DateTime.new("2015-03-19T20:35:58+00")
=> #<ISO8601::DateTime:0x007fa75bb3eed0 @original="2015-03-19T20:35:58+00", @date_time=#<DateTime: 2015-03-19T20:35:58+00:00 ((2457101j,74158s,0n),+0s,2299161j)>, @second=58.0>
irb(main):038:0> ISO8601::DateTime.new("2015-03-19T20:35:58+00:00")
=> #<ISO8601::DateTime:0x007fa75bb2e030 @original="2015-03-19T20:35:58+00:00", @date_time=#<DateTime: 2015-03-19T20:35:58+00:00 ((2457101j,74158s,0n),+0s,2299161j)>, @second=58.0>
irb(main):039:0> ISO8601::DateTime.new("2015-03-19T20:35:58+0000")
ISO8601::Errors::UnknownPattern: Unknown pattern 20:35:58+0000
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/time.rb:123:in `atomize'
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/time.rb:36:in `initialize'
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/date_time.rb:128:in `new'
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/date_time.rb:128:in `parse_time'
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/date_time.rb:99:in `parse'
    from /Users/sb012532/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/iso8601-0.8.5/lib/iso8601/date_time.rb:25:in `initialize'
    from (irb):39:in `new'
    from (irb):39
    from /Users/sb012532/.rbenv/versions/2.2.1/bin/irb:11:in `<main>'

I would be willing to submit a solution once I have time.

TimeInterval reads invalid length from non-UTC strings

Hi, I noticed that TimeInterval reads invalid length from non-UTC strings since 0.10.0.

diff --git a/spec/iso8601/time_interval_spec.rb b/spec/iso8601/time_interval_spec.rb
index 00b97ee..75b5a19 100644
--- a/spec/iso8601/time_interval_spec.rb
+++ b/spec/iso8601/time_interval_spec.rb
@@ -133,10 +133,12 @@ RSpec.describe ISO8601::TimeInterval do
       pattern = 'PT1H/2010-05-09T10:30:00Z'
       pattern2 = '2010-05-09T11:30:00Z/PT1H'
       pattern3 = '2010-05-09T11:30:00Z/2010-05-09T12:30:00Z'
+      pattern4 = '2010-05-09T11:30:00+09:00/PT1H'
 
       expect(ISO8601::TimeInterval.parse(pattern).to_f).to eq(hour)
       expect(ISO8601::TimeInterval.parse(pattern2).to_f).to eq(hour)
       expect(ISO8601::TimeInterval.parse(pattern3).to_f).to eq(hour)
+      expect(ISO8601::TimeInterval.parse(pattern4).to_f).to eq(hour)
     end
 
     it "should be 0" do

gives

Failures:

  1) ISO8601::TimeInterval#to_f should calculate the size of time interval
     Failure/Error: expect(ISO8601::TimeInterval.parse(pattern4).to_f).to eq(hour)

       expected: 3600.0
            got: 36000.0

       (compared using ==)
     # ./spec/iso8601/time_interval_spec.rb:141:in `block (3 levels) in <top (required)>'

New maintainer needed

This project is close to my heart but sadly I'm no longer able to properly maintain and evolve it the way it deserves. It would be great if someone could take over.

Incorrect start date on TimeIntervals anchored in the month of December

Some cases:

ISO8601::TimeInterval.new("P1Y/2017-12-06T18:30:00Z").first.to_s
# => "2015-12-07T18:30:00+00:00" expected: "2017-12-06T18:30:00+00:00"
ISO8601::TimeInterval.new("P2M/2017-12-06T18:30:00Z").first.to_s
# => "2017-10-05T18:30:00+00:00" expected: "2017-10-06T18:30:00+00:00"
ISO8601::TimeInterval.new("P3D/2017-12-06T18:30:00Z").first.to_s
# => "2016-12-03T18:30:00+00:00" expected: "2017-12-03T18:30:00+00:00"

ISO8601::TimeInterval.new("P1Y/2017-11-06T18:30:00Z").first.to_s
# => "2016-11-06T18:30:00+00:00" correct
ISO8601::TimeInterval.new("P2M/2017-11-06T18:30:00Z").first.to_s
# => "2017-09-06T18:30:00+00:00" correct
ISO8601::TimeInterval.new("P3D/2017-11-06T18:30:00Z").first.to_s
# => "2017-11-03T18:30:00+00:00" correct

I have traced the problem to ISO8601::Months#to_seconds (called from ISO8601::DateInterval#to_seconds, which in turn is called from ISO8601::TimeInterval#tuple_by_end).

The root of the problem lies in incorrect values returned by ISO8601::Months#zero_calculate and ISO8601::Months#calculate (called from ISO8601::Months#to_seconds):

I calculated the return value of ISO8601::Months#zero_calculate with base dates from every month and found it returns 0.0 for all but December, in which case it returns 31536000.0 (1 year). I'm confused why this method is necessary: if the months atom is zero, then my gut feeling is that to_seconds should return zero.

There's a lot of logic in ISO8601::Months#calculate, and I did not have time to inspect it. It seems that the value returned by this calculation is off by a day when the base month is December.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.