Date & time validation

Hi all,

I am looking for an easy way to validate date and time values in a
script I have written.

The script takes values from a large file containing various data sets,
some dates and some times. I need to validate these dates and time
values once I have loaded them into a variable and I was thinking of
doing this through an a date check and time check object for example:

date1 = field[2]
date1 = dateCheck(date1) if date1 != “”

date2 = field[23]
date2 = dateCheck(date2) if date2 != “”

time = field[24]
time = timeCheck(time) if time != “”

def dateCheck(dateData)
I need some code to check what ever is in this string and check for a
valid date of yyyy/mm/dd. The data being checked can be anything, so
I need to know does it match the date format of yyyy/mm/dd, if so return
true otherwise return an empty string
end

def timeCheck(timeData)
similar idea with the time I need to check the data is hh:mm:ss
otherwise return an empty string.
end

Any ideas on how to do this? I was looking a the docs for date and I am
struggling to make head way at this stage.

Thanks in advance!

2009/9/1 Ne Scripter [email protected]:

date1 = field[2]
valid date of yyyy/mm/dd. The data being checked can be anything, so

Any ideas on how to do this? I was looking a the docs for date and I am
struggling to make head way at this stage.

Thanks in advance!

Just parse it into a Time instance:

15:32:29 ~$ irb19 -r time
Ruby version 1.9.1
irb(main):001:0> Time.parse ‘2009/01/02’
=> 2009-01-02 00:00:00 +0100
irb(main):002:0> Time.parse ‘2009/20/02’
ArgumentError: argument out of range
from /opt/lib/ruby19/1.9.1/time.rb:202:in local' from /opt/lib/ruby19/1.9.1/time.rb:202:inmake_time’
from /opt/lib/ruby19/1.9.1/time.rb:261:in parse' from (irb):2 from /opt/bin/irb19:12:in
irb(main):003:0>

Cheers

robert

Robert,

I understand what you are doing here and I have looked at using this
already however if I have a string 2009/09/01 12:22:36 it will be
returned as true because the date format is correct, the string above
will in fact be invalid because only a field consisting of yyyy/mm/dd is
valid.

Many thanks

Stuart

Robert K. wrote:

2009/9/1 Ne Scripter [email protected]:

date1 = field[2]
valid � �date of yyyy/mm/dd. The data being checked can be anything, so

Any ideas on how to do this? I was looking a the docs for date and I am
struggling to make head way at this stage.

Thanks in advance!

Just parse it into a Time instance:

15:32:29 ~$ irb19 -r time
Ruby version 1.9.1
irb(main):001:0> Time.parse ‘2009/01/02’
=> 2009-01-02 00:00:00 +0100
irb(main):002:0> Time.parse ‘2009/20/02’
ArgumentError: argument out of range
from /opt/lib/ruby19/1.9.1/time.rb:202:in local' from /opt/lib/ruby19/1.9.1/time.rb:202:inmake_time’
from /opt/lib/ruby19/1.9.1/time.rb:261:in parse' from (irb):2 from /opt/bin/irb19:12:in
irb(main):003:0>

Cheers

robert

Max W. wrote:

date = (string =~ /^\d{4}/\d{2}/\d{2}$/) &&

Beware: use

date = (string =~ /\A\d{4}/\d{2}/\d{2}\z/) …

or else malicious inputs may be able to bypass your validation. (They
might not be able to bypass Date.strptime in this particular instance,
but still you ought to validate correctly)

You could run it through a rough regex match first and then Date parse
it using strptime.

date = (string =~ /^\d{4}/\d{2}/\d{2}$/) &&
(Date.strptime(string,"%Y/%m/%d"))

2009/9/1 Brian C. [email protected]:

Max W. wrote:

date = (string =~ /^\d{4}/\d{2}/\d{2}$/) &&

Beware: use

date = (string =~ /\A\d{4}/\d{2}/\d{2}\z/) …

or else malicious inputs may be able to bypass your validation. (They
might not be able to bypass Date.strptime in this particular instance,
but still you ought to validate correctly)

Then you can do:

16:48:53 ~$ irb19 -r date
Ruby version 1.9.1
irb(main):001:0> %w{2009/10/11 2009/10/44}.each do |s|
irb(main):002:1* p s
irb(main):003:1> date = %r{\A(\d{4})/(\d{2})/(\d{2})\z} =~ s &&
Date.new($1.to_i, $2.to_i, $3.to_i)
irb(main):004:1> end
“2009/10/11”
“2009/10/44”
ArgumentError: invalid date
from /opt/lib/ruby19/1.9.1/date.rb:809:in civil' from (irb):6:inblock in irb_binding’
from (irb):4:in each' from (irb):4 from /opt/bin/irb19:12:in
irb(main):005:0>

Cheers

robert

Thanks all for the responses. I am still hitting a bit of a block with
this, initially I want to check if a date matches this criteria, then if
not do some of the processes that have been suggested.

I need to say
if date = yyyy/mm/dd
puts date
else
validate date
end

How would I do this? Sorry for so many questions, I am struggling to get
my head around the date libraries

Many thanks

Robert K. wrote:

2009/9/1 Brian C. [email protected]:

Max W. wrote:

date = (string =~ /^\d{4}/\d{2}/\d{2}$/) &&

Beware: use

date = (string =~ /\A\d{4}/\d{2}/\d{2}\z/) …

or else malicious inputs may be able to bypass your validation. (They
might not be able to bypass Date.strptime in this particular instance,
but still you ought to validate correctly)

Then you can do:

16:48:53 ~$ irb19 -r date
Ruby version 1.9.1
irb(main):001:0> %w{2009/10/11 2009/10/44}.each do |s|
irb(main):002:1* p s
irb(main):003:1> date = %r{\A(\d{4})/(\d{2})/(\d{2})\z} =~ s &&
Date.new($1.to_i, $2.to_i, $3.to_i)
irb(main):004:1> end
“2009/10/11”
“2009/10/44”
ArgumentError: invalid date
from /opt/lib/ruby19/1.9.1/date.rb:809:in civil' from (irb):6:inblock in irb_binding’
from (irb):4:in each' from (irb):4 from /opt/bin/irb19:12:in
irb(main):005:0>

Cheers

robert

Just an update of where I am. This is what I have

if date =~ (/\d{4}/\d{2}/\d{2}/)
puts date
else
date = (Date.strptime(date, “%Y/%m/%d”))
end

This works to an extent but does not deal with a string which contains a
valid date but still invalid data like so

2009/09/07 12:12:12

This would be passed as valid when it is not only a string containing
yyyy/mm/dd.

Any ideas?

Thanks a lot

Ne Scripter wrote:

Thanks all for the responses. I am still hitting a bit of a block with
this, initially I want to check if a date matches this criteria, then if
not do some of the processes that have been suggested.

I need to say
if date = yyyy/mm/dd
puts date
else
validate date
end

How would I do this? Sorry for so many questions, I am struggling to get
my head around the date libraries

Many thanks

Robert K. wrote:

2009/9/1 Brian C. [email protected]:

Max W. wrote:

date = (string =~ /^\d{4}/\d{2}/\d{2}$/) &&

Beware: use

date = (string =~ /\A\d{4}/\d{2}/\d{2}\z/) …

or else malicious inputs may be able to bypass your validation. (They
might not be able to bypass Date.strptime in this particular instance,
but still you ought to validate correctly)

Then you can do:

16:48:53 ~$ irb19 -r date
Ruby version 1.9.1
irb(main):001:0> %w{2009/10/11 2009/10/44}.each do |s|
irb(main):002:1* p s
irb(main):003:1> date = %r{\A(\d{4})/(\d{2})/(\d{2})\z} =~ s &&
Date.new($1.to_i, $2.to_i, $3.to_i)
irb(main):004:1> end
“2009/10/11”
“2009/10/44”
ArgumentError: invalid date
from /opt/lib/ruby19/1.9.1/date.rb:809:in civil' from (irb):6:inblock in irb_binding’
from (irb):4:in each' from (irb):4 from /opt/bin/irb19:12:in
irb(main):005:0>

Cheers

robert

Ne Scripter wrote:

Just an update of where I am. This is what I have

if date =~ (/\d{4}/\d{2}/\d{2}/)
puts date
else
date = (Date.strptime(date, “%Y/%m/%d”))
end

This works to an extent but does not deal with a string which contains a
valid date but still invalid data like so

2009/09/07 12:12:12

This would be passed as valid when it is not only a string containing
yyyy/mm/dd.

Any ideas?

Thanks a lot

Look at the regex’s in all the following examples. How do they differ
from your regex?

Robert K. wrote:

2009/9/1 Brian C. [email protected]:

Max W. wrote:

/^\d{4}/\d{2}/\d{2}$/)

Beware: use

/\A\d{4}/\d{2}/\d{2}\z/

%r{\A(\d{4})/(\d{2})/(\d{2})\z}


.
.
.
.
.
.

Ne Scripter wrote:

Just an update of where I am. This is what I have

if date =~ (/\d{4}/\d{2}/\d{2}/)
puts date
else
date = (Date.strptime(date, “%Y/%m/%d”))
end

This works to an extent but does not deal with a string which contains a
valid date but still invalid data like so

2009/09/07 12:12:12

This would be passed as valid when it is not only a string containing
yyyy/mm/dd.

Ok, to summarize to see if I’ve got it right:

 blah 2009/09/07 blah     # <-- is what we want to accept
 blah 2009/09/07 12:00:00 blah # <-- is what we want to reject

%r#\d{4}/\d{2}/\d{2}# matches a date but gives a false positive for
dates followed by time.

You could filter out lines that have date followed by time using
something like:

next if %r#\d{4}/\d{2}/\d{2}\s+\d{2}:\d{2}:\d{2}#

then capture any that make it past that test with a regular date regex.

Or, you can combine the test and capture in one regex pattern using
look-ahead…

%r#(\d{4}/\d{2}/\d{2})\s+(?!\d{2}:\d{2}:\d{2})# =~ 'blah 2009/01/01 

blah’ # => 5
%r#(\d{4}/\d{2}/\d{2})\s+(?!\d{2}:\d{2}:\d{2})# =~ ‘blah 2009/01/01
12:00:00 blah’ # => nil

The first line successfully matches “text date text”.
The second line rejects “text date time text”.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs