Need to parse string to Date safely

I can have the date format as below :

“01/05/2014”
“02/04/2014 10:00”
“02/04/2014 10:00:23”

If I do only,

DateTime.strptime(date_string, “%d/%m/%Y %H:%M:%S”) , I would get the
argument error, when date_string will not be having the exact format
“%d/%m/%Y %H:%M:%S”.

What is the correct way to handle this using Date::strptime. I
wouldn’t use Date::parse.

I’ve used nested rescue blocks before:

begin
DateTime.strptime(date_string, “%d/%m/%Y %H:%M:%S”)
rescue ArgumentError
begin
DateTime.strptime(date_string, “%d/%m/%Y %H:%M”)
rescue ArgumentError
begin

It feels clunky but it works, and it can be made more elegant by turning
it into a loop.

You could also use a case with regexes.

  • A

On 14-03-18, 6:30, Arup R. wrote:

“%d/%m/%Y %H:%M:%S”.

What is the correct way to handle this using Date::strptime. I
wouldn’t use Date::parse.

How do you mean “safely”? Do you mean to accept strictly those 3
formats?

One way is to add the missing :00 on the string before parsing it,
something like this:

 "12/03/2014 12:34".gsub!(/\b(\d{2}:\d{2})\b/, "\1:00")

Another way is to use rescue and run a list of valid matching patterns:

 require 'time'
 def parse_time(t)
   patterns ||= ["%d/%m/%Y %H:%M:%S", "%d/%m/%Y %H:%M", "%d/%m/%Y"]
   Time.strptime(t, patterns.shift)
 rescue ArgumentError => e
   patterns.any? ? retry : raise(e)
 end

Andrew V.

Andrew V. wrote in post #1140308:

Do you mean to accept strictly those 3
formats?

Yes. :slight_smile:

Hum… This is a good trick to solve this. It means I need to write all
possible format in the array.

Another way is to use rescue and run a list of valid matching patterns:

 require 'time'
 def parse_time(t)
   patterns ||= ["%d/%m/%Y %H:%M:%S", "%d/%m/%Y %H:%M", "%d/%m/%Y"]
   Time.strptime(t, patterns.shift)
 rescue ArgumentError => e
   patterns.any? ? retry : raise(e)
 end

Andrew V.

Alex C. wrote in post #1140306:

I’ve used nested rescue blocks before:

Nice idea too :slight_smile:

You could also use a case with regexes.

  • A

Andrew V. wrote in post #1140308:

On 14-03-18, 6:30, Arup R. wrote:
require ‘time’
def parse_time(t)
patterns ||= ["%d/%m/%Y %H:%M:%S", “%d/%m/%Y %H:%M”, “%d/%m/%Y”]

I think it should be DateTime.strptime(t, patterns.shift)… Right ?

   Time.strptime(t, patterns.shift)
 rescue ArgumentError => e
   patterns.any? ? retry : raise(e)
 end

Andrew V.