diff --git a/README b/README index 982ab98..dc29d78 100644 --- a/README +++ b/README @@ -129,6 +129,8 @@ you want. No regular expressions or duck punching (monkey patching) the plugin. d.m.yy d mmm yy + NOTE: to switch to using non-US date formats see US/EURO FORMATS section + Datetime formats: m/d/yy h:nn:ss OR d/m/yy hh:nn:ss m/d/yy h:nn OR d/m/yy h:nn @@ -138,6 +140,8 @@ you want. No regular expressions or duck punching (monkey patching) the plugin. ddd mmm d hh:nn:ss zo yyyy # Ruby time string yyyy-mm-ddThh:nn:ss(?:Z|zo) # ISO 8601 + NOTE: to switch to using non-US date formats see US/EURO FORMATS section + Here is what each format token means: Format tokens: @@ -177,6 +181,21 @@ regular expressions directly. So, no, it won't make your app slow! To see all defined formats look in the lib/validates_timeliness/formats.rb. +=== US/EURO FORMATS + +The perenial problem for non-US develops or applications not primarily for the +US, is the US date format of m/d/yy. This is ambiguous with the European format +of d/my/yy. By default the plugin uses the US formats as this is the Ruby default +when it does date interpretation, and is in keeping PoLS (principle of least +surprise). + +To switch to using the European (or Rest of The World) formats put this in an +initializer or environment.rb + + ValidatesTimeliness::Formats.remove_us_formats + +Now '01/02/2000' will be parsed as 1st February 2000, instead of 2nd January 2000. + === CUSTOMISING FORMATS: I hear you say "Thats greats but I don't want X format to be valid". Well to diff --git a/lib/validates_timeliness/formats.rb b/lib/validates_timeliness/formats.rb index 36fee77..cd890f7 100644 --- a/lib/validates_timeliness/formats.rb +++ b/lib/validates_timeliness/formats.rb @@ -1,4 +1,3 @@ -# TODO add support switching US to euro date formats module ValidatesTimeliness # A date and time format regular expression generator. Allows you to @@ -230,8 +229,8 @@ module ValidatesTimeliness # 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. + # 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 = {} @@ -248,6 +247,17 @@ module ValidatesTimeliness 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) hour = hour.to_i return hour if meridian.nil? diff --git a/spec/formats_spec.rb b/spec/formats_spec.rb index 91cfa87..44a1793 100644 --- a/spec/formats_spec.rb +++ b/spec/formats_spec.rb @@ -225,6 +225,21 @@ describe ValidatesTimeliness::Formats do formats.time_formats.delete("ss:hh:nn") end end + + describe "removing US formats" do + it "should validate a date as European format when US formats removed" do + time_array = formats.extract_date_time_values('01/02/2000', :date) + time_array.should == [2000, 1, 2,nil,nil,nil,nil] + formats.remove_us_formats + puts formats.datetime_formats.inspect + time_array = formats.extract_date_time_values('01/02/2000', :date) + time_array.should == [2000, 2, 1,nil,nil,nil,nil] + end + + after do + + end + end def validate(time_string, type) valid = false