lib/validates_timeliness/formats.rb in adzap-validates_timeliness-2.0.0 vs lib/validates_timeliness/formats.rb in adzap-validates_timeliness-2.1.0
- old
+ new
@@ -19,10 +19,21 @@
:date_expressions,
:datetime_expressions,
:format_tokens,
:format_proc_args
+
+ # Set the threshold value for a two digit year to be considered last century
+ # Default: 30
+ #
+ # Example:
+ # year = '29' is considered 2029
+ # year = '30' is considered 1930
+ #
+ cattr_accessor :ambiguous_year_threshold
+ self.ambiguous_year_threshold = 30
+
# Format tokens:
# y = year
# m = month
# d = day
# h = hour
@@ -44,11 +55,11 @@
# x = 1 or 2 digits for unit (e.g. 'h' means an hour can be '9' or '09')
# xx = 2 digits exactly for unit (e.g. 'hh' means an hour can only be '09')
#
# Special Cases:
# yy = 2 or 4 digit year
- # yyyyy = exactly 4 digit year
+ # yyyy = exactly 4 digit year
# mmm = month long name (e.g. 'Jul' or 'July')
# ddd = Day name of 3 to 9 letters (e.g. Wed or Wednesday)
# u = microseconds matches 1 to 6 digits
#
# Any other invalid combination of repeating tokens will be swallowed up
@@ -83,10 +94,11 @@
]
@@datetime_formats = [
'yyyy-mm-dd hh:nn:ss',
'yyyy-mm-dd h:nn',
+ 'yyyy-mm-dd h:nn_ampm',
'yyyy-mm-dd hh:nn:ss.u',
'm/d/yy h:nn:ss',
'm/d/yy h:nn_ampm',
'm/d/yy h:nn',
'd/m/yy hh:nn:ss',
@@ -224,10 +236,53 @@
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)
+ hour = hour.to_i
+ return hour if meridian.nil?
+ if meridian.delete('.').downcase == 'am'
+ hour == 12 ? 0 : hour
+ else
+ hour == 12 ? hour : hour + 12
+ end
+ end
+
+ def unambiguous_year(year)
+ if year.length <= 2
+ century = Time.now.year.to_s[0..1].to_i
+ century -= 1 if year.to_i >= ambiguous_year_threshold
+ year = "#{century}#{year.rjust(2,'0')}"
+ end
+ year.to_i
+ end
+
+ def month_index(month)
+ return month.to_i if month.to_i.nonzero?
+ abbr_month_names.index(month.capitalize) || month_names.index(month.capitalize)
+ end
+
+ def month_names
+ defined?(I18n) ? I18n.t('date.month_names') : Date::MONTHNAMES
+ end
+
+ def abbr_month_names
+ defined?(I18n) ? I18n.t('date.abbr_month_names') : Date::ABBR_MONTHNAMES
+ end
+
+ def microseconds(usec)
+ (".#{usec}".to_f * 1_000_000).to_i
+ end
+
+ def offset_in_seconds(offset)
+ sign = offset =~ /^-/ ? -1 : 1
+ parts = offset.scan(/\d\d/).map {|p| p.to_f }
+ parts[1] = parts[1].to_f / 60
+ (parts[0] + parts[1]) * sign * 3600
+ end
+
private
# Compile formats into validation regexps and format procs
def format_expression_generator(string_format)
regexp = string_format.dup
@@ -257,11 +312,16 @@
def format_proc(order)
arg_map = format_proc_args
args = order.invert.sort.map {|p| arg_map[p[1]][1] }
arr = [nil] * 7
order.keys.each {|k| i = arg_map[k][0]; arr[i] = arg_map[k][2] unless i.nil? }
- proc_string = "lambda {|#{args.join(',')}| md||=nil; [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|i| i.is_a?(Float) ? i : i.to_i } }"
+ proc_string = <<-EOL
+ lambda {|#{args.join(',')}|
+ md ||= nil
+ [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|i| i.is_a?(Float) ? i : i.to_i }
+ }
+ EOL
eval proc_string
end
def compile_formats(formats)
formats.map { |format| [ format, *format_expression_generator(format) ] }
@@ -283,47 +343,9 @@
datetime_expressions + date_expressions
end
end
end
- def full_hour(hour, meridian)
- hour = hour.to_i
- return hour if meridian.nil?
- if meridian.delete('.').downcase == 'am'
- hour == 12 ? 0 : hour
- else
- hour == 12 ? hour : hour + 12
- end
- end
-
- def unambiguous_year(year, threshold=30)
- year = "#{year.to_i < threshold ? '20' : '19'}#{year}" if year.length == 2
- year.to_i
- end
-
- def month_index(month)
- return month.to_i if month.to_i.nonzero?
- abbr_month_names.index(month.capitalize) || month_names.index(month.capitalize)
- end
-
- def month_names
- defined?(I18n) ? I18n.t('date.month_names') : Date::MONTHNAMES
- end
-
- def abbr_month_names
- defined?(I18n) ? I18n.t('date.abbr_month_names') : Date::ABBR_MONTHNAMES
- end
-
- def microseconds(usec)
- (".#{usec}".to_f * 1_000_000).to_i
- end
-
- def offset_in_seconds(offset)
- sign = offset =~ /^-/ ? -1 : 1
- parts = offset.scan(/\d\d/).map {|p| p.to_f }
- parts[1] = parts[1].to_f / 60
- (parts[0] + parts[1]) * sign * 3600
- end
end
end
end
ValidatesTimeliness::Formats.compile_format_expressions