├── .ci.gemfile ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG ├── MIT-LICENSE ├── README.rdoc ├── Rakefile ├── american_date.gemspec ├── lib └── american_date.rb └── spec ├── american_date_keyword_spec.rb └── american_date_spec.rb /.ci.gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'minitest-global_expectations' 4 | 5 | if RUBY_VERSION < '2.4.0' 6 | # Until mintest 5.12.0 is fixed 7 | gem 'minitest', '5.11.3' 8 | gem 'rake', '<10.0.0' 9 | else 10 | gem 'rake' 11 | end 12 | 13 | platforms :ruby do 14 | if RUBY_VERSION >= '2.6' 15 | gem 'date', '>= 3.2.1' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | tests: 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | os: [ubuntu-latest] 18 | ruby: [ "2.0.0", 2.1, 2.3, 2.4, 2.5, 2.6, 2.7, "3.0", 3.1, 3.2, 3.3, 3.4, jruby-9.3, jruby-9.4, jruby-10.0 ] 19 | include: 20 | - { os: ubuntu-22.04, ruby: "1.9.3" } 21 | - { os: ubuntu-22.04, ruby: jruby-9.1 } 22 | - { os: ubuntu-22.04, ruby: jruby-9.2 } 23 | runs-on: ${{ matrix.os }} 24 | name: ${{ matrix.ruby }} 25 | env: 26 | BUNDLE_GEMFILE: .ci.gemfile 27 | steps: 28 | - uses: actions/checkout@v4 29 | - uses: ruby/setup-ruby@v1 30 | with: 31 | ruby-version: ${{ matrix.ruby }} 32 | bundler-cache: true 33 | - run: bundle exec rake 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /rdoc 2 | /coverage 3 | /american_date-*.gem 4 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | === 1.3.0 (2023-07-13) 2 | 3 | * Make sure AMERICAN_DATE_RE constant is defined on Date and not on the top level (jeremyevans) 4 | 5 | === 1.2.0 (2021-11-17) 6 | 7 | * Support the limit keyword argument supported by date 3.2.1+ (jeremyevans) 8 | 9 | === 1.1.1 (2015-10-27) 10 | 11 | * Support the third argument to Date/DateTime.parse (costi) (#13) 12 | 13 | === 1.1.0 (2013-03-23) 14 | 15 | * Handle MM/DD/YYYY substrings in the middle of strings, not just the beginning (sd, clonezone, jeremyevans) (#5) 16 | 17 | === 1.0.1 (2013-03-20) 18 | 19 | * Don't freeze the regular expression used, to allow easier overrides (jeremyevans) 20 | 21 | * Raise TypeError if passed object not implicitly convertible to String (jeremyevans) (#6) 22 | 23 | === 1.0.0 (2011-12-12) 24 | 25 | * Initial public release 26 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2021 Jeremy Evans 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = ruby-american_date 2 | 3 | ruby-american_date exists to make ruby 1.9+ parse american-style 4 | month/day/year dates correctly, with behavior matching ruby 1.8.7. 5 | It can also be used on earlier ruby versions, but it is basically 6 | a noop there. 7 | 8 | As far as I know, there isn't a gem that already handles this. You 9 | can find many snippets on the web that partially solve the issue, but 10 | most won't be compatible with ruby 1.9.3, because Date.parse and 11 | DateTime.parse no longer call Date._parse directly on 1.9.3. Also 12 | most don't handle cases where an american date format is used in 13 | addition to a time format. 14 | 15 | Note that this gem only handles / separated dates. It does not 16 | handle - or . separated dates. This is by design, for compatibility 17 | with ruby 1.8.7. 18 | 19 | == Design 20 | 21 | The general idea is fairly simple. We look for a month/day/year 22 | substring in the input string, and if we find it, we transform it 23 | into a year-month-day ISO format string before passing it to the 24 | standard date parsing methods. This is probably the least invasive 25 | way that works correctly on both the pure-ruby date parser (<1.9.3) 26 | and the C extension date parser (>=1.9.3). 27 | 28 | == Installation 29 | 30 | ruby-american_date is distributed as a gem, and can be installed with: 31 | 32 | gem install american_date 33 | 34 | == Source 35 | 36 | ruby-american_date is hosted on GitHub: 37 | 38 | https://github.com/jeremyevans/ruby-american_date 39 | 40 | == Issues 41 | 42 | ruby-american_date uses GitHub Issues for issue tracking: 43 | 44 | https://github.com/jeremyevans/ruby-american_date/issues 45 | 46 | == Author 47 | 48 | Jeremy Evans 49 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rake" 2 | require "rake/clean" 3 | 4 | CLEAN.include ["*.gem", "rdoc"] 5 | RDOC_OPTS = ['--inline-source', '--line-numbers', '--title', '', '--main', 'README.rdoc'] 6 | 7 | desc "Generate rdoc" 8 | task :rdoc do 9 | rdoc_dir = "rdoc" 10 | rdoc_opts = ["--line-numbers", "--inline-source", '--title', 'american_date: parse month/day/year dates'] 11 | 12 | begin 13 | gem 'hanna' 14 | rdoc_opts.concat(['-f', 'hanna']) 15 | rescue Gem::LoadError 16 | end 17 | 18 | rdoc_opts.concat(['--main', 'README.rdoc', "-o", rdoc_dir] + 19 | %w"README.rdoc CHANGELOG MIT-LICENSE" + 20 | Dir["lib/**/*.rb"] 21 | ) 22 | 23 | FileUtils.rm_rf(rdoc_dir) 24 | 25 | require "rdoc" 26 | RDoc::RDoc.new.document(rdoc_opts) 27 | end 28 | 29 | desc "Run specs" 30 | task :spec do 31 | sh "#{FileUtils::RUBY} #{"-w" if RUBY_VERSION >= '3'} #{'-W:strict_unused_block' if RUBY_VERSION >= '3.4'} spec/american_date_spec.rb" 32 | end 33 | task :default=>[:spec] 34 | 35 | desc "Run specs with coverage" 36 | task :spec_cov do 37 | ENV['COVERAGE'] = '1' 38 | sh "#{FileUtils::RUBY} spec/american_date_spec.rb" 39 | end 40 | 41 | desc "Package american_date" 42 | task :gem=>[:clean] do 43 | load './american_date.gemspec' 44 | Gem::Builder.new(AMERICAN_DATE_GEMSPEC).build 45 | end 46 | -------------------------------------------------------------------------------- /american_date.gemspec: -------------------------------------------------------------------------------- 1 | AMERICAN_DATE_GEMSPEC = Gem::Specification.new do |s| 2 | s.name = 'american_date' 3 | s.version = '1.3.0' 4 | s.platform = Gem::Platform::RUBY 5 | s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "MIT-LICENSE"] 6 | s.rdoc_options += ["--quiet", '--inline-source', '--line-numbers', '--title', 'american_date: American style month/day/year date parsing for ruby 1.9+', '--main', 'README.rdoc'] 7 | s.summary = "American style month/day/year date parsing for ruby 1.9+" 8 | s.description = s.summary 9 | s.license = "MIT" 10 | s.metadata = { 11 | 'bug_tracker_uri' => 'https://github.com/jeremyevans/ruby-american_date/issues', 12 | 'changelog_uri' => 'https://github.com/jeremyevans/ruby-american_date/blob/master/CHANGELOG', 13 | 'source_code_uri' => 'https://github.com/jeremyevans/ruby-american_date' 14 | } 15 | s.author = "Jeremy Evans" 16 | s.email = "code@jeremyevans.net" 17 | s.homepage = "https://github.com/jeremyevans/ruby-american_date" 18 | s.files = %w(MIT-LICENSE CHANGELOG README.rdoc lib/american_date.rb) 19 | s.add_development_dependency "minitest", '>=5' 20 | s.add_development_dependency "minitest-global_expectations" 21 | end 22 | -------------------------------------------------------------------------------- /lib/american_date.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | # :nocov: 4 | if RUBY_VERSION >= '1.9' 5 | # :nocov: 6 | long_date = ' ' * 128 + '2021-10-11' 7 | limit_supported = begin 8 | Date.parse(long_date) 9 | rescue ArgumentError 10 | (Date.parse(long_date, true, Date::ITALY, :limit=>nil) == Date.new(2021, 10, 11)) rescue false 11 | # :nocov: 12 | else 13 | false 14 | # :nocov: 15 | end 16 | 17 | # American date format detected by the library. 18 | Date::AMERICAN_DATE_RE = eval('%r_(?= '1.9.3' 46 | # :nocov: 47 | # Alias for stdlib Date.parse 48 | alias parse_without_american_date parse 49 | 50 | if limit_supported 51 | instance_eval(<<-END, __FILE__, __LINE__+1) 52 | def parse(string, comp=true, start=Date::ITALY, limit: 128) 53 | parse_without_american_date(convert_american_to_iso(string), comp, start, limit: limit) 54 | end 55 | END 56 | # :nocov: 57 | else 58 | # Transform american dates into ISO dates before parsing. 59 | def parse(string, comp=true, start=Date::ITALY) 60 | parse_without_american_date(convert_american_to_iso(string), comp, start) 61 | end 62 | end 63 | # :nocov: 64 | end 65 | 66 | private 67 | 68 | # Transform american date fromat into ISO format. 69 | def convert_american_to_iso(string) 70 | unless string.is_a?(String) 71 | if string.respond_to?(:to_str) 72 | str = string.to_str 73 | unless str.is_a?(String) 74 | raise TypeError, "no implicit conversion of #{string.inspect} into String" 75 | end 76 | string = str 77 | else 78 | raise TypeError, "no implicit conversion of #{string.inspect} into String" 79 | end 80 | end 81 | string.sub(Date::AMERICAN_DATE_RE){|m| "#$3-#$1-#$2"} 82 | end 83 | end 84 | 85 | # :nocov: 86 | if RUBY_VERSION >= '1.9.3' 87 | # :nocov: 88 | # Modify parsing methods to handle american date format correctly. 89 | DateTime.instance_eval do 90 | # Alias for stdlib Date.parse 91 | alias parse_without_american_date parse 92 | 93 | if limit_supported 94 | instance_eval(<<-END, __FILE__, __LINE__+1) 95 | def parse(string, comp=true, start=Date::ITALY, limit: 128) 96 | parse_without_american_date(convert_american_to_iso(string), comp, start, limit: limit) 97 | end 98 | END 99 | # :nocov: 100 | else 101 | # Transform american dates into ISO dates before parsing. 102 | def parse(string, comp=true, start=Date::ITALY) 103 | parse_without_american_date(convert_american_to_iso(string), comp, start) 104 | end 105 | end 106 | # :nocov: 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /spec/american_date_keyword_spec.rb: -------------------------------------------------------------------------------- 1 | long_date = ' ' * 128 + '01/02/2003' 2 | begin 3 | Date.parse(long_date) 4 | rescue ArgumentError 5 | if ((Date.parse(long_date, true, Date::ITALY, :limit=>nil) == Date.new(2003, 1, 2)) rescue false) 6 | describe "Date.parse" do 7 | specify "should not support long dates without limit keyword" do 8 | proc{Date.parse(long_date, true)}.must_raise ArgumentError 9 | end 10 | 11 | specify "should not support long dates with limit keyword" do 12 | Date.parse(long_date, true, limit: 150).must_equal Date.new(2003, 1, 2) 13 | Date.parse(long_date, true, limit: nil).must_equal Date.new(2003, 1, 2) 14 | end 15 | end 16 | 17 | describe "DateTime.parse" do 18 | long_datetime = long_date + ' 10:11:12' 19 | specify "should not support long dates without limit keyword" do 20 | proc{DateTime.parse(long_datetime, true)}.must_raise ArgumentError 21 | end 22 | 23 | specify "should not support long dates with limit keyword" do 24 | DateTime.parse(long_datetime, true, limit: 150).must_equal DateTime.new(2003, 1, 2, 10, 11, 12) 25 | DateTime.parse(long_datetime, true, limit: nil).must_equal DateTime.new(2003, 1, 2, 10, 11, 12) 26 | end 27 | end 28 | 29 | describe "Date._parse" do 30 | specify "should not support long dates without limit keyword" do 31 | proc{Date._parse(long_date, true)}.must_raise ArgumentError 32 | end 33 | 34 | specify "should not support long dates with limit keyword" do 35 | Date._parse(long_date, true, limit: 150).must_equal(:year=>2003, :mon=>1, :mday=>2) 36 | Date._parse(long_date, true, limit: nil).must_equal(:year=>2003, :mon=>1, :mday=>2) 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/american_date_spec.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | require 'rubygems' 3 | 4 | if ENV.delete('COVERAGE') 5 | require 'simplecov' 6 | 7 | SimpleCov.start do 8 | enable_coverage :branch 9 | add_filter "/spec/" 10 | add_group('Missing'){|src| src.covered_percent < 100} 11 | add_group('Covered'){|src| src.covered_percent == 100} 12 | end 13 | end 14 | 15 | require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib', 'american_date') 16 | 17 | ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins 18 | gem 'minitest' 19 | require 'minitest/global_expectations/autorun' 20 | 21 | if RUBY_VERSION >= '2.0' 22 | require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'spec', 'american_date_keyword_spec') 23 | end 24 | 25 | describe "Date.parse" do 26 | specify "should use american date format for dd/mm/yy" do 27 | Date.parse('01/02/03', true).must_equal Date.new(2003, 1, 2) 28 | Date.parse('01/02/03', true, Date::ITALY).must_equal Date.new(2003, 1, 2) 29 | end 30 | 31 | specify "should use american date format for d/m/yy" do 32 | Date.parse('1/2/03', true).must_equal Date.new(2003, 1, 2) 33 | Date.parse('1/2/03', false).must_equal Date.new(3, 1, 2) 34 | end 35 | 36 | specify "should use american date format for dd/mm/yyyy" do 37 | Date.parse('01/02/2003').must_equal Date.new(2003, 1, 2) 38 | end 39 | 40 | specify "should use american date format for dd/mm" do 41 | Date.parse('01/02').must_equal Date.new(Time.now.year, 1, 2) 42 | end 43 | 44 | specify "should use american date format for d/m" do 45 | Date.parse('1/2').must_equal Date.new(Time.now.year, 1, 2) 46 | end 47 | 48 | specify "should ignore preceding whitespace" do 49 | Date.parse(' 01/02/2003').must_equal Date.new(2003, 1, 2) 50 | end 51 | 52 | specify "should ignore preceding weekday" do 53 | Date.parse('Day 01/02/2003').must_equal Date.new(2003, 1, 2) 54 | end 55 | 56 | specify "should work just like 1.8 does" do 57 | Date.parse('10:20:30something01/02/2003else').must_equal Date.new(2003, 1, 2) 58 | end 59 | 60 | specify "should not mismatch years" do 61 | Date.parse('2003/01/02').must_equal Date.new(2003, 1, 2) 62 | end 63 | 64 | specify "should behave like 1.8 and only allow / as delimiters in american-style dates" do 65 | Date.parse("10/11/2012").must_equal Date.new(2012, 10, 11) 66 | Date.parse("10-11-2012").must_equal Date.new(2012, 11, 10) 67 | Date.parse("10.11.2012").must_equal Date.new(2012, 11, 10) 68 | end 69 | 70 | if RUBY_VERSION > '1.9' 71 | specify "should raise TypeError for invalid values" do 72 | [nil, 1, 1.0, [], {}].each do |x| 73 | proc{Date.parse(x)}.must_raise(TypeError) 74 | end 75 | end 76 | 77 | specify "should handle values implicitly convertible to String" do 78 | o = Object.new 79 | def o.to_str() '01/02/2003' end 80 | Date.parse(o).must_equal Date.new(2003, 1, 2) 81 | end 82 | 83 | specify "should handle values implicitly convertible to String" do 84 | o = Object.new 85 | def o.to_str() 1 end 86 | proc{Date.parse(o)}.must_raise(TypeError) 87 | end 88 | end 89 | end 90 | 91 | describe "DateTime.parse" do 92 | specify "should use american date format for dd/mm/yy" do 93 | DateTime.parse('01/02/03', true).must_equal DateTime.new(2003, 1, 2) 94 | DateTime.parse('01/02/03', true, DateTime::ITALY).must_equal DateTime.new(2003, 1, 2) 95 | end 96 | 97 | specify "should use american date format for d/m/yy" do 98 | DateTime.parse('1/2/03', true).must_equal DateTime.new(2003, 1, 2) 99 | DateTime.parse('1/2/03', false).must_equal DateTime.new(3, 1, 2) 100 | end 101 | 102 | specify "should use american date format for dd/mm/yyyy" do 103 | DateTime.parse('01/02/2003').must_equal DateTime.new(2003, 1, 2) 104 | end 105 | 106 | specify "should use american date format for dd/mm" do 107 | DateTime.parse('01/02').must_equal DateTime.new(Time.now.year, 1, 2) 108 | end 109 | 110 | specify "should use american date format for d/m" do 111 | DateTime.parse('1/2').must_equal DateTime.new(Time.now.year, 1, 2) 112 | end 113 | 114 | specify "should ignore preceding whitespace" do 115 | DateTime.parse(' 01/02/2003').must_equal DateTime.new(2003, 1, 2) 116 | end 117 | 118 | specify "should ignore preceding weekday" do 119 | DateTime.parse('Day 01/02/2003').must_equal Date.new(2003, 1, 2) 120 | end 121 | 122 | specify "should work with times" do 123 | DateTime.parse('01/02/2003 10:20:30').must_equal DateTime.new(2003, 1, 2, 10, 20, 30) 124 | end 125 | 126 | specify "should work with times and weekdays" do 127 | DateTime.parse('Day 01/02/2003 10:20:30').must_equal DateTime.new(2003, 1, 2, 10, 20, 30) 128 | end 129 | 130 | specify "should work just like 1.8 does" do 131 | DateTime.parse('10:20:30something01/02/2003else').must_equal DateTime.new(2003, 1, 2, 10, 20, 30) 132 | end 133 | 134 | specify "should not mismatch years" do 135 | DateTime.parse('2003/01/02').must_equal Date.new(2003, 1, 2) 136 | end 137 | 138 | if RUBY_VERSION > '1.9' 139 | specify "should raise TypeError for invalid values" do 140 | [nil, 1, 1.0, [], {}].each do |x| 141 | proc{DateTime.parse(x)}.must_raise(TypeError) 142 | end 143 | end 144 | 145 | specify "should handle values implicitly convertible to String" do 146 | o = Object.new 147 | def o.to_str() '01/02/2003' end 148 | DateTime.parse(o).must_equal DateTime.new(2003, 1, 2) 149 | end 150 | 151 | specify "should handle values implicitly convertible to String" do 152 | o = Object.new 153 | def o.to_str() 1 end 154 | proc{DateTime.parse(o)}.must_raise(TypeError) 155 | end 156 | end 157 | end 158 | 159 | describe "Time.parse" do 160 | specify "should use american date format for dd/mm/yy" do 161 | Time.parse('01/02/03').must_equal Time.local(2003, 1, 2) 162 | end 163 | 164 | specify "should use american date format for d/m/yy" do 165 | Time.parse('1/2/03').must_equal Time.local(2003, 1, 2) 166 | end 167 | 168 | specify "should use american date format for dd/mm/yyyy" do 169 | Time.parse('01/02/2003').must_equal Time.local(2003, 1, 2) 170 | end 171 | 172 | specify "should use american date format for dd/mm" do 173 | Time.parse('01/02').must_equal Time.local(Time.now.year, 1, 2) 174 | end 175 | 176 | specify "should use american date format for d/m" do 177 | Time.parse('1/2').must_equal Time.local(Time.now.year, 1, 2) 178 | end 179 | 180 | specify "should ignore preceding whitespace" do 181 | Time.parse(' 01/02/2003').must_equal Time.local(2003, 1, 2) 182 | end 183 | 184 | specify "should ignore preceding weekdays" do 185 | Time.parse('Day 01/02/2003').must_equal Time.local(2003, 1, 2) 186 | end 187 | 188 | specify "should work with times" do 189 | Time.parse('01/02/2003 10:20:30').must_equal Time.local(2003, 1, 2, 10, 20, 30) 190 | end 191 | 192 | specify "should work with times and weekdays" do 193 | Time.parse('Day 01/02/2003 10:20:30').must_equal Time.local(2003, 1, 2, 10, 20, 30) 194 | end 195 | 196 | specify "should work with time first and date second" do 197 | Time.parse('10:20:30 01/02/2003').must_equal Time.local(2003, 1, 2, 10, 20, 30) 198 | end 199 | 200 | specify "should work with time first and date second and weekday in the middle" do 201 | Time.parse('10:20:30 Thu 01/02/2003').must_equal Time.local(2003, 1, 2, 10, 20, 30) 202 | end 203 | 204 | specify "should work just like 1.8 does" do 205 | Time.parse('10:20:30something01/02/2003else').must_equal Time.local(2003, 1, 2, 10, 20, 30) 206 | end 207 | 208 | specify "should not mismatch years" do 209 | Time.parse('2003/01/02').must_equal Time.local(2003, 1, 2, 0, 0, 0) 210 | end 211 | 212 | if RUBY_VERSION > '1.9' 213 | specify "should raise TypeError for invalid values" do 214 | [nil, 1, 1.0, [], {}].each do |x| 215 | proc{Time.parse(x)}.must_raise(TypeError) 216 | end 217 | end 218 | 219 | specify "should handle values implicitly convertible to String" do 220 | o = Object.new 221 | def o.to_str() '01/02/2003' end 222 | Time.parse(o).must_equal Time.local(2003, 1, 2) 223 | end 224 | 225 | specify "should handle values implicitly convertible to String" do 226 | o = Object.new 227 | def o.to_str() 1 end 228 | proc{Time.parse(o)}.must_raise(TypeError) 229 | end 230 | end 231 | end 232 | 233 | describe "Date._parse" do 234 | specify "should use american date format for dd/mm/yy" do 235 | Date._parse('01/02/03', true).must_equal(:year=>2003, :mon=>1, :mday=>2) 236 | end 237 | 238 | specify "should use american date format for d/m/yy" do 239 | Date._parse('1/2/03', true).must_equal(:year=>2003, :mon=>1, :mday=>2) 240 | Date._parse('1/2/03', false).must_equal(:year=>3, :mon=>1, :mday=>2) 241 | end 242 | 243 | specify "should use american date format for dd/mm/yyyy" do 244 | Date._parse('01/02/2003').must_equal(:year=>2003, :mon=>1, :mday=>2) 245 | end 246 | 247 | specify "should use american date format for dd/mm" do 248 | Date._parse('01/02').must_equal(:mon=>1, :mday=>2) 249 | end 250 | 251 | specify "should use american date format for d/m" do 252 | Date._parse('1/2').must_equal(:mon=>1, :mday=>2) 253 | end 254 | 255 | specify "should ignore preceding whitespace" do 256 | Date._parse(' 01/02/2003').must_equal(:year=>2003, :mon=>1, :mday=>2) 257 | end 258 | 259 | specify "should work with times" do 260 | DateTime._parse('01/02/2003 10:20:30').must_equal(:year=>2003, :mon=>1, :mday=>2, :hour=>10, :min=>20, :sec=>30) 261 | end 262 | 263 | if RUBY_VERSION > '1.9' 264 | specify "should raise TypeError for invalid values" do 265 | [nil, 1, 1.0, [], {}].each do |x| 266 | proc{DateTime._parse(x)}.must_raise(TypeError) 267 | end 268 | end 269 | 270 | specify "should handle values implicitly convertible to String" do 271 | o = Object.new 272 | def o.to_str() '01/02/2003' end 273 | DateTime._parse(o).must_equal(:year=>2003, :mon=>1, :mday=>2) 274 | end 275 | 276 | specify "should handle values implicitly convertible to String" do 277 | o = Object.new 278 | def o.to_str() 1 end 279 | proc{DateTime._parse(o)}.must_raise(TypeError) 280 | end 281 | end 282 | end 283 | --------------------------------------------------------------------------------