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

Time::iso8601 does not implement the ISO8601 standard protocol #193

Open
mgartner opened this issue Mar 5, 2013 · 14 comments
Open

Time::iso8601 does not implement the ISO8601 standard protocol #193

mgartner opened this issue Mar 5, 2013 · 14 comments

Comments

@mgartner
Copy link

mgartner commented Mar 5, 2013

It only supports using "Z" as the timezone. It should support other timezone types. For example

Time.iso8601("2012-05-31T19:41:33+00:00") # returns nil
@jimsynz
Copy link
Contributor

jimsynz commented Mar 5, 2013

ugh. that sucks.

@jimsynz
Copy link
Contributor

jimsynz commented Mar 5, 2013

I guess we can take a look at ActiveSupport, since it does it?

James Harton
sociable.co.nz
@jamesotron
+64226803869

On Tuesday, 5 March 2013 at 2:19 PM, Marcus Gartner wrote:

Yeah, tell me about it. What's a bigger bitch is that the only reliable to way to parse a string like this is using the ISO8601DateFormatter cocoapod, but of course that crashes in iOS 5.


Reply to this email directly or view it on GitHub (#193 (comment)).

@bensie
Copy link
Contributor

bensie commented Mar 5, 2013

It's actually part of stdlib -- you have to require 'time' in MRI to get that method.

@jimsynz
Copy link
Contributor

jimsynz commented Mar 5, 2013

From time.rb:

  def xmlschema(fraction_digits=0)
    fraction_digits = fraction_digits.to_i
    s = strftime("%FT%T")
    if fraction_digits > 0
      s << strftime(".%#{fraction_digits}N")
    end
    s << (utc? ? 'Z' : strftime("%:z"))
  end
  alias iso8601 xmlschema

@jimsynz
Copy link
Contributor

jimsynz commented Mar 5, 2013

Also, from Rubinius, which is more useful maybe:

    #
    # Parses +date+ as dateTime defined by XML Schema and converts it to a Time
    # object.  The format is restricted version of the format defined by ISO
    # 8601.
    #
    # ArgumentError is raised if +date+ is not compliant with the format or Time
    # class cannot represent specified date.
    #
    # See #xmlschema for more information on this format.
    #
    # time library should be required to use this method as follows.
    #
    #     require 'time'
    #
    def xmlschema(date)
      if /\A\s*
          (-?\d+)-(\d\d)-(\d\d)
          T
          (\d\d):(\d\d):(\d\d)
          (\.\d+)?
          (Z|[+-]\d\d:\d\d)?
          \s*\z/ix =~ date
        year = $1.to_i
        mon = $2.to_i
        day = $3.to_i
        hour = $4.to_i
        min = $5.to_i
        sec = $6.to_i
        usec = 0
        if $7
          usec = Rational($7) * 1000000
        end
        if $8
          zone = $8
          year, mon, day, hour, min, sec =
            apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
          self.utc(year, mon, day, hour, min, sec, usec)
        else
          self.local(year, mon, day, hour, min, sec, usec)
        end
      else
        raise ArgumentError.new("invalid date: #{date.inspect}")
      end
    end
    alias iso8601 xmlschema

@bogardon
Copy link
Contributor

according to this from here, we can use "yyyy-MM-dd'T'HH:mm:ssZZZZZ" to parse op's original example.

i'm just going to make a simple PR that accounts for that particular case. i suppose later on we can cache a ton of date formatters that account for all possible ISO8601 combinations?

@joshsmith
Copy link

Odd, this is not parsing the following string, either: 2013-10-16T07:00:00-07:00, though it fits OP's original example.

@mgartner
Copy link
Author

@joshsmith #255 added a method Time::iso8601_with_timezone which should be used for the format you gave. It works for me running BubbleWrap v1.4.0.

(main)> Time.iso8601_with_timezone("2013-10-16T07:00:00-07:00")
=> 2013-10-16 07:00:00 -0700

@joshsmith
Copy link

@mgartner Whoops, I missed that! Saw the first spec and missed the second. Thanks!

@joshsmith
Copy link

This still does not act as expected, though it's perhaps user error again. Right now when we use Time::iso8601_with_timezone it does not use the correct timezone for me, and the times end up formatting in the local time for the device (tested on simulators/devices in NYC and San Diego).

@markgk629
Copy link

It doesn't support fractional digits.

e.g.
MRI returns

2.1.0p0 :007 > Time.iso8601('2014-02-17T02:50:22.020')
 => 2014-02-17 02:50:22 +1100

BubbleWrap 1.4 returns

(main)> Time.iso8601('2014-02-17T02:50:22.020')
=> nil

@bogardon
Copy link
Contributor

just look up the right date formats to use here: http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns

@speedmax
Copy link

decimal fraction is part of ISO8601 standard http://dotat.at/tmp/ISO_8601-2004_E.pdf

It's supported in

  • Javascript: Date.parse("2014-02-17T02:50:22.020") preserves the fraction of a second part
  • Ruby: require 'time'; Time.parse("2014-02-17T02:50:22.020") ignores faction of a second in Standard Lib, but it doesn't blow up.
  • Java: Joda's IsoDateTimeFormat supports three digit fraction of second

I suggest Bubblewrap to implement Ruby 2.1's behavior

@Bodacious
Copy link

Any update on this? I've just hit the same bug last week ><

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

No branches or pull requests

8 participants