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:in
make_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:in
make_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:in
block 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:in
block 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:in
block 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”.