Time Iso 8601 in Ruby

Converting UTC timestamp to ISO 8601 in Ruby

I think you're trying to trick us.

The input date to your question is the 25th of October, 2010, whilst the output is the 29th of October, 2010. Well played!

Continuing on this nit-picking thread: your times are also completely different and you're missing the seconds from the output time.

Now for the true answer.

A little factoid first though: the ISO 8601 output in Ruby is similar to the "Combined date and time" output from ISO 8601's Wikipedia page.

You've got a string and so you'll need to convert it into a Time object which you can do with to_time. Then it's simply a matter of calling iso8601 on that object to get the ISO 8601 version:

"2010-10-25 23:48:46 UTC".to_time.iso8601

The to_time method is courtesy of Rails, whilst the iso8601 is courtesy of Ruby's standard library.

Ruby check if datetime is a iso8601 and saving

I dont' quite understand your question. I am assuming that you want to check a DateTime string if it's a valid ISO8601 format date string or not. Correct me if I am wrong.

You can use the class methods Time.iso8601 and Date.iso8601. In order to use them, you need to require the 'date' and 'time' library from standard library. One caveat is, as you can see from the name, they are not predicate method (without ?), instead they raise an ArgumentError with "invalid date" message if the wrong string is being input. So, you need to add a begin rescue block. eg.

require 'time'

t = Time.now
time_string = t.rfc2822 # intentionally set to wrong format string
begin
Time.iso8601(time_string)
puts "Yeah, correct string"
rescue ArgumentError => e
puts e
puts "Nah, wrong string"

end

This is more verbose than your "date.iso8601 == date". But I am posting it because don't understand how your method works. To me date.iso8601 == date would always be false. Am I wrong?

UPDATE

As an answer for your updated question, it's best you can just store the DateTime normally in the database and call iso8601 method to get the ISO8601 string. For creating DateTime, you can just use Time.iso8601 to parse the input string into DateTime object.

UNIX time stamp to iso8601 in ruby


require 'time'
Time.at("1483050457000".to_i).iso8601
#=> "48965-12-30T12:16:40-08:00"

require 'time' is essential here. Without it you find that you only have access to Time's core methods. Run Time.instance_methods.sort to list them. By first executing require 'time' the following instance methods are added to the class Time: => [:httpdate, :iso8601, :rfc2822, :rfc822, :to_date, :to_datetime, :to_time, :xmlschema].

Is there a full implementation for ISO-8601 date parsing for Ruby?

Yes, but unfortunately it's in Ruby 1.9.

require "date"

Date.iso8601("2010-W32-5").strftime
#=> "2010-08-13"

I don't believe there are any implementations for Ruby 1.8.7 (or at least I couldn't find any). You could either try to upgrade to Ruby 1.9, which is pretty stable as of 1.9.2. Alternatively, you could try to parse the dates yourself.

Ruby's Parsing of iso8601 dates seems broken

According to the docs:

Creates a new Date object by parsing from a string according to some typical ISO 8601 formats.

Date.iso8601('2001-02-03')        #=> #<Date: 2001-02-03 ...>
Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>

Not really sure what "typical ISO 8601 formats" mean, as there should really be only one. I wouldn't say it's a bug though.

If you want strict parsing, then I'd look at Date#strptime.

How can I validate and parse an ISO 8601 timestamp with user's time zone?

I suggest that you simply split the assignment into two steps: validate the ISO8601 format first and if valid, parse it:

user_time_zone = 'America/Los_Angeles'
params = { when: '2016-04-01T01:01:01' }

begin
Time.iso8601(params[:when]) # raises ArgumentError if format invalid
rescue ArgumentError => e
puts "invalid time format"
return
end

Time.use_zone(user_time_zone) do
timestamp = Time.zone.parse(params[:when])
end


Related Topics



Leave a reply



Submit