mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-25 07:16:41 +00:00
added compile_set method to get expressions and combine date and datetime expressions to allow a date string to parse when type is datetime
made internal methods private
This commit is contained in:
parent
85ac2bfc69
commit
7500781887
@ -83,15 +83,15 @@ module ValidatesTimeliness
|
|||||||
]
|
]
|
||||||
|
|
||||||
@@datetime_formats = [
|
@@datetime_formats = [
|
||||||
'yyyy-mm-dd hh:nn:ss.u',
|
|
||||||
'yyyy-mm-dd hh:nn:ss',
|
'yyyy-mm-dd hh:nn:ss',
|
||||||
'yyyy-mm-dd h:nn',
|
'yyyy-mm-dd h:nn',
|
||||||
|
'yyyy-mm-dd hh:nn:ss.u',
|
||||||
'm/d/yy h:nn:ss',
|
'm/d/yy h:nn:ss',
|
||||||
'm/d/yy h:nn',
|
|
||||||
'm/d/yy h:nn_ampm',
|
'm/d/yy h:nn_ampm',
|
||||||
|
'm/d/yy h:nn',
|
||||||
'd/m/yy hh:nn:ss',
|
'd/m/yy hh:nn:ss',
|
||||||
'd/m/yy h:nn',
|
|
||||||
'd/m/yy h:nn_ampm',
|
'd/m/yy h:nn_ampm',
|
||||||
|
'd/m/yy h:nn',
|
||||||
'ddd, dd mmm yyyy hh:nn:ss (zo|tz)', # RFC 822
|
'ddd, dd mmm yyyy hh:nn:ss (zo|tz)', # RFC 822
|
||||||
'ddd mmm d hh:nn:ss zo yyyy', # Ruby time string
|
'ddd mmm d hh:nn:ss zo yyyy', # Ruby time string
|
||||||
'yyyy-mm-ddThh:nn:ss(?:Z|zo)' # iso 8601
|
'yyyy-mm-ddThh:nn:ss(?:Z|zo)' # iso 8601
|
||||||
@ -149,8 +149,76 @@ module ValidatesTimeliness
|
|||||||
:meridian => [nil, 'md', nil]
|
:meridian => [nil, 'md', nil]
|
||||||
}
|
}
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
|
def compile_format_expressions
|
||||||
|
@@time_expressions = compile_formats(@@time_formats)
|
||||||
|
@@date_expressions = compile_formats(@@date_formats)
|
||||||
|
@@datetime_expressions = compile_formats(@@datetime_formats)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loop through format expressions for type and call proc on matches. Allow
|
||||||
|
# pre or post match strings to exist if strict is false. Otherwise wrap
|
||||||
|
# regexp in start and end anchors.
|
||||||
|
# Returns 7 part time array.
|
||||||
|
def parse(string, type, strict=true)
|
||||||
|
return string unless string.is_a?(String)
|
||||||
|
|
||||||
|
expressions = expression_set(type, string)
|
||||||
|
time_array = nil
|
||||||
|
expressions.each do |(regexp, processor)|
|
||||||
|
regexp = strict || type == :datetime ? /\A#{regexp}\Z/ : (type == :date ? /\A#{regexp}/ : /#{regexp}\Z/)
|
||||||
|
if matches = regexp.match(string.strip)
|
||||||
|
time_array = processor.call(*matches[1..7])
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return time_array
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete formats of specified type. Error raised if format not found.
|
||||||
|
def remove_formats(type, *remove_formats)
|
||||||
|
remove_formats.each do |format|
|
||||||
|
unless self.send("#{type}_formats").delete(format)
|
||||||
|
raise "Format #{format} not found in #{type} formats"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
compile_format_expressions
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds new formats. Must specify format type and can specify a :before
|
||||||
|
# option to nominate which format the new formats should be inserted in
|
||||||
|
# front on to take higher precedence.
|
||||||
|
# Error is raise if format already exists or if :before format is not found.
|
||||||
|
def add_formats(type, *add_formats)
|
||||||
|
formats = self.send("#{type}_formats")
|
||||||
|
options = {}
|
||||||
|
options = add_formats.pop if add_formats.last.is_a?(Hash)
|
||||||
|
before = options[:before]
|
||||||
|
raise "Format for :before option #{format} was not found." if before && !formats.include?(before)
|
||||||
|
|
||||||
|
add_formats.each do |format|
|
||||||
|
raise "Format #{format} is already included in #{type} formats" if formats.include?(format)
|
||||||
|
|
||||||
|
index = before ? formats.index(before) : -1
|
||||||
|
formats.insert(index, format)
|
||||||
|
end
|
||||||
|
compile_format_expressions
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Removes formats where the 1 or 2 digit month comes first, to eliminate
|
||||||
|
# formats which are ambiguous with the European style of day then month.
|
||||||
|
# The mmm token is ignored as its not ambigous.
|
||||||
|
def remove_us_formats
|
||||||
|
us_format_regexp = /\Am{1,2}[^m]/
|
||||||
|
date_formats.reject! { |format| us_format_regexp =~ format }
|
||||||
|
datetime_formats.reject! { |format| us_format_regexp =~ format }
|
||||||
|
compile_format_expressions
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
# Compile formats into validation regexps and format procs
|
# Compile formats into validation regexps and format procs
|
||||||
def format_expression_generator(string_format)
|
def format_expression_generator(string_format)
|
||||||
regexp = string_format.dup
|
regexp = string_format.dup
|
||||||
@ -195,71 +263,25 @@ module ValidatesTimeliness
|
|||||||
def compile_formats(formats)
|
def compile_formats(formats)
|
||||||
formats.collect { |format| regexp, format_proc = format_expression_generator(format) }
|
formats.collect { |format| regexp, format_proc = format_expression_generator(format) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_format_expressions
|
# Pick expression set and combine date and datetimes for
|
||||||
@@time_expressions = compile_formats(@@time_formats)
|
# datetime attributes to allow date string as datetime
|
||||||
@@date_expressions = compile_formats(@@date_formats)
|
def expression_set(type, string)
|
||||||
@@datetime_expressions = compile_formats(@@datetime_formats)
|
case type
|
||||||
end
|
when :date
|
||||||
|
date_expressions
|
||||||
# Loop through format expressions for type and call proc on matches. Allow
|
when :time
|
||||||
# pre or post match strings to exist if strict is false. Otherwise wrap
|
time_expressions
|
||||||
# regexp in start and end anchors.
|
when :datetime
|
||||||
# Returns 7 part time array.
|
# gives a speed-up for date string as datetime attributes
|
||||||
def parse(time_string, type, strict=true)
|
if string.length < 11
|
||||||
expressions = self.send("#{type}_expressions")
|
date_expressions + datetime_expressions
|
||||||
time_array = nil
|
else
|
||||||
expressions.each do |(regexp, processor)|
|
datetime_expressions + date_expressions
|
||||||
regexp = strict || type == :datetime ? /\A#{regexp}\Z/ : (type == :date ? /\A#{regexp}/ : /#{regexp}\Z/)
|
end
|
||||||
if matches = regexp.match(time_string.strip)
|
|
||||||
time_array = processor.call(*matches[1..7])
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return time_array
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete formats of specified type. Error raised if format not found.
|
|
||||||
def remove_formats(type, *remove_formats)
|
|
||||||
remove_formats.each do |format|
|
|
||||||
unless self.send("#{type}_formats").delete(format)
|
|
||||||
raise "Format #{format} not found in #{type} formats"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
compile_format_expressions
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds new formats. Must specify format type and can specify a :before
|
|
||||||
# option to nominate which format the new formats should be inserted in
|
|
||||||
# front on to take higher precedence.
|
|
||||||
# Error is raise if format already exists or if :before format is not found.
|
|
||||||
def add_formats(type, *add_formats)
|
|
||||||
formats = self.send("#{type}_formats")
|
|
||||||
options = {}
|
|
||||||
options = add_formats.pop if add_formats.last.is_a?(Hash)
|
|
||||||
before = options[:before]
|
|
||||||
raise "Format for :before option #{format} was not found." if before && !formats.include?(before)
|
|
||||||
|
|
||||||
add_formats.each do |format|
|
|
||||||
raise "Format #{format} is already included in #{type} formats" if formats.include?(format)
|
|
||||||
|
|
||||||
index = before ? formats.index(before) : -1
|
|
||||||
formats.insert(index, format)
|
|
||||||
end
|
|
||||||
compile_format_expressions
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Removes formats where the 1 or 2 digit month comes first, to eliminate
|
|
||||||
# formats which are ambiguous with the European style of day then month.
|
|
||||||
# The mmm token is ignored as its not ambigous.
|
|
||||||
def remove_us_formats
|
|
||||||
us_format_regexp = /\Am{1,2}[^m]/
|
|
||||||
date_formats.reject! { |format| us_format_regexp =~ format }
|
|
||||||
datetime_formats.reject! { |format| us_format_regexp =~ format }
|
|
||||||
compile_format_expressions
|
|
||||||
end
|
|
||||||
|
|
||||||
def full_hour(hour, meridian)
|
def full_hour(hour, meridian)
|
||||||
hour = hour.to_i
|
hour = hour.to_i
|
||||||
return hour if meridian.nil?
|
return hour if meridian.nil?
|
||||||
|
|||||||
@ -153,6 +153,11 @@ describe ValidatesTimeliness::Formats do
|
|||||||
time_array.should == [2000,2,1,12,13,14,0]
|
time_array.should == [2000,2,1,12,13,14,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should parse date string when type is datetime" do
|
||||||
|
time_array = formats.parse('2000-02-01', :datetime, false)
|
||||||
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
|
end
|
||||||
|
|
||||||
it "should ignore time when extracting date and strict is false" do
|
it "should ignore time when extracting date and strict is false" do
|
||||||
time_array = formats.parse('2000-02-01 12:12', :date, false)
|
time_array = formats.parse('2000-02-01 12:12', :date, false)
|
||||||
time_array.should == [2000,2,1,0,0,0,0]
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
@ -252,15 +257,15 @@ describe ValidatesTimeliness::Formats do
|
|||||||
|
|
||||||
def generate_regexp(format)
|
def generate_regexp(format)
|
||||||
# wrap in line start and end anchors to emulate extract values method
|
# wrap in line start and end anchors to emulate extract values method
|
||||||
/\A#{formats.format_expression_generator(format)[0]}\Z/
|
/\A#{formats.send(:format_expression_generator, format)[0]}\Z/
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_regexp_str(format)
|
def generate_regexp_str(format)
|
||||||
formats.format_expression_generator(format)[0].inspect
|
formats.send(:format_expression_generator, format)[0].inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_proc(format)
|
def generate_proc(format)
|
||||||
formats.format_expression_generator(format)[1]
|
formats.send(:format_expression_generator, format)[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_format(type, format)
|
def delete_format(type, format)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user