Ruby check if datetime is a iso8601 and saving
Asked Answered
S

2

5

I need to check if a DateTime is in a valid ISO8601 format. Like: #iso8601?

I checked if ruby has a specific method but I haven't found any. Currently I'm using date.iso8601 == date to check this. Is there a good way to do this?

EDIT

Explaining my environment, and changing the scope of the question.

So, my project will use the js api FullCalendar, that's why i need a iso8601 string format. And I wondered what it's better or the correct way, save the date in the database in the correct format, or let the ActiveRecord do their job and manipulate it on just when I require the time information.

Subdivide answered 25/7, 2015 at 14:6 Comment(3)
I cant think of any better, this is clean, otherwise you will be monkey patching rails.. :)Indicator
Thanks for the fast answer Adam. So I'll keep this. And thanks for the edit Yu, my english skills are in progress.Subdivide
This is my first question in SO :)Subdivide
M
8

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.

Monterrey answered 25/7, 2015 at 14:36 Comment(4)
Hey, thanks for answering. I think '#iso8601' can parse any valid time/datetime string, so i think that 'Time.iso8601(time_string)' would be always true, since 'time_string' is a valid time string, just in the unwanted format. What i want is check if a DateTime/Time is on a iso8601 format.Subdivide
Have you tested the code in irb. I've tested the above code with ruby 2 and it executed puts in the rescue block. Time.iso8601 parse only valid iso8601 strings, not other strings, not even other valid datetime string. That behaviour is for Date.parse method. Also I don't understand what do you mean by DateTime/Time is on a iso8601 format? In ruby a Time object is just a time, it doesn't have a format. Formats are just representation of that time object.Monterrey
Here is an excellent blog post by Avdi Grimm on this matter. Hope this helps.Monterrey
Oh, i understand how Time works on ruby now. You're right, my method goes always be false. So it's quite useless this checking, right? I'm going edit my question to explain the environment that i have.Subdivide
B
0

Ruby 3.1:

begin
  invalid_date = '1970-01-32'
  Date.iso8601(invalid_date)
rescue Date::Error
  puts 'The date is invalid'
end

Rails 6.1:

Given the attribute has the type of date in the underlying database, you will not be able to set it to the invalid value. The following test (written in RSpec) passes:

specify 'Rails ignores invalid date' do
  invalid_date = '1970-01-32'
  invoice = Invoice.new

  invoice.date = invalid_date

  expect(invoice.date).to be nil
end

P.S. It's not fully clear whether you needed to make it work with Rails or without so there are solutions for both cases.

Brinkmanship answered 16/1, 2022 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.