├── .gitignore ├── CHANGELOG ├── LICENSE ├── README.rdoc ├── Rakefile ├── Rakefile.cross ├── bench ├── cpu_bench.rb ├── cpu_bench_util.rb ├── dt_garbage_bench.rb ├── dt_mem_bench.rb ├── garbage_bench.rb ├── mem_bench.rb └── parser_bench.rb ├── bin └── home_run ├── default.mspec ├── ext └── date_ext │ ├── date_ext.c │ ├── date_ext.h │ ├── date_parser.c │ ├── date_parser.rl │ ├── datetime.c │ └── extconf.rb ├── home_run.gemspec ├── lib ├── date.rb ├── date │ └── format.rb └── home_run.rb └── spec ├── date ├── accessor_spec.rb ├── add_month_spec.rb ├── add_spec.rb ├── allocate_spec.rb ├── boat_spec.rb ├── civil_spec.rb ├── clone_spec.rb ├── commercial_spec.rb ├── constants_spec.rb ├── conversions_spec.rb ├── day_spec.rb ├── downto_spec.rb ├── dup_spec.rb ├── encoding_spec.rb ├── eql_spec.rb ├── format_spec.rb ├── gregorian_spec.rb ├── hash_spec.rb ├── julian_spec.rb ├── leap_spec.rb ├── limits_spec.rb ├── minus_month_spec.rb ├── minus_spec.rb ├── next_prev_spec.rb ├── ordinal_spec.rb ├── parse_spec.rb ├── parsing_spec.rb ├── relationship_spec.rb ├── step_spec.rb ├── strftime_spec.rb ├── strptime_spec.rb ├── succ_spec.rb ├── today_spec.rb └── upto_spec.rb ├── datetime ├── accessor_spec.rb ├── add_month_spec.rb ├── add_spec.rb ├── allocate_spec.rb ├── boat_spec.rb ├── clone_spec.rb ├── constructor_spec.rb ├── conversions_spec.rb ├── day_spec.rb ├── downto_spec.rb ├── dup_spec.rb ├── encoding_spec.rb ├── eql_spec.rb ├── format_spec.rb ├── hash_spec.rb ├── leap_spec.rb ├── limits_spec.rb ├── minus_month_spec.rb ├── minus_spec.rb ├── next_prev_spec.rb ├── now_spec.rb ├── parse_spec.rb ├── parsing_spec.rb ├── relationship_spec.rb ├── step_spec.rb ├── strftime_spec.rb ├── strptime_spec.rb ├── succ_spec.rb └── upto_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | /ext/date_ext/Makefile 3 | /ext/date_ext/*.o 4 | /ext/date_ext/date_ext.so 5 | /rdoc 6 | /home_run-*.gem 7 | *.core 8 | /pkg 9 | /lib/1.* 10 | /lib/date_ext.so 11 | /tmp 12 | /coverage 13 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | === 1.0.9 (2013-03-19) 2 | 3 | * Add Date::Infinity implementation (jeremyevans) (#50) 4 | 5 | === 1.0.8 (2013-02-28) 6 | 7 | * Switch %i to %d in format strings to work on ruby 2.0 (jeremyevans) 8 | 9 | === 1.0.7 (2012-08-08) 10 | 11 | * Make DateTime constructors handle fractional seconds in seconds argument (jeremyevans) 12 | 13 | === 1.0.6 (2012-02-27) 14 | 15 | * Merge DateTime#<=> into Date#<=> to work around ActiveSupport bug (jeremyevans) (#45, #41, #38, #36) 16 | 17 | === 1.0.5 (2011-12-22) 18 | 19 | * Handle DateTime.jd with a single float argument (jeremyevans) 20 | 21 | === 1.0.4 (2011-09-02) 22 | 23 | * Handle time zone offsets given as strings in the constructors (jeremyevans) (#37) 24 | 25 | === 1.0.3 (2011-07-05) 26 | 27 | * Work around segfault in rb_ary_push during extension initialization (jeremyevans) 28 | 29 | === 1.0.2 (2011-03-18) 30 | 31 | * Support fractional timestamps in the ISO date parser (funny-falcon) 32 | 33 | * Support more variations in timezone formats in the ISO date parser (funny-falcon) 34 | 35 | === 1.0.1 (2011-02-28) 36 | 37 | * Make #step with a 0 step value raise an ArgumentError (jeremyevans) 38 | 39 | * Fix #dup and #clone to work correctly (jeremyevans) (#21) 40 | 41 | === 1.0.0 (2011-02-01) 42 | 43 | * Define the ZONES hash in ruby to work around probable interpreter bug (jeremyevans) 44 | 45 | === 0.9.4 (2010-10-18) 46 | 47 | * Have methods of subclasses of Date and DateTime return instances of the subclass (jeremyevans) 48 | 49 | === 0.9.3 (2010-09-20) 50 | 51 | * Don't attempt to undefine already undefined method if you require date_ext twice with two different paths (jeremyevans) 52 | 53 | === 0.9.2 (2010-09-13) 54 | 55 | * Make DateTime#sec_fraction on ruby 1.9 to be compatible with 1.9 stdlib (jeremyevans) 56 | 57 | * Remove the use of the %hhi sprintf format specifier, for greater standards compatibility (jeremyevans) 58 | 59 | * Fix a bug where the same symbol was present in multiple objects, causing build failures with -fno-common (jeremyevans) (#10) 60 | 61 | === 0.9.1 (2010-09-01) 62 | 63 | * Fix strptime for %Y%m%d and similar formats (jeremyevans) (#9) 64 | 65 | * Require rake-compiler when building from source (may need to clean out your ext/date_ext directory manually) (jeremyevans) 66 | 67 | * Include the ragel-generated file in the repository, so you don't need ragel to build from source (jeremyevans) 68 | 69 | * Respect Encoding.default_internal for returned strings on 1.9 (brianmario, jeremyevans) 70 | 71 | * Handle problems with zones in the -HH,DDD or -HH.DDD formats (jeremyevans) 72 | 73 | * Compile C files separately, instead of including C files in other C files (jeremyevans) 74 | 75 | * On ruby 1.9, return strings in US-ASCII encoding instead of ASCII-8BIT (jeremyevans) (#8) 76 | 77 | * Reorganize directory structure to use the standard ruby extension structure (luislavena, jeremyevans) 78 | 79 | * Support Date/DateTime#step without a block returning an Enumerator on 1.9 (jeremyevans) (#6) 80 | 81 | * Support ruby build with CALC_EXACT_MALLOC_SIZE (nocode) (#5) 82 | 83 | * Add Ragel parser for Apache Common Log Format date format (jeremyevans) 84 | 85 | * Add Ragel parser for RFC 822 date format (jeremyevans) 86 | 87 | * Fix loading date/format.rb directly where the date extension hasn't been included but the Date class has been opened (jeremyevans) (#3) 88 | 89 | * Don't override ruby's default extension optimization flags (jeremyevans) 90 | 91 | * Fix compilation on Solaris with the Sun Studio Compiler (ankopainting) 92 | 93 | * Handle YYYY/MM/DD date format in the ISO 8601 Ragel parser (jeremyevans) 94 | 95 | * Add a home_run.rb file to allow you to require 'home_run' to load the extension, useful on Heroku with ruby 1.8 (jeremyevans) (#2) 96 | 97 | * Don't think that Mac OS X/Darwin users are on Windows (jeremyevans) (#1) 98 | 99 | * Tighten up offset limits to exactly 14 hours from UTC (jeremyevans) 100 | 101 | * Make dates outside of the allowed range raise RangeErrors (jeremyevans) 102 | 103 | * Add range check for DateTime#+ and related methods (jeremyevans) 104 | 105 | * Add range check for DateTime#new! (jeremyevans) 106 | 107 | === 0.9.0 (2010-08-20) 108 | 109 | * Initial Public Release 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 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 | 20 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rake" 2 | require "rake/clean" 3 | require 'rbconfig' 4 | 5 | CLEAN.include %w'**/*.rbc *.core rdoc coverage' 6 | RUBY=ENV['RUBY'] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) 7 | 8 | desc "Build the RDoc documentation" 9 | task :rdoc do 10 | require 'fileutils' 11 | FileUtils.rm_rf('rdoc') 12 | sh 'rdoc --quiet --line-numbers --inline-source --output rdoc --title ' \ 13 | '"home_run: Fast Date/DateTime classes for ruby" --main README.rdoc ' \ 14 | 'README.rdoc CHANGELOG LICENSE lib/date.rb lib/date/format.rb ext/date_ext/*.c' 15 | end 16 | 17 | desc "Run the specs with mspec" 18 | task :default => :spec 19 | task :spec do 20 | ENV['RUBY'] ||= RUBY 21 | sh %{mspec} 22 | end 23 | 24 | desc "Build the gem" 25 | task :gem => [:distclean] do 26 | sh %{gem build home_run.gemspec} 27 | end 28 | 29 | desc "Try to clean up everything" 30 | task :distclean do 31 | CLEAN.concat(%w'pkg home_run-*.gem lib/1.* tmp') 32 | Rake::Task[:clean].invoke 33 | end 34 | 35 | begin 36 | require 'rake/extensiontask' 37 | Rake::ExtensionTask.new('date_ext') 38 | rescue LoadError 39 | end 40 | 41 | desc "Regenerate the ragel parser" 42 | task :parser do 43 | sh %{cd ext/date_ext && ragel date_parser.rl} 44 | end 45 | 46 | desc "Start an IRB shell using the extension" 47 | task :irb do 48 | irb = ENV['IRB'] || File.join(RbConfig::CONFIG['bindir'], File.basename(RUBY).sub('ruby', 'irb')) 49 | sh %{#{irb} -I lib -r date} 50 | end 51 | 52 | desc "Run comparative benchmarks" 53 | task :bench do 54 | sh %{#{RUBY} bench/cpu_bench.rb} 55 | end 56 | 57 | desc "Run all benchmarks" 58 | task :bench_all => [:bench, :mem_bench, :garbage_bench] 59 | 60 | desc "Run comparative parser benchmarks" 61 | task :parser_bench do 62 | sh %{#{RUBY} bench/parser_bench.rb} 63 | end 64 | 65 | desc "Run comparative memory benchmarks" 66 | task :mem_bench do 67 | if RUBY_PLATFORM =~ /mswin|mingw/ 68 | puts "Memory benchmarks not supported on Windows" 69 | next 70 | end 71 | 72 | stdlib = `#{RUBY} -I #{RbConfig::CONFIG['rubylibdir']} bench/mem_bench.rb`.to_i 73 | home_run = `#{RUBY} -I lib bench/mem_bench.rb`.to_i 74 | puts "Date memory use,#{stdlib}KB,#{home_run}KB,#{sprintf('%0.1f', stdlib/home_run.to_f)}" 75 | 76 | stdlib = `#{RUBY} -I #{RbConfig::CONFIG['rubylibdir']} bench/dt_mem_bench.rb`.to_i 77 | home_run = `#{RUBY} -I lib bench/dt_mem_bench.rb`.to_i 78 | puts "DateTime memory use,#{stdlib}KB,#{home_run}KB,#{sprintf('%0.1f', stdlib/home_run.to_f)}" 79 | end 80 | 81 | desc "Run comparative garbage creation benchmarks" 82 | task :garbage_bench do 83 | if RUBY_PLATFORM =~ /mswin|mingw/ 84 | puts "Garbage creation benchmarks not supported on Windows" 85 | next 86 | end 87 | 88 | stdlib = `#{RUBY} -I #{RbConfig::CONFIG['rubylibdir']} bench/garbage_bench.rb`.to_i 89 | home_run = `#{RUBY} -I lib bench/garbage_bench.rb`.to_i 90 | puts "Date garbage created,#{stdlib}KB,#{home_run}KB,#{sprintf('%0.1f', stdlib/home_run.to_f)}" 91 | 92 | stdlib = `#{RUBY} -I #{RbConfig::CONFIG['rubylibdir']} bench/dt_garbage_bench.rb`.to_i 93 | home_run = `#{RUBY} -I lib bench/dt_garbage_bench.rb`.to_i 94 | puts "DateTime garbage created,#{stdlib}KB,#{home_run}KB,#{sprintf('%0.1f', stdlib/home_run.to_f)}" 95 | end 96 | -------------------------------------------------------------------------------- /Rakefile.cross: -------------------------------------------------------------------------------- 1 | load File.join(File.dirname(File.expand_path(__FILE__)), 'Rakefile') 2 | 3 | ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1' 4 | require 'rake/extensiontask' 5 | load('home_run.gemspec') 6 | Rake::ExtensionTask.new('date_ext', HOME_RUN_GEMSPEC) do |ext| 7 | ext.cross_compile = true 8 | ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60'] 9 | end 10 | -------------------------------------------------------------------------------- /bench/cpu_bench_util.rb: -------------------------------------------------------------------------------- 1 | require 'rbconfig' 2 | $:.unshift RbConfig::CONFIG['rubylibdir'] 3 | require 'date' 4 | require 'benchmark' 5 | 6 | SD = Date 7 | SDT = DateTime 8 | Object.send(:remove_const, :Date) 9 | Object.send(:remove_const, :DateTime) 10 | $:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib')) 11 | load 'lib/date.rb' 12 | load 'lib/date/format.rb' 13 | HRD = Date 14 | HRDT = DateTime 15 | NANOS_PER_SEC = 1000000000 16 | N = ENV['N'] ? ENV['N'].to_i : 10000 17 | S = ENV['S'] ? ENV['S'].to_f : 2 18 | FILTER = ARGV.empty? ? nil : Regexp.new(ARGV[0]) 19 | 20 | def compare(label, datetime=false, &block) 21 | return if FILTER && label !~ FILTER 22 | Object.send(:remove_const, :Date) 23 | Object.send(:remove_const, :DateTime) 24 | Object.send(:const_set, :Date, SD) 25 | Object.send(:const_set, :DateTime, SDT) 26 | stdlib = 0.0 27 | stdlib_times = 0 28 | while stdlib < S 29 | t = Time.now 30 | yield(datetime ? SDT : SD) 31 | stdlib += Time.now - t 32 | stdlib_times += 1 33 | end 34 | 35 | Object.send(:remove_const, :Date) 36 | Object.send(:remove_const, :DateTime) 37 | Object.send(:const_set, :Date, HRD) 38 | Object.send(:const_set, :DateTime, HRDT) 39 | home_run = 0.0 40 | home_run_times = 0 41 | while home_run < S 42 | t = Time.now 43 | yield(datetime ? HRDT : HRD) 44 | home_run += Time.now - t 45 | home_run_times += 1 46 | end 47 | 48 | puts sprintf('%s%s,%i,%i,%0.2f', datetime ? 'DateTime' : 'Date', label, (stdlib * NANOS_PER_SEC)/(N * stdlib_times), (home_run * NANOS_PER_SEC)/(N * home_run_times), (stdlib/stdlib_times)/(home_run/home_run_times)) 49 | end 50 | 51 | def dt_compare(label, &block) 52 | compare(label, true, &block) 53 | end 54 | 55 | puts "label,stdlib,home_run,times faster" 56 | -------------------------------------------------------------------------------- /bench/dt_garbage_bench.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | def mem_usage 4 | `ps -o vsz -p #{$$}`.split.last.to_i 5 | end 6 | n = 50000 7 | GC.start 8 | GC.disable 9 | start_mem = mem_usage 10 | n.times{DateTime.civil(2010, 11, 21, 13, 43, 57)} 11 | puts(mem_usage - start_mem) 12 | -------------------------------------------------------------------------------- /bench/dt_mem_bench.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | def mem_usage 4 | `ps -o vsz -p #{$$}`.split.last.to_i 5 | end 6 | n = 100000 7 | GC.start 8 | start_mem = mem_usage 9 | m = (0...n).map{nil} 10 | GC.start 11 | array_usage = mem_usage - start_mem 12 | m = (0...n).map{DateTime.civil} 13 | GC.start 14 | puts(mem_usage - start_mem - array_usage) 15 | -------------------------------------------------------------------------------- /bench/garbage_bench.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | def mem_usage 4 | `ps -o vsz -p #{$$}`.split.last.to_i 5 | end 6 | n = 100000 7 | GC.start 8 | GC.disable 9 | start_mem = mem_usage 10 | n.times{Date.civil(2010, 11, 21)} 11 | puts(mem_usage - start_mem) 12 | -------------------------------------------------------------------------------- /bench/mem_bench.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | def mem_usage 4 | `ps -o vsz -p #{$$}`.split.last.to_i 5 | end 6 | n = 100000 7 | GC.start 8 | start_mem = mem_usage 9 | m = (0...n).map{nil} 10 | GC.start 11 | array_usage = mem_usage - start_mem 12 | m = (0...n).map{Date.jd} 13 | GC.start 14 | puts(mem_usage - start_mem - array_usage) 15 | -------------------------------------------------------------------------------- /bench/parser_bench.rb: -------------------------------------------------------------------------------- 1 | load(File.join(File.dirname(File.expand_path(__FILE__)), 'cpu_bench_util.rb')) 2 | n = N 3 | formats = < 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H 13 | #define RHR_ENCODING 1 14 | #include 15 | #endif 16 | 17 | #ifdef RUBY19 18 | #define RHR_DEFAULT_CWYEAR -4713 19 | #define RHR_DEFAULT_CWEEK 1 20 | #define RHR_DEFAULT_CWDAY 1 21 | #else 22 | #define RHR_DEFAULT_CWYEAR 1582 23 | #define RHR_DEFAULT_CWEEK 41 24 | #define RHR_DEFAULT_CWDAY 5 25 | #endif 26 | 27 | #define RHR_JD_MJD 2400001 28 | #define RHR_JD_LD 2299160 29 | #define RHR_JD_ITALY 2299161 30 | #define RHR_JD_ENGLAND 2361222 31 | #define RHR_UNIX_EPOCH 2440588 32 | #define RHR_SECONDS_PER_HOUR 3600 33 | #define RHR_MINUTES_PER_DAYD 1440.0 34 | #define RHR_SECONDS_PER_DAY 86400 35 | #define RHR_SECONDS_PER_DAYD 86400.0 36 | #define RHR_MAX_OFFSET 840 37 | #define RHR_MIN_OFFSET -840 38 | 39 | /* 40 | In both the 32-bit and 64-bit cases, the limits are chosen so that you cannot 41 | store a civil date where converting it to a jd would cause an overflow. 42 | */ 43 | #if __LP64__ 44 | /* 45 | On 64-bit systems, the limits depend on the number of significant digits in 46 | a double (15). These are slightly below the maximum so that all numbers used 47 | in calculations have fewer than 15 digits. 48 | */ 49 | #define RHR_JD_MAX 999979466117609 50 | #define RHR_JD_MIN -999979466119058 51 | #define RHR_YEAR_MAX 2737850782415 52 | #define RHR_MONTH_MAX 12 53 | #define RHR_DAY_MAX 5 54 | #define RHR_YEAR_MIN -2737850791845 55 | #define RHR_MONTH_MIN 11 56 | #define RHR_DAY_MIN 26 57 | 58 | #else 59 | /* 60 | On 32-bit systems, the limits depend on the storage limits of 32-bit integers. 61 | The numbers are slightly less than 2**31 - 1 and slightly greater than -2**31 62 | so that no calculations can overflow. 63 | */ 64 | #define RHR_JD_MAX 2147438064 65 | #define RHR_JD_MIN -2145083647 66 | #define RHR_YEAR_MAX 5874773 67 | #define RHR_MONTH_MAX 8 68 | #define RHR_DAY_MAX 15 69 | #define RHR_YEAR_MIN -5877752 70 | #define RHR_MONTH_MIN 5 71 | #define RHR_DAY_MIN 8 72 | #endif 73 | 74 | #define RHR_HAVE_JD 1 75 | #define RHR_HAVE_CIVIL 2 76 | #define RHR_HAVE_NANOS 4 77 | #define RHR_HAVE_HMS 8 78 | 79 | #define RHR_NO_RAISE 0 80 | #define RHR_OVERLIMIT_RAISE 1 81 | 82 | #define RHR_NANOS_PER_MILLISECOND 1000000LL 83 | #define RHR_NANOS_PER_SECOND 1000000000LL 84 | #define RHR_NANOS_PER_MINUTE 60000000000LL 85 | #define RHR_NANOS_PER_DAY 86400000000000LL 86 | #define RHR_NANOS_PER_DAYD 86400000000000.0 87 | #define RHR_NANOS_PER_SECONDD 1000000000.0 88 | 89 | #define RHRR_YEAR_SET 0x1 90 | #define RHRR_MONTH_SET 0x2 91 | #define RHRR_DAY_SET 0x4 92 | #define RHRR_YDAY_SET 0x8 93 | #define RHRR_HOUR_SET 0x10 94 | #define RHRR_MINUTE_SET 0x20 95 | #define RHRR_SECOND_SET 0x40 96 | #define RHRR_WDAY_SET 0x80 97 | #define RHRR_CENTURY_SET 0x100 98 | #define RHRR_CWYEAR_SET 0x200 99 | #define RHRR_CWEEK_SET 0x400 100 | #define RHRR_CWDAY_SET 0x800 101 | #define RHRR_SEC_FRACTION_SET 0x1000 102 | #define RHRR_UNIX_SET 0x2000 103 | #define RHRR_WNUM0_SET 0x4000 104 | #define RHRR_WNUM1_SET 0x8000 105 | #define RHRR_MERIDIAN_SET 0x10000 106 | #define RHRR_ZONE_SET 0x20000 107 | #define RHRR_OFFSET_SET 0x40000 108 | #define RHRR_UNIXM_SET 0x80000 109 | 110 | #define RHR_HAS_JD(d) (((d)->flags & RHR_HAVE_JD) == RHR_HAVE_JD) 111 | #define RHR_HAS_CIVIL(d) (((d)->flags & RHR_HAVE_CIVIL) == RHR_HAVE_CIVIL) 112 | 113 | #define RHR_FILL_JD(d) if (((d)->flags & RHR_HAVE_JD) == 0) { rhrd__civil_to_jd(d); } 114 | #define RHR_FILL_CIVIL(d) if (((d)->flags & RHR_HAVE_CIVIL) == 0) { rhrd__jd_to_civil(d); } 115 | 116 | #define RHRDT_FILL_JD(d) if (!((d)->flags & RHR_HAVE_JD)) { rhrdt__civil_to_jd(d); } 117 | #define RHRDT_FILL_CIVIL(d) if (!((d)->flags & RHR_HAVE_CIVIL)) { rhrdt__jd_to_civil(d); } 118 | #define RHRDT_FILL_HMS(d) if (!((d)->flags & RHR_HAVE_HMS)) { rhrdt__nanos_to_hms(d); } 119 | #define RHRDT_FILL_NANOS(d) if (!((d)->flags & RHR_HAVE_NANOS)) { rhrdt__hms_to_nanos(d); } 120 | 121 | #ifdef RHR_ENCODING 122 | #define RHR_ASCII_ENCODING(s) s = rb_enc_associate_index(s, rhrd_encoding_index); \ 123 | if(rb_default_internal_encoding()) {s = rb_str_export_to_enc(s, rb_default_internal_encoding());} 124 | #else 125 | #define RHR_ASCII_ENCODING(s) /* do nothing */ 126 | #endif 127 | 128 | #ifdef RUBY186 129 | #define RHR_RETURN_RESIZED_STR(s, len) return rb_str_resize(s, len); 130 | #else 131 | #define RHR_RETURN_RESIZED_STR(s, len) rb_str_set_len(s, len); RHR_ASCII_ENCODING(s); return s; 132 | #endif 133 | 134 | #define RHR_SPACE_SHIP(x, l, r) if (l < r) { x = -1; } else if (l == r) { x = 0; } else { x = 1; } 135 | 136 | #define RHR_CHECK_JD(d) if ((d->jd > RHR_JD_MAX) || (d->jd < RHR_JD_MIN)) { rb_raise(rb_eRangeError, "date out of range: jd = %ld", d->jd);} 137 | #define RHR_CHECK_CIVIL(d) if (!rhrd__valid_civil_limits(d->year, d->month, d->day)) { rb_raise(rb_eRangeError, "date out of range: year = %ld, month = %d, day = %d", d->year, (int)d->month, (int)d->day);} 138 | 139 | #define RHR_CACHED_IV(self, iv) VALUE v = rb_ivar_get(self, iv); if (RTEST(v)) {return v;} 140 | 141 | typedef struct rhrd_s { 142 | long jd; 143 | long year; 144 | unsigned char month; 145 | unsigned char day; 146 | unsigned char flags; 147 | } rhrd_t; 148 | 149 | typedef struct rhrdt_s { 150 | long long nanos; /* Nanoseconds since start of day */ 151 | long jd; 152 | long year; 153 | short offset; /* Offset from UTC in minutes */ 154 | unsigned char month; 155 | unsigned char day; 156 | unsigned char hour; 157 | unsigned char minute; 158 | unsigned char second; 159 | unsigned char flags; 160 | } rhrdt_t; 161 | 162 | void rhrdt__civil_to_jd(rhrdt_t *d); 163 | void rhrdt__hms_to_nanos(rhrdt_t *d); 164 | int rhrd__leap_year(long year); 165 | int rhrd__valid_civil_limits(long year, long month, long day); 166 | long rhrd__ymd_to_jd(long year, long month, long day); 167 | long rhrd__commercial_to_jd(long cwyear, long cweek, long cwday); 168 | void rhrd__fill_commercial(rhrd_t *d); 169 | long rhrd__unix_to_jd(long long t); 170 | long rhrd__mod(long a, long b); 171 | long rhrd__modll(long long a, long b); 172 | long rhrd__safe_add_long(long a, long b); 173 | unsigned char rhrd__days_in_month(long year, unsigned char month); 174 | int rhrd__fill_from_hash(rhrd_t *d, VALUE hash); 175 | void rhrd__today(rhrd_t * d); 176 | VALUE rhrd__strptime(VALUE rstr, const char *fmt_str, long fmt_len); 177 | long rhrd__jd_to_wday(long jd); 178 | void rhrd__set_cw_ivs(VALUE self, rhrd_t *d); 179 | void rhrd__civil_to_jd(rhrd_t *d); 180 | VALUE rhrd_s_zone_to_diff(VALUE self, VALUE zone); 181 | VALUE rhrd__strftime(rhrdt_t *d, const char * fmt, int fmt_len); 182 | long rhrd__ordinal_day(long year, unsigned char month, unsigned char day); 183 | VALUE rhrd__ragel_parse(char * p, long len); 184 | VALUE rhrdt__new_offset(VALUE self, double offset); 185 | long rhrdt__spaceship(rhrdt_t *dt, rhrdt_t *odt); 186 | void Init_datetime(void); 187 | 188 | #endif /* DATE_EXT_H */ 189 | -------------------------------------------------------------------------------- /ext/date_ext/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | $CFLAGS << " -DRUBY19" if RUBY_VERSION >= '1.9.0' 3 | $CFLAGS << " -DRUBY186" if RUBY_VERSION < '1.8.7' 4 | $CFLAGS << " -Wall " unless RUBY_PLATFORM =~ /solaris/ 5 | $CFLAGS << ' -g -ggdb -rdynamic -O0 -DDEBUG' if ENV['DEBUG'] 6 | $CFLAGS << " -Wconversion -Wsign-compare -Wno-unused-parameter -Wwrite-strings -Wpointer-arith -fno-common -pedantic -Wno-long-long" if ENV['STRICT'] 7 | $CFLAGS << (ENV['CFLAGS'] || '') 8 | create_makefile("date_ext") 9 | -------------------------------------------------------------------------------- /home_run.gemspec: -------------------------------------------------------------------------------- 1 | HOME_RUN_GEMSPEC = Gem::Specification.new do |s| 2 | s.name = 'home_run' 3 | s.version = '1.0.9' 4 | s.platform = Gem::Platform::RUBY 5 | s.has_rdoc = true 6 | s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "LICENSE"] 7 | s.rdoc_options += ["--quiet", "--line-numbers", "--inline-source", '--title', 'home_run: Fast Date/DateTime classes for ruby', '--main', 'README.rdoc'] 8 | s.summary = "Fast Date/DateTime classes for ruby" 9 | s.author = "Jeremy Evans" 10 | s.email = "code@jeremyevans.net" 11 | s.homepage = "http://github.com/jeremyevans/home_run" 12 | s.required_ruby_version = ">= 1.8.6" 13 | s.files = %w(LICENSE CHANGELOG README.rdoc Rakefile default.mspec bin/home_run) + Dir["{lib,ext,spec,bench}/**/*.{c,h,rb,rl}"] 14 | s.extensions << 'ext/date_ext/extconf.rb' 15 | s.executables << 'home_run' 16 | s.description = < 0 end 14 | 15 | def d() @d end 16 | 17 | protected :d 18 | 19 | def zero? () false end 20 | def finite? () false end 21 | def infinite? () d.nonzero? end 22 | def nan? () d.zero? end 23 | 24 | def abs() self.class.new end 25 | 26 | def -@ () self.class.new(-d) end 27 | def +@ () self.class.new(+d) end 28 | 29 | def <=> (other) 30 | case other 31 | when Infinity; return d <=> other.d 32 | when Numeric; return d 33 | else 34 | begin 35 | l, r = other.coerce(self) 36 | return l <=> r 37 | rescue NoMethodError 38 | end 39 | end 40 | nil 41 | end 42 | 43 | def coerce(other) 44 | case other 45 | when Numeric; return -d, d 46 | else 47 | super 48 | end 49 | end 50 | 51 | def to_f 52 | return 0 if @d == 0 53 | if @d > 0 54 | Float::INFINITY 55 | else 56 | -Float::INFINITY 57 | end 58 | end 59 | end 60 | end 61 | 62 | require "date/format" unless defined?(Date::Format::ZONES) 63 | -------------------------------------------------------------------------------- /lib/home_run.rb: -------------------------------------------------------------------------------- 1 | Object.send(:remove_const, :Date) if defined?(Date) 2 | Object.send(:remove_const, :DateTime) if defined?(DateTime) 3 | dir = File.dirname(File.expand_path(__FILE__)) 4 | load File.join(dir, 'date.rb') 5 | load File.join(dir, 'date', 'format.rb') unless defined?(Date::Format) 6 | -------------------------------------------------------------------------------- /spec/date/accessor_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#ajd" do 4 | it "should be able to determine the Astronomical Julian day for a date" do 5 | Date.civil(2007, 1, 17).ajd.should == 2454118 6 | end 7 | end 8 | 9 | describe "Date#amjd" do 10 | it "should be able to determine the Astronomical Modified Julian day for a date" do 11 | Date.civil(2007, 1, 17).amjd.should == 54117 12 | end 13 | end 14 | 15 | describe "Date#day_fraction" do 16 | it "should be able to determine the day fraction for a date" do 17 | Date.civil(2007, 1, 17).day_fraction.should == 0 18 | end 19 | end 20 | 21 | describe "Date#jd" do 22 | it "should be able to determine the julian date for a date" do 23 | Date.civil(2007, 1, 17).jd.should == 2454118 24 | Date.civil(2008, 10, 28).jd.should == 2454768 25 | Date.commercial(2008, 1, 1).jd.should == 2454466 26 | Date.commercial(2008, 52, 1).jd.should == 2454823 27 | Date.jd(2454782).jd.should == 2454782 28 | Date.jd(2454832).jd.should == 2454832 29 | Date.ordinal(2008, 1).jd.should == 2454467 30 | Date.ordinal(2008, 359).jd.should == 2454825 31 | Date.ordinal(2008, 366).jd.should == 2454832 32 | end 33 | end 34 | 35 | describe "Date#mjd" do 36 | it "should be able to determine the Modified Julian day for a date" do 37 | Date.civil(2007, 1, 17).mjd.should == 54117 38 | end 39 | end 40 | 41 | describe "Date#ld" do 42 | it "should be able to determine the Modified Julian day for a date" do 43 | Date.civil(2007, 1, 17).ld.should == 154958 44 | end 45 | end 46 | 47 | describe "Date#year" do 48 | it "should be able to determine the year for a date" do 49 | Date.civil(2007, 1, 17).year.should == 2007 50 | Date.civil(2008, 1, 17).year.should == 2008 51 | Date.commercial(2008, 1, 1).year.should == 2007 52 | Date.commercial(2008, 52, 1).year.should == 2008 53 | Date.jd(2454782).year.should == 2008 54 | Date.jd(2454833).year.should == 2009 55 | Date.ordinal(2008, 1).year.should == 2008 56 | Date.ordinal(2008, 170).year.should == 2008 57 | Date.ordinal(2008, 366).year.should == 2008 58 | end 59 | end 60 | 61 | describe "Date#yday" do 62 | it "should be able to determine the year for a date" do 63 | Date.civil(2007, 1, 17).yday.should == 17 64 | Date.civil(2008, 10, 28).yday.should == 302 65 | Date.commercial(2008, 1, 1).yday.should == 365 66 | Date.commercial(2008, 52, 1).yday.should == 357 67 | Date.jd(2454782).yday.should == 316 68 | Date.jd(2454832).yday.should == 366 69 | Date.ordinal(2008, 1).yday.should == 1 70 | Date.ordinal(2008, 170).yday.should == 170 71 | Date.ordinal(2008, 366).yday.should == 366 72 | end 73 | end 74 | 75 | describe "Date#mon and #month" do 76 | it "should be able to determine the month for a date" do 77 | Date.civil(2007, 1, 17).mon.should == 1 78 | Date.civil(2008, 10, 28).mon.should == 10 79 | Date.civil(2007, 1, 17).month.should == 1 80 | Date.civil(2008, 10, 28).month.should == 10 81 | Date.commercial(2008, 1, 1).mon.should == 12 82 | Date.commercial(2008, 52, 1).mon.should == 12 83 | Date.jd(2454782).mon.should == 11 84 | Date.jd(2454832).mon.should == 12 85 | Date.ordinal(2008, 1).mon.should == 1 86 | Date.ordinal(2008, 170).mon.should == 6 87 | Date.ordinal(2008, 366).mon.should == 12 88 | end 89 | end 90 | 91 | describe "Date#mday and #day" do 92 | it "should be able to determine the day of the month for a date" do 93 | Date.civil(2007, 1, 17).mday.should == 17 94 | Date.civil(2008, 10, 28).mday.should == 28 95 | Date.civil(2007, 1, 17).day.should == 17 96 | Date.civil(2008, 10, 28).day.should == 28 97 | Date.commercial(2008, 1, 1).day.should == 31 98 | Date.commercial(2008, 52, 1).day.should == 22 99 | Date.jd(2454782).day.should == 11 100 | Date.jd(2454832).day.should == 31 101 | Date.ordinal(2008, 1).day.should == 1 102 | Date.ordinal(2008, 359).day.should == 24 103 | Date.ordinal(2008, 366).day.should == 31 104 | end 105 | end 106 | 107 | describe "Date#wday" do 108 | it "should be able to determine the week day for a date" do 109 | Date.civil(2007, 1, 17).wday.should == 3 110 | Date.civil(2008, 10, 26).wday.should == 0 111 | Date.commercial(2008, 1, 1).wday.should == 1 112 | Date.commercial(2008, 52, 1).wday.should == 1 113 | Date.jd(2454782).wday.should == 2 114 | Date.jd(2454832).wday.should == 3 115 | Date.ordinal(2008, 1).wday.should == 2 116 | Date.ordinal(2008, 170).wday.should == 3 117 | Date.ordinal(2008, 366).wday.should == 3 118 | end 119 | end 120 | 121 | describe "Date#cwyear" do 122 | it "should be able to determine the commercial year for a date" do 123 | Date.civil(2007, 1, 17).cwyear.should == 2007 124 | Date.civil(2008, 10, 28).cwyear.should == 2008 125 | Date.civil(2007, 12, 31).cwyear.should == 2008 126 | Date.civil(2010, 1, 1).cwyear.should == 2009 127 | Date.commercial(2008, 1, 1).cwyear.should == 2008 128 | Date.commercial(2008, 52, 1).cwyear.should == 2008 129 | Date.jd(2454782).cwyear.should == 2008 130 | Date.jd(2454832).cwyear.should == 2009 131 | Date.ordinal(2008, 1).cwyear.should == 2008 132 | Date.ordinal(2008, 359).cwyear.should == 2008 133 | Date.ordinal(2008, 366).cwyear.should == 2009 134 | end 135 | end 136 | 137 | describe "Date#cweek" do 138 | it "should be able to determine the commercial week for a date" do 139 | Date.civil(2007, 1, 17).cweek.should == 3 140 | Date.civil(2008, 10, 28).cweek.should == 44 141 | Date.civil(2007, 12, 31).cweek.should == 1 142 | Date.civil(2010, 1, 1).cweek.should == 53 143 | Date.commercial(2008, 1, 1).cweek.should == 1 144 | Date.commercial(2008, 10, 5).cweek.should == 10 145 | Date.jd(2454782).cweek.should == 46 146 | Date.jd(2454789).cweek.should == 47 147 | Date.ordinal(2008, 1).cweek.should == 1 148 | Date.ordinal(2008, 359).cweek.should == 52 149 | Date.ordinal(2008, 366).cweek.should == 1 150 | end 151 | end 152 | 153 | describe "Date#cwday" do 154 | it "should be able to determine the commercial week day for a date" do 155 | Date.civil(2007, 1, 17).cwday.should == 3 156 | Date.civil(2008, 10, 26).cwday.should == 7 157 | Date.commercial(2008, 1, 1).cwday.should == 1 158 | Date.commercial(2008, 10, 5).cwday.should == 5 159 | Date.jd(2454782).cwday.should == 2 160 | Date.jd(2454786).cwday.should == 6 161 | Date.ordinal(2008, 1).cwday.should == 2 162 | Date.ordinal(2008, 317).cwday.should == 3 163 | end 164 | end 165 | 166 | describe "Date#start" do 167 | it "#start should be less than a low number" do 168 | Date.civil(2008, 10, 11).start.should < -(2**30) 169 | end 170 | 171 | ruby_version_is "" ... "1.9" do 172 | it "#sg should be less than a low number" do 173 | Date.civil(2008, 10, 11).sg.should < -(2**30) 174 | end 175 | end 176 | end 177 | -------------------------------------------------------------------------------- /spec/date/add_month_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#>>" do 4 | 5 | it "should add a number of months to a Date" do 6 | (Date.civil(2007,2,27) >> 10).should == Date.civil(2007, 12, 27) 7 | (Date.civil(2007,2,27) >> 10).should == Date.civil(2007, 12, 27) 8 | (Date.commercial(2007,2,2) >> 10).should == Date.commercial(2007, 45, 5) 9 | (Date.jd(2454782) >> 10).should == Date.jd(2455086) 10 | (Date.ordinal(2008, 10) >> 10).should == Date.ordinal(2008, 315) 11 | (Date.civil(2007,2,27) >> 22).should == Date.civil(2008, 12, 27) 12 | (Date.civil(2007,2,27) >> -2).should == Date.civil(2006, 12, 27) 13 | end 14 | 15 | it "should result in the last day of a month if the day doesn't exist" do 16 | d = Date.civil(2008,3,31) >> 1 17 | d.should == Date.civil(2008, 4, 30) 18 | end 19 | 20 | it "should keep the same class as the receiver" do 21 | c = Class.new(Date) 22 | c.jd.>>(-10).should be_kind_of(c) 23 | end 24 | 25 | it "should raise an error on non numeric parameters" do 26 | lambda { Date.civil(2007,2,27) >> "hello" }.should raise_error(TypeError) 27 | lambda { Date.civil(2007,2,27) >> Date.new }.should raise_error(TypeError) 28 | lambda { Date.civil(2007,2,27) >> Object.new }.should raise_error(TypeError) 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /spec/date/add_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#+" do 4 | 5 | it "should add a number of days to a Date" do 6 | (Date.civil(2007,2,27) + 315).should == Date.civil(2008, 1, 8) 7 | (Date.commercial(2007,2,2) + 315).should == Date.commercial(2007, 47, 2) 8 | (Date.jd(2454782) + 315).should == Date.jd(2455097) 9 | (Date.ordinal(2008, 10) + 315).should == Date.ordinal(2008, 325) 10 | end 11 | 12 | it "should add a negative number of days to a Date" do 13 | d = Date.civil(2007,2,27).+(-10) 14 | d.should == Date.civil(2007, 2, 17) 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(Date) 19 | c.jd.+(10).should be_kind_of(c) 20 | end 21 | 22 | it "should raise an error on non numeric parameters" do 23 | lambda { Date.civil(2007,2,27) + "hello" }.should raise_error(TypeError) 24 | lambda { Date.civil(2007,2,27) + Date.new }.should raise_error(TypeError) 25 | lambda { Date.civil(2007,2,27) + Object.new }.should raise_error(TypeError) 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /spec/date/allocate_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date.allocate" do 4 | it "should be the same as jd" do 5 | Date.allocate.should == Date.jd 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/date/boat_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#<=>" do 4 | 5 | it "should be able to compare two same dates" do 6 | (Date.civil(2000, 04, 06) <=> Date.civil(2000, 04, 06)).should == 0 7 | end 8 | 9 | it "should be able to compare two different dates" do 10 | (Date.civil(2000, 04, 05) <=> Date.civil(2000, 04, 06)).should == -1 11 | (Date.civil(2001, 04, 05) <=> Date.civil(2000, 04, 06)).should == 1 12 | end 13 | 14 | it "should be able to compare a Date to a DateTime" do 15 | (Date.civil(2000, 04, 06) <=> DateTime.civil(2000, 04, 06)).should == 0 16 | (Date.civil(2000, 04, 05) <=> DateTime.civil(2000, 04, 06)).should == -1 17 | (Date.civil(2000, 04, 07) <=> DateTime.civil(2000, 04, 06)).should == 1 18 | (Date.civil(2000, 04, 05) <=> DateTime.civil(2000, 04, 05, 1)).should == -1 19 | end 20 | 21 | it "should be able to compare to another numeric" do 22 | (Date.civil(2000, 04, 05) <=> Date.civil(2000, 04, 06).jd).should == -1 23 | (Date.civil(2001, 04, 05) <=> Date.civil(2000, 04, 06).jd).should == 1 24 | end 25 | 26 | end 27 | 28 | describe "Date#between?" do 29 | it "should be true if the date falls in between the two given dates" do 30 | (Date.civil(2000, 04, 06).between?(Date.civil(2000, 04, 05), Date.civil(2000, 04, 07))).should == true 31 | (Date.civil(2000, 04, 06).between?(Date.civil(2000, 04, 06), Date.civil(2000, 04, 07))).should == true 32 | (Date.civil(2000, 04, 06).between?(Date.civil(2000, 04, 05), Date.civil(2000, 04, 06))).should == true 33 | end 34 | 35 | it "should be false if the date does not fall in between the two given dates" do 36 | (Date.civil(2000, 04, 05).between?(Date.civil(2000, 04, 06), Date.civil(2000, 04, 07))).should == false 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/date/civil_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe :date_civil, :shared => true do 4 | it "creates a Date with jd 0 by default" do 5 | d = Date.send(@method) 6 | d.year.should == -4713 7 | d.month.should == 11 8 | d.day.should == 24 9 | d.julian?.should == false 10 | d.jd.should == 0 11 | end 12 | 13 | it "creates a date with arguments" do 14 | d = Date.send(@method, 2000, 3, 5) 15 | d.year.should == 2000 16 | d.month.should == 3 17 | d.day.should == 5 18 | d.julian?.should == false 19 | d.jd.should == 2451609 20 | 21 | # Should also work with years far in the past and future 22 | 23 | d = Date.send(@method, -9000, 7, 5) 24 | d.year.should == -9000 25 | d.month.should == 7 26 | d.day.should == 5 27 | d.julian?.should == false 28 | d.jd.should == -1565937 29 | 30 | d = Date.send(@method, 9000, 10, 14) 31 | d.year.should == 9000 32 | d.month.should == 10 33 | d.day.should == 14 34 | d.julian?.should == false 35 | d.jd.should == 5008529 36 | 37 | end 38 | 39 | it "raises errors for invalid dates" do 40 | lambda { Date.send(@method, 2000, 13, 31) }.should raise_error(ArgumentError) 41 | lambda { Date.send(@method, 2000, 12, 32) }.should raise_error(ArgumentError) 42 | lambda { Date.send(@method, 2000, 2, 30) }.should raise_error(ArgumentError) 43 | lambda { Date.send(@method, 1900, 2, 29) }.should raise_error(ArgumentError) 44 | lambda { Date.send(@method, 2000, 2, 29) }.should_not raise_error(ArgumentError) 45 | 46 | lambda { Date.send(@method, 1582, 10, 15) }.should_not raise_error(ArgumentError) 47 | 48 | end 49 | end 50 | 51 | describe "Date.civil" do 52 | it_behaves_like(:date_civil, :civil) 53 | 54 | it "should have defaults and an optional sg value" do 55 | Date.civil.should == Date.jd 56 | Date.civil(2008).should == Date.civil(2008, 1, 1) 57 | Date.civil(2008, 1).should == Date.civil(2008, 1, 1) 58 | Date.civil(2008, 1, 1).should == Date.civil(2008, 1, 1) 59 | Date.civil(2008, 1, 1, 1).should == Date.civil(2008, 1, 1) 60 | end 61 | 62 | it "should not accept more than 4 arguments" do 63 | proc{Date.civil(2008, 1, 1, 1, 1)}.should raise_error(ArgumentError) 64 | end 65 | 66 | it "should raise ArgumentError for invalid dates" do 67 | proc{Date.civil(2008, 2, 30)}.should raise_error(ArgumentError) 68 | proc{Date.civil(2009, 2, 29)}.should raise_error(ArgumentError) 69 | end 70 | 71 | it "should keep the same class as the receiver" do 72 | c = Class.new(Date) 73 | c.civil.should be_kind_of(c) 74 | end 75 | end 76 | 77 | describe "Date.new" do 78 | it_behaves_like(:date_civil, :new) 79 | end 80 | 81 | ruby_version_is "" ... "1.9" do 82 | describe "Date.new3" do 83 | it_behaves_like(:date_civil, :new3) 84 | end 85 | end 86 | 87 | describe "Date.valid_civil?" do 88 | 89 | ruby_version_is "" ... "1.9" do 90 | it "should be able to determine if a date is valid" do 91 | Date.valid_civil?(1582, 10, 14).should == Date.civil(1582, 10, 14).jd 92 | Date.valid_civil?(1582, 10, 15).should == Date.civil(1582, 10, 15).jd 93 | Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should_not == nil 94 | Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd 95 | Date.valid_civil?(2007, 2, 24).should == 2454156 96 | Date.valid_civil?(2007, 2, 24, 1).should == 2454156 97 | Date.valid_civil?(2007, 2, 30, 1).should == nil 98 | end 99 | 100 | it "#valid_date? should be the same as valid_civil?" do 101 | Date.valid_date?(2007, 2, 24, 1).should == Date.valid_civil?(2007, 2, 24, 1) 102 | end 103 | 104 | it "#exist? should be the same as valid_date?" do 105 | Date.exist?(2007, 2, 24, 1).should == Date.valid_date?(2007, 2, 24, 1) 106 | end 107 | 108 | it "#exist3? should be the same as valid_date?" do 109 | Date.exist3?(2007, 2, 24, 1).should == Date.valid_date?(2007, 2, 24, 1) 110 | end 111 | 112 | it "should be able to handle negative months and days" do 113 | Date.valid_civil?(1582, -3, -31).should == Date.civil(1582, 10, 1).jd 114 | Date.valid_civil?(1582, -3, -28).should == Date.civil(1582, 10, 4).jd 115 | Date.valid_civil?(1582, -3, -27).should == Date.civil(1582, 10, 5).jd 116 | Date.valid_civil?(1582, -3, -22).should == Date.civil(1582, 10, 10).jd 117 | Date.valid_civil?(1582, -3, -21).should == Date.civil(1582, 10, 11).jd 118 | Date.valid_civil?(1582, -3, -18).should == Date.civil(1582, 10, 14).jd 119 | Date.valid_civil?(1582, -3, -17).should == Date.civil(1582, 10, 15).jd 120 | 121 | Date.valid_civil?(2007, -11, -10).should == Date.civil(2007, 2, 19).jd 122 | Date.valid_civil?(2008, -11, -10).should == Date.civil(2008, 2, 20).jd 123 | end 124 | end 125 | 126 | ruby_version_is "1.9" do 127 | it "should be able to determine if a date is valid" do 128 | Date.valid_civil?(1582, 10, 14).should == true 129 | Date.valid_civil?(1582, 10, 15).should == true 130 | Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should == true 131 | Date.valid_civil?(2007, 2, 24).should == true 132 | Date.valid_civil?(2007, 2, 24, 1).should == true 133 | Date.valid_civil?(2007, 2, 30, 1).should == false 134 | end 135 | 136 | it "#valid_date? should be the same as valid_civil?" do 137 | Date.valid_date?(2007, 2, 24, 1).should == Date.valid_civil?(2007, 2, 24, 1) 138 | Date.valid_date?(2007, 2, 30, 1).should == Date.valid_civil?(2007, 2, 30, 1) 139 | end 140 | 141 | it "should be able to handle negative months and days" do 142 | Date.valid_civil?(1582, -3, -22).should == true 143 | Date.valid_civil?(1582, -3, -21).should == true 144 | Date.valid_civil?(1582, -3, -18).should == true 145 | Date.valid_civil?(1582, -3, -17).should == true 146 | 147 | Date.valid_civil?(2007, -11, -10).should == true 148 | Date.valid_civil?(2008, -11, -10).should == true 149 | end 150 | end 151 | end 152 | -------------------------------------------------------------------------------- /spec/date/clone_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#clone" do 4 | before do 5 | @d = Date.today 6 | end 7 | 8 | it "should return a copy of the date" do 9 | @d.clone.should == @d 10 | end 11 | 12 | it "should return a different object_id" do 13 | @d.clone.object_id.should_not == @d.object_id 14 | end 15 | 16 | it "should keep frozen status" do 17 | @d.freeze 18 | @d.clone.frozen?.should be_true 19 | end 20 | 21 | it "should keep singleton_methods" do 22 | class << @d; def foo() 1 end end 23 | @d.clone.respond_to?(:foo).should be_true 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/date/commercial_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe :date_commercial, :shared => true do 4 | ruby_version_is "" ... "1.9" do 5 | it "creates a Date for the day of Julian calendar reform in Italy by default" do 6 | d = Date.send(@method) 7 | d.year.should == 1582 8 | d.month.should == 10 9 | d.day.should == 15 10 | end 11 | end 12 | 13 | ruby_version_is "1.9" do 14 | it "creates a Date for Julian Day Number day 0 by default" do 15 | Date.send(@method).jd.should == 0 16 | end 17 | end 18 | 19 | ruby_version_is "" ... "1.9" do 20 | it "Creates a Date for the friday in the year and week given" do 21 | d = Date.send(@method, 2000, 1) 22 | d.year.should == 2000 23 | d.month.should == 1 24 | d.day.should == 7 25 | d.cwday.should == 5 26 | end 27 | end 28 | 29 | ruby_version_is "1.9" do 30 | it "Creates a Date for the monday in the year and week given" do 31 | d = Date.send(@method, 2000, 1) 32 | d.year.should == 2000 33 | d.month.should == 1 34 | d.day.should == 3 35 | d.cwday.should == 1 36 | end 37 | end 38 | 39 | it "Creates a Date for the correct day given the year, week and day number" do 40 | d = Date.send(@method, 2004, 1, 1) 41 | d.year.should == 2003 42 | d.month.should == 12 43 | d.day.should == 29 44 | d.cwday.should == 1 45 | d.cweek.should == 1 46 | d.cwyear.should == 2004 47 | end 48 | 49 | it "raises errors for invalid dates" do 50 | lambda { Date.send(@method, 2004, 53, 1) }.should_not raise_error(ArgumentError) 51 | lambda { Date.send(@method, 2004, 53, 0) }.should raise_error(ArgumentError) 52 | lambda { Date.send(@method, 2004, 53, 8) }.should raise_error(ArgumentError) 53 | lambda { Date.send(@method, 2004, 54, 1) }.should raise_error(ArgumentError) 54 | lambda { Date.send(@method, 2004, 0, 1) }.should raise_error(ArgumentError) 55 | 56 | lambda { Date.send(@method, 2003, 52, 1) }.should_not raise_error(ArgumentError) 57 | lambda { Date.send(@method, 2003, 53, 1) }.should raise_error(ArgumentError) 58 | lambda { Date.send(@method, 2003, 52, 0) }.should raise_error(ArgumentError) 59 | lambda { Date.send(@method, 2003, 52, 8) }.should raise_error(ArgumentError) 60 | end 61 | end 62 | 63 | describe "Date.commercial" do 64 | it_behaves_like(:date_commercial, :commercial) 65 | 66 | ruby_version_is "" ... "1.9" do 67 | it "should have defaults and an optional sg value" do 68 | Date.commercial.should == Date.commercial(1582, 41, 5) 69 | Date.commercial(2008).should == Date.commercial(2008, 41, 5) 70 | Date.commercial(2008, 1).should == Date.commercial(2008, 1, 5) 71 | Date.commercial(2008, 1, 1).should == Date.commercial(2008, 1, 1) 72 | Date.commercial(2008, 1, 1, 1).should == Date.commercial(2008, 1, 1) 73 | end 74 | end 75 | 76 | ruby_version_is "1.9" do 77 | it "should have defaults and an optional sg value" do 78 | Date.commercial.should == Date.jd 79 | Date.commercial(2008).should == Date.commercial(2008, 1, 1) 80 | Date.commercial(2008, 1).should == Date.commercial(2008, 1, 1) 81 | Date.commercial(2008, 1, 1).should == Date.commercial(2008, 1, 1) 82 | Date.commercial(2008, 1, 1, 1).should == Date.commercial(2008, 1, 1) 83 | end 84 | end 85 | 86 | it ".should not accept more than 4 arguments" do 87 | proc{Date.commercial(2008, 1, 1, 1, 1)}.should raise_error(ArgumentError) 88 | end 89 | 90 | it "should raise ArgumentError for invalid dates" do 91 | proc{Date.commercial(2008, 54, 6)}.should raise_error(ArgumentError) 92 | proc{Date.commercial(2009, 1, 8)}.should raise_error(ArgumentError) 93 | end 94 | 95 | it "should keep the same class as the receiver" do 96 | c = Class.new(Date) 97 | c.commercial.should be_kind_of(c) 98 | end 99 | end 100 | 101 | ruby_version_is "" ... "1.9" do 102 | describe "Date.neww" do 103 | it_behaves_like(:date_commercial, :neww) 104 | end 105 | end 106 | 107 | describe "Date.valid_commercial?" do 108 | 109 | ruby_version_is "" ... "1.9" do 110 | it "should be able to determine if the date is a valid commercial date" do 111 | Date.valid_commercial?(1582, 41, 4).should == Date.civil(1582, 10, 14).jd 112 | Date.valid_commercial?(1582, 41, 5).should == Date.civil(1582, 10, 15).jd 113 | 114 | Date.valid_commercial?(1582, 41, 4, Date::ENGLAND).should == Date.civil(1582, 10, 14).jd 115 | Date.valid_commercial?(1752, 37, 4, Date::ENGLAND).should == Date.civil(1752, 9, 14, Date::ENGLAND).jd 116 | 117 | Date.valid_commercial?(2007, 45, 1).should == 2454410 118 | Date.valid_commercial?(2007, 45, 1, 1).should == 2454410 119 | Date.valid_commercial?(2007, 54, 1, 1).should == nil 120 | end 121 | 122 | it "#existw? should be the same as valid_commercial?" do 123 | Date.existw?(2007, 45, 1, 1).should == Date.valid_commercial?(2007, 45, 1, 1) 124 | end 125 | 126 | it "should be able to handle negative week and day numbers" do 127 | Date.valid_commercial?(1582, -12, -4).should == Date.civil(1582, 10, 14).jd 128 | Date.valid_commercial?(1582, -12, -3).should == Date.civil(1582, 10, 15).jd 129 | 130 | Date.valid_commercial?(2007, -44, -2).should == Date.civil(2007, 3, 3).jd 131 | Date.valid_commercial?(2008, -44, -2).should == Date.civil(2008, 3, 1).jd 132 | end 133 | end 134 | 135 | ruby_version_is "1.9" do 136 | it "should be able to determine if the date is a valid commercial date" do 137 | Date.valid_commercial?(1582, 39, 4).should == true 138 | Date.valid_commercial?(1582, 39, 5).should == true 139 | Date.valid_commercial?(1582, 41, 4).should == true 140 | Date.valid_commercial?(1582, 41, 5).should == true 141 | Date.valid_commercial?(1582, 41, 4, Date::ENGLAND).should == true 142 | Date.valid_commercial?(1752, 37, 4, Date::ENGLAND).should == true 143 | 144 | Date.valid_commercial?(2007, 45, 1).should == true 145 | Date.valid_commercial?(2007, 45, 1, 1).should == true 146 | Date.valid_commercial?(2007, 54, 1, 1).should == false 147 | end 148 | 149 | it "should be able to handle negative week and day numbers" do 150 | Date.valid_commercial?(1582, -12, -4).should == true 151 | Date.valid_commercial?(1582, -12, -3).should == true 152 | 153 | Date.valid_commercial?(2007, -44, -2).should == true 154 | Date.valid_commercial?(2008, -44, -2).should == true 155 | end 156 | end 157 | 158 | end 159 | -------------------------------------------------------------------------------- /spec/date/constants_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date constants" do 4 | 5 | it "should define ITALY" do 6 | Date::ITALY.should == 2299161 # 1582-10-15 7 | end 8 | 9 | it "should define ENGLAND" do 10 | Date::ENGLAND.should == 2361222 # 1752-09-14 11 | end 12 | 13 | # Fixes in 1.8.7 14 | ruby_bug "#", "1.8.6" do 15 | it "should define JULIAN" do 16 | (Date::JULIAN <=> 2**30).should == 1 17 | end 18 | end 19 | 20 | # Fixed in 1.8.7 21 | ruby_bug "#", "1.8.6" do 22 | it "should define GREGORIAN" do 23 | (Date::GREGORIAN <=> -(2**30)).should == -1 24 | end 25 | end 26 | 27 | it "should define MONTHNAMES" do 28 | Date::MONTHNAMES.should == [nil] + %w(January February March April May June July 29 | August September October November December) 30 | end 31 | 32 | it "should define DAYNAMES" do 33 | Date::DAYNAMES.should == %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) 34 | end 35 | 36 | it "should define ABBR_MONTHNAMES" do 37 | Date::ABBR_MONTHNAMES.should == [nil] + %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) 38 | end 39 | 40 | it "should define ABBR_DAYNAMES" do 41 | Date::ABBR_DAYNAMES.should == %w(Sun Mon Tue Wed Thu Fri Sat) 42 | end 43 | 44 | end 45 | -------------------------------------------------------------------------------- /spec/date/conversions_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#new_start" do 4 | it "should convert a date object into another with a new calendar reform" do 5 | Date.civil(1582, 10, 14, Date::ENGLAND).new_start.should == Date.civil(1582, 10, 14) 6 | Date.civil(1582, 10, 4, Date::ENGLAND).new_start.should == Date.civil(1582, 10, 4) 7 | Date.civil(1582, 10, 15).new_start(Date::ENGLAND).should == Date.civil(1582, 10, 15, Date::ENGLAND) 8 | Date.civil(1752, 9, 14).new_start(Date::ENGLAND).should == Date.civil(1752, 9, 14, Date::ENGLAND) 9 | Date.civil(1752, 9, 13).new_start(Date::ENGLAND).should == Date.civil(1752, 9, 13, Date::ENGLAND) 10 | end 11 | 12 | it "should keep the same class as the receiver" do 13 | c = Class.new(Date) 14 | c.jd.new_start.should be_kind_of(c) 15 | end 16 | 17 | ruby_version_is "" ... "1.9" do 18 | it "#newsg should be the same as new_start" do 19 | Date.civil(1582, 10, 14, Date::ENGLAND).newsg.should == Date.civil(1582, 10, 14, Date::ENGLAND).new_start 20 | Date.civil(1582, 10, 14, Date::ENGLAND).newsg(1).should == Date.civil(1582, 10, 14, Date::ENGLAND).new_start(1) 21 | end 22 | end 23 | end 24 | 25 | describe "Date#italy" do 26 | it "should convert a date object into another with the Italian calendar reform" do 27 | Date.civil(1582, 10, 14, Date::ENGLAND).italy.should == Date.civil(1582, 10, 14) 28 | Date.civil(1582, 10, 4, Date::ENGLAND).italy.should == Date.civil(1582, 10, 4) 29 | end 30 | end 31 | 32 | describe "Date#england" do 33 | it "should convert a date object into another with the English calendar reform" do 34 | Date.civil(1582, 10, 15).england.should == Date.civil(1582, 10, 15, Date::ENGLAND) 35 | Date.civil(1752, 9, 14).england.should == Date.civil(1752, 9, 14, Date::ENGLAND) 36 | Date.civil(1752, 9, 13).england.should == Date.civil(1752, 9, 13, Date::ENGLAND) 37 | end 38 | end 39 | 40 | describe "Date#julian" do 41 | it "should convert a date object into another with the Julian calendar" do 42 | Date.civil(1582, 10, 15).julian.should == Date.civil(1582, 10, 15, Date::JULIAN) 43 | Date.civil(1752, 9, 14).julian.should == Date.civil(1752, 9, 14, Date::JULIAN) 44 | Date.civil(1752, 9, 13).julian.should == Date.civil(1752, 9, 13, Date::JULIAN) 45 | end 46 | end 47 | 48 | describe "Date#gregorian" do 49 | it "should convert a date object into another with the Gregorian calendar" do 50 | Date.civil(1582, 10, 14).gregorian.should == Date.civil(1582, 10, 14, Date::GREGORIAN) 51 | Date.civil(1752, 9, 14).gregorian.should == Date.civil(1752, 9, 14, Date::GREGORIAN) 52 | end 53 | 54 | it "should keep the same class as the receiver" do 55 | c = Class.new(Date) 56 | c.jd.gregorian.should be_kind_of(c) 57 | end 58 | end 59 | 60 | ruby_version_is "" ... "1.9" do 61 | describe "Date#ordinal_to_jd" do 62 | it "should convert an ordinal date (year-day) to a Julian day number" do 63 | Date.ordinal_to_jd(2007, 55).should == 2454156 64 | end 65 | end 66 | 67 | describe "Date#jd_to_ordinal" do 68 | it "should convert a Julian day number into an ordinal date" do 69 | Date.jd_to_ordinal(2454156).should == [2007, 55] 70 | Date.jd_to_ordinal(2454156, 1).should == [2007, 55] 71 | end 72 | end 73 | 74 | describe "Date#civil_to_jd" do 75 | it "should convert a civil date into a Julian day number" do 76 | Date.civil_to_jd(2007, 2, 24).should == 2454156 77 | Date.civil_to_jd(2007, 2, 24, 1).should == 2454156 78 | end 79 | end 80 | 81 | describe "Date#jd_to_civil" do 82 | it "should convert a Julian day into a civil date" do 83 | Date.jd_to_civil(2454156).should == [2007, 2, 24] 84 | Date.jd_to_civil(2454156, 1).should == [2007, 2, 24] 85 | end 86 | end 87 | 88 | describe "Date#commercial_to_jd" do 89 | it "should convert a commercial date (year - week - day of week) into a Julian day number" do 90 | Date.commercial_to_jd(2007, 45, 1).should == 2454410 91 | Date.commercial_to_jd(2007, 45, 1, 1).should == 2454410 92 | end 93 | end 94 | 95 | describe "Date#jd_to_commercial" do 96 | it "should convert a Julian day number into a commercial date" do 97 | Date.jd_to_commercial(2454410).should == [2007, 45, 1] 98 | Date.jd_to_commercial(2454410, 1).should == [2007, 45, 1] 99 | end 100 | end 101 | 102 | describe "Date#ajd_to_jd" do 103 | it "should convert a Astronomical Julian day number into a Julian day number" do 104 | Date.ajd_to_jd(2454410).should == [2454410, 0.5] 105 | Date.ajd_to_jd(2454410, 1.0/ 2).should == [2454410, 0.5] 106 | Date.ajd_to_jd(1).should == [1, 0.5] 107 | Date.ajd_to_jd(1, 1).should == [1, 0.5] 108 | end 109 | end 110 | 111 | describe "Date#jd_to_ajd" do 112 | it "should convert a Julian day number into a Astronomical Julian day number" do 113 | Date.jd_to_ajd(2454410, 0).should == 2454410 114 | Date.jd_to_ajd(2454410, 1.0/ 2).should == 2454410 115 | Date.jd_to_ajd(2454156, 0).should == 2454156 116 | Date.jd_to_ajd(2454156, 1, 1).should == 2454156 117 | end 118 | end 119 | 120 | describe "Date#day_fraction_to_time" do 121 | it "should be able to convert a day fraction into time" do 122 | Date.day_fraction_to_time(2).should == [48, 0, 0, 0] 123 | Date.day_fraction_to_time(1).should == [24, 0, 0, 0] 124 | Date.day_fraction_to_time(1.0/ 2).should == [12, 0, 0, 0] 125 | a = Date.day_fraction_to_time(1.0/ 7) 126 | a.pop.should be_close(1.0/ 100800, 0.00003) 127 | a.should == [3, 25, 42] 128 | end 129 | end 130 | 131 | describe "Date#time_to_day_fraction" do 132 | it "should be able to convert a time into a day fraction" do 133 | Date.time_to_day_fraction(48, 0, 0).should == 2.0 134 | Date.time_to_day_fraction(24, 0, 0).should == 1.0 135 | Date.time_to_day_fraction(12, 0, 0).should == 0.5 136 | Date.time_to_day_fraction(10, 20, 10).should == 10.0/24.0 + 20.0/(24 * 60) + 10.0/(24 * 60 * 60) 137 | end 138 | end 139 | 140 | describe "Date#amjd_to_ajd" do 141 | it "shoud be able to convert Astronomical Modified Julian day numbers into Astronomical Julian day numbers" do 142 | Date.amjd_to_ajd(10).should == 2400010 143 | end 144 | end 145 | 146 | describe "Date#ajd_to_amjd" do 147 | it "shoud be able to convert Astronomical Julian day numbers into Astronomical Modified Julian day numbers" do 148 | Date.ajd_to_amjd(10000010).should == 7600009 149 | end 150 | end 151 | 152 | describe "Date#mjd_to_jd" do 153 | it "shoud be able to convert Modified Julian day numbers into Julian day numbers" do 154 | Date.mjd_to_jd(2000).should == 2000 + 2400001 155 | end 156 | end 157 | 158 | describe "Date#jd_to_mjd" do 159 | it "shoud be able to convert Julian day numbers into Modified Julian day numbers" do 160 | Date.jd_to_mjd(2500000).should == 2500000 - 2400001 161 | end 162 | end 163 | 164 | describe "Date#ld_to_jd" do 165 | it "should be able to convert the number of days since the Gregorian calendar in Italy into Julian day numbers" do 166 | Date.ld_to_jd(450000).should == 450000 + 2299160 167 | end 168 | end 169 | 170 | describe "Date#jd_to_ld" do 171 | it "should be able to convert Julian day numbers into the number of days since the Gregorian calendar in Italy" do 172 | Date.jd_to_ld(2450000).should == 2450000 - 2299160 173 | end 174 | end 175 | 176 | describe "Date#jd_to_wday" do 177 | it "should be able to convert a Julian day number into a week day number" do 178 | Date.jd_to_wday(2454482).should == 3 179 | end 180 | end 181 | end 182 | 183 | describe "Date instance methods" do 184 | before do 185 | @d = Date.civil(2008, 10, 11) 186 | end 187 | 188 | it "#ajd should be the same as jd" do 189 | @d.ajd.should == @d.jd 190 | end 191 | 192 | it "#amjd should be the astronomical modified julian date" do 193 | @d.amjd.should == 54750 194 | end 195 | 196 | it "#ld should be the days since italian calendar reform day" do 197 | @d.ld.should == 155591 198 | end 199 | 200 | it "#mjd should be the modified julian date" do 201 | @d.mjd.should == 54750 202 | end 203 | end 204 | 205 | ruby_version_is "" ... "1.9" do 206 | describe "Date.valid_time?" do 207 | it " should return corresponding day fraction if valid and nil if not" do 208 | Date.valid_time?(12, 0, 0).should == 0.5 209 | Date.valid_time?(25, 0, 0).should == nil 210 | Date.valid_time?(12, 61, 0).should == nil 211 | Date.valid_time?(12, 0, 61).should == nil 212 | end 213 | end 214 | end 215 | 216 | describe "Date marshalling" do 217 | it "should marshal and unmarshal correctly" do 218 | Marshal.load(Marshal.dump(Date.jd)).should == Date.civil 219 | Marshal.load(Marshal.dump(Date.today)).should == Date.today 220 | Marshal.load(Marshal.dump(Date.civil(2010, 2, 4))).should == Date.civil(2010, 2, 4) 221 | end 222 | end 223 | 224 | ruby_version_is "1.9" do 225 | describe "Date#to_date" do 226 | it " should return the receiver" do 227 | Date.new(2009, 1, 2).to_date.should == Date.new(2009, 1, 2) 228 | end 229 | end 230 | 231 | describe "Date#to_datetime" do 232 | it " should return a DateTime equal to the receiver" do 233 | Date.new(2009, 1, 2).to_datetime.should == DateTime.new(2009, 1, 2) 234 | end 235 | end 236 | 237 | describe "Date#to_time" do 238 | it " should return a Time in local time with the same year, month, day as the receiver" do 239 | Date.new(2009, 1, 2).to_time.should == Time.local(2009, 1, 2) 240 | end 241 | end 242 | 243 | describe "Time#to_date" do 244 | it " should return a Date with the same year, month, and day as the receiver" do 245 | Time.local(2009, 1, 2).to_date.should == Date.new(2009, 1, 2) 246 | end 247 | end 248 | 249 | describe "Time#to_time" do 250 | it " should return the receiver in local time" do 251 | Time.local(2009, 1, 2).to_time.should == Time.local(2009, 1, 2) 252 | Time.local(2009, 1, 2).getutc.to_time.should == Time.local(2009, 1, 2) 253 | end 254 | end 255 | end 256 | 257 | -------------------------------------------------------------------------------- /spec/date/day_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "Date#sunday?" do 5 | it "should return true if the day is a Sunday" do 6 | Date.civil(2009,1,4).sunday?.should == true 7 | end 8 | 9 | it "should return false if the day is not a Sunday" do 10 | Date.civil(2009,1,2).sunday?.should == false 11 | end 12 | end 13 | 14 | describe "Date#monday?" do 15 | it "should return true if the day is a Monday" do 16 | Date.civil(2009,1,5).monday?.should == true 17 | end 18 | 19 | it "should return false if the day is not a Monday" do 20 | Date.civil(2009,1,2).monday?.should == false 21 | end 22 | end 23 | 24 | describe "Date#tuesday?" do 25 | it "should return true if the day is a Tuesday" do 26 | Date.civil(2009,1,6).tuesday?.should == true 27 | end 28 | 29 | it "should return false if the day is not a Tuesday" do 30 | Date.civil(2009,1,2).tuesday?.should == false 31 | end 32 | end 33 | 34 | describe "Date#wednesday?" do 35 | it "should return true if the day is a Wednesday" do 36 | Date.civil(2009,1,7).wednesday?.should == true 37 | end 38 | 39 | it "should return false if the day is not a Tuesday" do 40 | Date.civil(2009,1,2).wednesday?.should == false 41 | end 42 | end 43 | 44 | describe "Date#thursday?" do 45 | it "should return true if the day is a Thursday" do 46 | Date.civil(2009,1,1).thursday?.should == true 47 | end 48 | 49 | it "should return false if the day is not a Thursday" do 50 | Date.civil(2009,1,2).thursday?.should == false 51 | end 52 | end 53 | 54 | describe "Date#friday?" do 55 | it "should return true if the day is a Friday" do 56 | Date.civil(2009,1,2).friday?.should == true 57 | end 58 | 59 | it "should return false if the day is not a Friday" do 60 | Date.civil(2009,1,1).friday?.should == false 61 | end 62 | end 63 | 64 | describe "Date#saturday?" do 65 | it "should return true if the day is a Saturday" do 66 | Date.civil(2009,1,3).saturday?.should == true 67 | end 68 | 69 | it "should return false if the day is not a Saturday" do 70 | Date.civil(2009,1,2).saturday?.should == false 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /spec/date/downto_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#downto" do 4 | 5 | it "should be able to step backward in time" do 6 | ds = Date.civil(2000, 4, 14) 7 | de = Date.civil(2000, 3, 29) 8 | count = 0 9 | ds.downto(de) do |d| 10 | d.should <= ds 11 | d.should >= de 12 | count += 1 13 | end 14 | count.should == 17 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(Date) 19 | c.jd.downto(c.jd - 2) do |d| 20 | d.should be_kind_of(c) 21 | end.should be_kind_of(c) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/date/dup_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#dup" do 4 | before do 5 | @d = Date.today 6 | end 7 | 8 | it "should return a copy of the date" do 9 | @d.dup.should == @d 10 | end 11 | 12 | it "should return a different object_id" do 13 | @d.dup.object_id.should_not == @d.object_id 14 | end 15 | 16 | it "should not keep frozen status" do 17 | @d.freeze 18 | @d.dup.frozen?.should be_false 19 | end 20 | 21 | it "should not keep singleton_methods" do 22 | class << @d; def foo() 1 end end 23 | @d.dup.respond_to?(:foo).should be_false 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/date/encoding_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "Date string encoding methods" do 5 | it "should return strings in US-ASCII encoding by default" do 6 | d = Date.today 7 | d.asctime.encoding.name.should == 'US-ASCII' 8 | d.ctime.encoding.name.should == 'US-ASCII' 9 | d.httpdate.encoding.name.should == 'US-ASCII' 10 | d.inspect.encoding.name.should == 'US-ASCII' 11 | d.iso8601.encoding.name.should == 'US-ASCII' 12 | d.jisx0301.encoding.name.should == 'US-ASCII' 13 | d.rfc2822.encoding.name.should == 'US-ASCII' 14 | d.rfc3339.encoding.name.should == 'US-ASCII' 15 | d.rfc822.encoding.name.should == 'US-ASCII' 16 | d.strftime('%S:%M:%H').encoding.name.should == 'US-ASCII' 17 | d.to_s.encoding.name.should == 'US-ASCII' 18 | d.xmlschema.encoding.name.should == 'US-ASCII' 19 | end 20 | 21 | it "should return strings in default_internal encoding if set" do 22 | begin 23 | Encoding.default_internal = 'UTF-8' 24 | d = Date.today 25 | d.asctime.encoding.name.should == 'UTF-8' 26 | d.ctime.encoding.name.should == 'UTF-8' 27 | d.httpdate.encoding.name.should == 'UTF-8' 28 | d.inspect.encoding.name.should == 'UTF-8' 29 | d.iso8601.encoding.name.should == 'UTF-8' 30 | d.jisx0301.encoding.name.should == 'UTF-8' 31 | d.rfc2822.encoding.name.should == 'UTF-8' 32 | d.rfc3339.encoding.name.should == 'UTF-8' 33 | d.rfc822.encoding.name.should == 'UTF-8' 34 | d.strftime('%S:%M:%H').encoding.name.should == 'UTF-8' 35 | d.to_s.encoding.name.should == 'UTF-8' 36 | d.xmlschema.encoding.name.should == 'UTF-8' 37 | ensure 38 | Encoding.default_internal = nil 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/date/eql_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#eql?" do 4 | it "should be able determine equality between date objects" do 5 | Date.civil(2007, 10, 11).should eql(Date.civil(2007, 10, 11)) 6 | Date.civil(2007, 10, 11).should eql(Date.civil(2007, 10, 12) - 1) 7 | Date.civil(2007, 10, 11).should_not eql(Date.civil(2007, 10, 12)) 8 | end 9 | 10 | it "should be able determine equality between a date and a datetime objects" do 11 | Date.civil(2007, 10, 11).should eql(DateTime.civil(2007, 10, 11)) 12 | Date.civil(2007, 10, 11).should eql(DateTime.civil(2007, 10, 12) - 1) 13 | Date.civil(2007, 10, 11).should_not eql(DateTime.civil(2007, 10, 12)) 14 | Date.civil(2007, 10, 11).should_not eql(DateTime.civil(2007, 10, 11, 1)) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/date/format_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date formatting methods" do 4 | it "#asctime and #ctime should use a format similar to Time" do 5 | Date.new(2008, 1, 2).asctime.should == 'Wed Jan 2 00:00:00 2008' 6 | Date.new(2008, 1, 2).ctime.should == 'Wed Jan 2 00:00:00 2008' 7 | end 8 | 9 | it "#to_s should use an ISO8601 format" do 10 | Date.new(2008, 1, 2).to_s.should == '2008-01-02' 11 | end 12 | 13 | it "#inspect should use an ISO8601 format" do 14 | Date.new(2008, 1, 2).inspect.should == '#' 15 | end 16 | 17 | ruby_version_is "1.9" do 18 | it "#httpdate should use an HTTP format" do 19 | Date.new(2009, 1, 2).httpdate.should == "Fri, 02 Jan 2009 00:00:00 GMT" 20 | end 21 | 22 | it "#iso8601 should use an ISO8601 format" do 23 | Date.new(2009, 1, 2).iso8601.should == "2009-01-02" 24 | end 25 | 26 | it "#jisx03010 should use an JIS X 0301 format" do 27 | Date.new(2009, 1, 2).jisx0301.should == "H21.01.02" 28 | Date.new(1988, 1, 2).jisx0301.should == "S63.01.02" 29 | Date.new(1925, 1, 2).jisx0301.should == "T14.01.02" 30 | Date.new(1911, 1, 2).jisx0301.should == "M44.01.02" 31 | Date.new(1873, 1, 2).jisx0301.should == "M06.01.02" 32 | Date.new(1872, 1, 2).jisx0301.should == "1872-01-02" 33 | Date.new(1867, 1, 2).jisx0301.should == "1867-01-02" 34 | end 35 | 36 | it "#rfc2822 should use an RFC2822 format" do 37 | Date.new(2009, 1, 2).rfc2822.should == "Fri, 2 Jan 2009 00:00:00 +0000" 38 | end 39 | 40 | it "#rfc822 should use an RFC822 format" do 41 | Date.new(2009, 1, 2).rfc822.should == "Fri, 2 Jan 2009 00:00:00 +0000" 42 | end 43 | 44 | it "#rfc3339 should use an RFC3339 format" do 45 | Date.new(2009, 1, 2).rfc3339.should == "2009-01-02T00:00:00+00:00" 46 | end 47 | 48 | it "#xmlschema should use an ISO8601 format" do 49 | Date.new(2009, 1, 2).xmlschema.should == "2009-01-02" 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /spec/date/gregorian_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#gregorian?" do 4 | it "should return true" do 5 | Date.civil(1007, 2, 27).gregorian?.should == true 6 | Date.civil(1907, 2, 27, Date.civil(2000, 1, 1).jd).gregorian?.should == true 7 | end 8 | 9 | ruby_version_is "" ... "1.9" do 10 | it "ns? should be same as gregorian?" do 11 | Date.civil(1007, 2, 27).ns?.should == true 12 | end 13 | end 14 | end 15 | 16 | describe "Date.gregorian_leap?" do 17 | 18 | it "should be able to determine whether a year is a leap year in the Gregorian calendar" do 19 | Date.gregorian_leap?(1900).should == false 20 | Date.gregorian_leap?(1999).should == false 21 | Date.gregorian_leap?(2000).should == true 22 | Date.gregorian_leap?(2002).should == false 23 | Date.gregorian_leap?(2004).should == true 24 | Date.gregorian_leap?(1901).should == false 25 | Date.gregorian_leap?(1899).should == false 26 | Date.gregorian_leap?(1904).should == true 27 | Date.gregorian_leap?(1896).should == true 28 | Date.gregorian_leap?(1999).should == false 29 | Date.gregorian_leap?(2001).should == false 30 | end 31 | 32 | it ".leap? should be the same as gregorian_leap" do 33 | Date.leap?(1900).should == Date.gregorian_leap?(1900) 34 | Date.leap?(2000).should == Date.gregorian_leap?(2000) 35 | end 36 | end 37 | 38 | ruby_version_is "" ... "1.9" do 39 | describe "Date" do 40 | it ".gregorian? should return whether the first argument is greater than or equal the second" do 41 | Date.gregorian?(1, 2).should == false 42 | Date.gregorian?(2, 1).should == true 43 | Date.gregorian?(1, 1).should == true 44 | end 45 | 46 | it ".ns? should be the same as gregorian?" do 47 | Date.ns?(2, 1).should == Date.gregorian?(2, 1) 48 | Date.ns?(1, 2).should == Date.gregorian?(1, 2) 49 | Date.ns?(1, 1).should == Date.gregorian?(1, 1) 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /spec/date/hash_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#hash" do 4 | it "should use the same hash value for equal dates" do 5 | Date.civil(2004, 7, 12).hash.should == Date.civil(2004, 7, 12).hash 6 | end 7 | 8 | it "should use a different hash value for different dates" do 9 | Date.civil(2004, 7, 12).hash.should_not == Date.civil(2004, 7, 13).hash 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/date/julian_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date.jd" do 4 | it "should be able to construct a Date object based on the Julian day" do 5 | Date.jd(2454482).should == Date.civil(2008, 1, 16) 6 | end 7 | 8 | it "should be able to determine the Julian day for a Date object" do 9 | Date.civil(2008, 1, 16).jd.should == 2454482 10 | end 11 | 12 | it "should have defaults" do 13 | Date.jd.should == Date.jd(0) 14 | Date.jd(2008).should == Date.jd(2008) 15 | Date.jd(2008, 1).should == Date.jd(2008) 16 | end 17 | 18 | it "should not accept more than 2 arguments" do 19 | proc{Date.jd(2008, 1, 1)}.should raise_error(ArgumentError) 20 | end 21 | 22 | it "should raise ArgumentError for invalid dates" do 23 | proc{Date.jd(Date::GREGORIAN)}.should raise_error 24 | proc{Date.jd(Date::JULIAN)}.should raise_error 25 | end 26 | 27 | it "should keep the same class as the receiver" do 28 | c = Class.new(Date) 29 | c.jd.should be_kind_of(c) 30 | end 31 | 32 | ruby_version_is "" ... "1.9" do 33 | it ".new1 should be the same as jd" do 34 | Date.new1(2454156).should == Date.jd(2454156) 35 | end 36 | end 37 | end 38 | 39 | describe "Date.new!" do 40 | it "should be the same as jd" do 41 | Date.new!(2454156).should == Date.jd(2454156) 42 | end 43 | 44 | it "should accept extra arguments" do 45 | Date.new!.should == Date.jd(0) 46 | Date.new!(2008).should == Date.jd(2008) 47 | Date.new!(2008, 1).should == Date.jd(2008) 48 | Date.new!(2008, 1, 1).should == Date.jd(2008) 49 | end 50 | 51 | it "should keep the same class as the receiver" do 52 | c = Class.new(Date) 53 | c.new!.should be_kind_of(c) 54 | end 55 | 56 | it "should not accept more than 3 arguments" do 57 | proc{Date.new!(2008, 1, 1, 1)}.should raise_error(ArgumentError) 58 | end 59 | 60 | ruby_version_is "" ... "1.9" do 61 | it "#new0 should be the same as new!" do 62 | Date.new0(2454156).should == Date.new!(2454156) 63 | end 64 | end 65 | end 66 | 67 | describe "Date#julian?" do 68 | it "should return false" do 69 | Date.civil(1007, 2, 27).julian?.should == false 70 | Date.civil(1907, 2, 27, Date.civil(2000, 1, 1).jd).julian?.should == false 71 | end 72 | 73 | ruby_version_is "" ... "1.9" do 74 | it "os? should be same as julian?" do 75 | Date.civil(1007, 2, 27).os?.should == false 76 | end 77 | end 78 | end 79 | 80 | describe "Date.julian_leap?" do 81 | 82 | it "should be able to determine whether a year is a leap year in the Julian calendar" do 83 | Date.julian_leap?(1900).should == true 84 | Date.julian_leap?(1999).should == false 85 | Date.julian_leap?(2000).should == true 86 | Date.julian_leap?(2002).should == false 87 | Date.julian_leap?(2004).should == true 88 | Date.julian_leap?(1901).should == false 89 | Date.julian_leap?(1899).should == false 90 | Date.julian_leap?(1904).should == true 91 | Date.julian_leap?(1896).should == true 92 | Date.julian_leap?(1999).should == false 93 | Date.julian_leap?(2001).should == false 94 | end 95 | 96 | end 97 | 98 | describe "Date.valid_jd?" do 99 | ruby_version_is "" ... "1.9" do 100 | it "should be able to determine if a day number is a valid Julian day number, true for all numbers" do 101 | # This might need to check the type of the jd parameter. Date.valid_jd?(:number) is of course 102 | # bogus but returns itself with the current implementation 103 | Date.valid_jd?(-100).should == -100 104 | Date.valid_jd?(0).should == 0 105 | Date.valid_jd?(100).should == 100 106 | Date.valid_jd?(2454156).should == 2454156 107 | Date.valid_jd?(2454156, 1).should == 2454156 108 | end 109 | 110 | it "#exist1? should be the same as valid_jd?" do 111 | Date.exist1?(2454156, 1).should == Date.valid_jd?(2454156, 1) 112 | end 113 | end 114 | 115 | ruby_version_is "1.9" do 116 | it "should be able to determine if a day number is a valid Julian day number, true for all numbers" do 117 | # This might need to check the type of the jd parameter. Date.valid_jd?(:number) is of course 118 | # bogus but returns itself with the current implementation 119 | Date.valid_jd?(-100).should == true 120 | Date.valid_jd?(0).should == true 121 | Date.valid_jd?(100).should == true 122 | Date.valid_jd?(2454156).should == true 123 | Date.valid_jd?(2454156, 1).should == true 124 | end 125 | end 126 | end 127 | 128 | ruby_version_is "" ... "1.9" do 129 | describe "Date" do 130 | it ".julian? should return whether the first argument is less than the second" do 131 | Date.julian?(1, 1).should == false 132 | Date.julian?(1, 2).should == true 133 | end 134 | 135 | it ".os? should be the same as julian?" do 136 | Date.os?(1, 2).should == Date.julian?(1, 2) 137 | end 138 | end 139 | end 140 | -------------------------------------------------------------------------------- /spec/date/leap_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#leap?" do 4 | it "should be true if the current date is a leap year and no argument is given" do 5 | Date.civil(2000, 10, 11).leap?.should == true 6 | Date.civil(2004, 10, 11).leap?.should == true 7 | Date.civil(2008, 10, 11).leap?.should == true 8 | Date.civil(1996, 10, 11).leap?.should == true 9 | Date.civil(1600, 10, 11).leap?.should == true 10 | end 11 | 12 | it "should be false if the current date is not a leap year and no argument is given" do 13 | Date.civil(1700, 10, 11).leap?.should == false 14 | Date.civil(1800, 10, 11).leap?.should == false 15 | Date.civil(1900, 10, 11).leap?.should == false 16 | Date.civil(1999, 10, 11).leap?.should == false 17 | Date.civil(2001, 10, 11).leap?.should == false 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/date/limits_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date limits: " do 4 | before do 5 | @d1 = Date.jd(Date::JULIAN - 1) 6 | @d2 = Date.jd(Date::GREGORIAN + 1) 7 | end 8 | 9 | it "#+ and #- should raise RangeError for dates that are too large or small" do 10 | proc{Date.jd(@d1.jd) + 1}.should raise_error(RangeError) 11 | proc{Date.jd(@d2.jd) - 1}.should raise_error(RangeError) 12 | end 13 | 14 | it "#<< and #>> should raise RangeError for dates that are too large or small" do 15 | proc{Date.jd(@d1.jd) >> 1}.should raise_error(RangeError) 16 | proc{Date.jd(@d2.jd) << 1}.should raise_error(RangeError) 17 | end 18 | 19 | ruby_version_is "1.9" do 20 | it "#next_year and #prev_year should raise RangeError for dates that are too large or small" do 21 | proc{Date.jd(@d1.jd).next_year}.should raise_error(RangeError) 22 | proc{Date.jd(@d2.jd).prev_year}.should raise_error(RangeError) 23 | end 24 | end 25 | 26 | it ".jd should raise RangeError for dates that are too large or small" do 27 | proc{Date.jd(@d1.jd + 1)}.should raise_error(RangeError) 28 | proc{Date.jd(@d2.jd - 1)}.should raise_error(RangeError) 29 | end 30 | 31 | it ".jd should not raise for dates that are not too large or small" do 32 | proc{Date.jd(@d1.jd)}.should_not raise_error 33 | proc{Date.jd(@d2.jd)}.should_not raise_error 34 | end 35 | 36 | it ".new! should raise RangeError for dates that are too large or small" do 37 | proc{Date.new!(@d1.jd + 1)}.should raise_error(RangeError) 38 | proc{Date.new!(@d2.jd - 1)}.should raise_error(RangeError) 39 | end 40 | 41 | it ".new! should not raise for dates that are not too large or small" do 42 | proc{Date.new!(@d1.jd)}.should_not raise_error 43 | proc{Date.new!(@d2.jd)}.should_not raise_error 44 | end 45 | 46 | it ".civil should raise RangeError for dates that are too large or small" do 47 | proc{Date.civil(@d1.year, @d1.month, @d1.day + 1)}.should raise_error(RangeError) 48 | proc{Date.civil(@d2.year, @d2.month, @d2.day - 1)}.should raise_error(RangeError) 49 | end 50 | 51 | it ".civil should not raise for dates that are not too large or small" do 52 | proc{Date.civil(@d1.year, @d1.month, @d1.day)}.should_not raise_error 53 | proc{Date.civil(@d2.year, @d2.month, @d2.day)}.should_not raise_error 54 | end 55 | 56 | it ".civil should correctly convert dates within limits to JD" do 57 | Date.civil(@d1.year, @d1.month, @d1.day).jd.should == @d1.jd 58 | Date.civil(@d2.year, @d2.month, @d2.day).jd.should == @d2.jd 59 | end 60 | 61 | it ".commercial should raise RangeError for dates that are too large or small" do 62 | proc{Date.commercial(@d1.cwyear, @d1.cwday == 6 ? @d1.cweek + 1 : @d1.cweek, @d1.cwday == 6 ? 1 : @d1.cwday + 1)}.should raise_error(RangeError) 63 | proc{Date.commercial(@d2.cwyear, @d2.cwday == 1 ? @d2.cweek - 1 : @d2.cweek, @d2.cwday == 1 ? 7 : @d2.cwday - 1)}.should raise_error(RangeError) 64 | end 65 | 66 | it ".commercial should not raise for dates that are not too large or small" do 67 | proc{Date.commercial(@d1.cwyear, @d1.cweek, @d1.cwday)}.should_not raise_error 68 | proc{Date.commercial(@d2.cwyear, @d2.cweek, @d2.cwday)}.should_not raise_error 69 | end 70 | 71 | it ".commercial should correctly convert dates within limits to JD" do 72 | Date.commercial(@d1.cwyear, @d1.cweek, @d1.cwday).jd.should == @d1.jd 73 | Date.commercial(@d2.cwyear, @d2.cweek, @d2.cwday).jd.should == @d2.jd 74 | end 75 | 76 | it ".ordinal should raise RangeError for dates that are too large or small" do 77 | proc{Date.ordinal(@d1.year, @d1.yday + 1)}.should raise_error(RangeError) 78 | proc{Date.ordinal(@d2.year, @d2.yday - 1)}.should raise_error(RangeError) 79 | end 80 | 81 | it ".ordinal should not raise for dates that are not too large or small" do 82 | proc{Date.ordinal(@d1.year, @d1.yday)}.should_not raise_error 83 | proc{Date.ordinal(@d2.year, @d2.yday)}.should_not raise_error 84 | end 85 | 86 | it ".ordinal should correctly convert dates within limits to JD" do 87 | Date.ordinal(@d1.year, @d1.yday).jd.should == @d1.jd 88 | Date.ordinal(@d2.year, @d2.yday).jd.should == @d2.jd 89 | end 90 | 91 | it ".parse should raise RangeError for civil dates that are too large or small" do 92 | proc{Date.parse("#{@d1.year}-#{@d1.month}-#{@d1.day+1}")}.should raise_error(RangeError) 93 | proc{Date.parse("#{@d2.year}-#{@d2.month}-#{@d2.day-1}")}.should raise_error(RangeError) 94 | end 95 | 96 | it ".parse should not raise for civil dates that are not too large or small" do 97 | proc{Date.parse("#{@d1.year}-#{@d1.month}-#{@d1.day}")}.should_not raise_error 98 | proc{Date.parse("#{@d2.year}-#{@d2.month}-#{@d2.day}")}.should_not raise_error 99 | end 100 | 101 | it ".parse should correctly convert civil dates within limits to JD" do 102 | Date.parse("#{@d1.year}-#{@d1.month}-#{@d1.day}").jd.should == @d1.jd 103 | Date.parse("#{@d2.year}-#{@d2.month}-#{@d2.day}").jd.should == @d2.jd 104 | end 105 | 106 | it ".strptime should raise RangeError for civil dates that are too large or small" do 107 | proc{Date.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day+1}", "%Y-%m-%d")}.should raise_error(RangeError) 108 | proc{Date.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day-1}", "%Y-%m-%d")}.should raise_error(RangeError) 109 | end 110 | 111 | it ".strptime should not raise for civil dates that are not too large or small" do 112 | proc{Date.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day}", "%Y-%m-%d")}.should_not raise_error 113 | proc{Date.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day}", "%Y-%m-%d")}.should_not raise_error 114 | end 115 | 116 | it ".strptime should correctly convert civil dates within limits to JD" do 117 | Date.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day}", "%Y-%m-%d").jd.should == @d1.jd 118 | Date.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day}", "%Y-%m-%d").jd.should == @d2.jd 119 | end 120 | 121 | end 122 | -------------------------------------------------------------------------------- /spec/date/minus_month_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#<<" do 4 | 5 | it "should substract a number of months from a date" do 6 | (Date.civil(2007, 12, 27) << 10).should == Date.civil(2007,2,27) 7 | (Date.commercial(2007, 45, 5) << 10).should == Date.commercial(2007,2,2) 8 | (Date.jd(2455086) << 10).should == Date.jd(2454782) 9 | (Date.ordinal(2008, 315) << 10).should == Date.ordinal(2008, 10) 10 | (Date.civil(2007, 12, 27) << 12).should == Date.civil(2006,12,27) 11 | (Date.civil(2007, 12, 27) << -12).should == Date.civil(2008,12,27) 12 | end 13 | 14 | it "should result in the last day of a month if the day doesn't exist" do 15 | d = Date.civil(2008,3,31) << 1 16 | d.should == Date.civil(2008, 2, 29) 17 | end 18 | 19 | it "should keep the same class as the receiver" do 20 | c = Class.new(Date) 21 | c.jd.<<(-10).should be_kind_of(c) 22 | end 23 | 24 | it "should raise an error on non numeric parameters" do 25 | lambda { Date.civil(2007,2,27) << "hello" }.should raise_error(TypeError) 26 | lambda { Date.civil(2007,2,27) << Date.new }.should raise_error(TypeError) 27 | lambda { Date.civil(2007,2,27) << Object.new }.should raise_error(TypeError) 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /spec/date/minus_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#-" do 4 | 5 | it "should substract a number of days from a Date" do 6 | (Date.civil(2008, 1, 8) - 315).should == Date.civil(2007,2,27) 7 | (Date.commercial(2007, 47, 2) - 315).should == Date.commercial(2007,2,2) 8 | (Date.jd(2455097) - 315).should == Date.jd(2454782) 9 | (Date.ordinal(2008, 325) - 315).should == Date.ordinal(2008, 10) 10 | end 11 | 12 | it "should substract a negative number of days from a Date" do 13 | d = Date.civil(2007, 4, 19).-(-13) 14 | d.should == Date.civil(2007, 5 ,2) 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(Date) 19 | c.jd.-(10).should be_kind_of(c) 20 | end 21 | 22 | it "should be able to compute the different between two dates" do 23 | (Date.civil(2007,2,27) - Date.civil(2007,2,27)).should == 0 24 | (Date.civil(2007,2,27) - Date.civil(2007,2,26)).should == 1 25 | (Date.civil(2006,2,27) - Date.civil(2007,2,27)).should == -365 26 | (Date.civil(2008,2,27) - Date.civil(2007,2,27)).should == 365 27 | (Date.civil(2009,2,27) - Date.civil(2008,2,27)).should == 366 28 | 29 | (Date.civil(2009,2,27) - Date.commercial(2008,2,1)).should == 417 30 | (Date.civil(2009,2,27) - Date.jd(2454782)).should == 108 31 | (Date.civil(2009,2,27) - Date.ordinal(2008, 10)).should == 414 32 | 33 | (Date.commercial(2008,2,1) - Date.civil(2008,2,27)).should == -51 34 | (Date.commercial(2008,2,1) - Date.jd(2454782)).should == -309 35 | (Date.commercial(2008,2,1) - Date.ordinal(2008, 10)).should == -3 36 | 37 | (Date.jd(2454782) - Date.commercial(2008,2,1)).should == 309 38 | (Date.jd(2454782) - Date.civil(2009,2,27)).should == -108 39 | (Date.jd(2454782) - Date.ordinal(2008, 10)).should == 306 40 | 41 | (Date.ordinal(2008, 10) - Date.commercial(2008,2,1)).should == 3 42 | (Date.ordinal(2008, 10) - Date.jd(2454782)).should == -306 43 | (Date.ordinal(2008, 10) - Date.civil(2009,2,27)).should == -414 44 | end 45 | 46 | it "should be able to compute the difference between a Date and a DateTime" do 47 | (Date.civil(2007, 4, 19) - DateTime.civil(2007, 4, 18, 12)).should == 0.5 48 | end 49 | 50 | it "should raise an error on non numeric parameters" do 51 | lambda { Date.civil(2007,2,27) - :hello }.should raise_error(TypeError) 52 | lambda { Date.civil(2007,2,27) - "hello" }.should raise_error(TypeError) 53 | lambda { Date.civil(2007,2,27) - Object.new }.should raise_error(TypeError) 54 | end 55 | 56 | end 57 | -------------------------------------------------------------------------------- /spec/date/next_prev_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "Date#next_day" do 5 | it "should add a single day to a Date if no arguments" do 6 | (Date.civil(2007,2,27).next_day).should == Date.civil(2007, 2, 28) 7 | end 8 | 9 | it "should add the given number of days to a Date if an argument" do 10 | (Date.civil(2007,2,27).next_day(2)).should == Date.civil(2007, 3, 1) 11 | end 12 | 13 | it "should handle a negative argument by subtracting days" do 14 | (Date.civil(2007,2,27).next_day(-2)).should == Date.civil(2007, 2, 25) 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(Date) 19 | c.jd.next_day.should be_kind_of(c) 20 | end 21 | end 22 | 23 | describe "Date#prev_day" do 24 | it "should subtract a single day to a Date if no arguments" do 25 | (Date.civil(2007,2,27).prev_day).should == Date.civil(2007, 2, 26) 26 | end 27 | 28 | it "should subtract the given number of days to a Date if an argument" do 29 | (Date.civil(2007,2,27).prev_day(2)).should == Date.civil(2007, 2, 25) 30 | end 31 | 32 | it "should handle a negative argument by adding days" do 33 | (Date.civil(2007,2,27).prev_day(-2)).should == Date.civil(2007, 3, 1) 34 | end 35 | 36 | it "should keep the same class as the receiver" do 37 | c = Class.new(Date) 38 | c.jd.prev_day.should be_kind_of(c) 39 | end 40 | end 41 | 42 | describe "Date#next_month" do 43 | it "should add a single month to a Date if no arguments" do 44 | (Date.civil(2007,2,27).next_month).should == Date.civil(2007, 3, 27) 45 | end 46 | 47 | it "should add the given number of months to a Date if an argument" do 48 | (Date.civil(2007,2,27).next_month(2)).should == Date.civil(2007, 4, 27) 49 | end 50 | 51 | it "should handle a negative argument by subtracting months" do 52 | (Date.civil(2007,2,27).next_month(-2)).should == Date.civil(2006, 12, 27) 53 | end 54 | 55 | it "should handle adding a month where the new date is not a valid date" do 56 | (Date.civil(2007,1,31).next_month).should == Date.civil(2007, 2, 28) 57 | (Date.civil(2008,1,31).next_month).should == Date.civil(2008, 2, 29) 58 | (Date.civil(2007,1,31).next_month(3)).should == Date.civil(2007, 4, 30) 59 | end 60 | 61 | it "should keep the same class as the receiver" do 62 | c = Class.new(Date) 63 | c.jd.next_month.should be_kind_of(c) 64 | end 65 | end 66 | 67 | describe "Date#prev_month" do 68 | it "should subtract a single month to a Date if no arguments" do 69 | (Date.civil(2007,2,27).prev_month).should == Date.civil(2007, 1, 27) 70 | end 71 | 72 | it "should subtract the given number of months to a Date if an argument" do 73 | (Date.civil(2007,2,27).prev_month(2)).should == Date.civil(2006, 12, 27) 74 | end 75 | 76 | it "should handle a negative argument by adding months" do 77 | (Date.civil(2007,2,27).prev_month(-2)).should == Date.civil(2007, 4, 27) 78 | end 79 | 80 | it "should handle subtracting a month where the new date is not a valid date" do 81 | (Date.civil(2007,3,31).prev_month).should == Date.civil(2007, 2, 28) 82 | (Date.civil(2008,3,31).prev_month).should == Date.civil(2008, 2, 29) 83 | (Date.civil(2007,3,31).prev_month(4)).should == Date.civil(2006, 11, 30) 84 | end 85 | 86 | it "should keep the same class as the receiver" do 87 | c = Class.new(Date) 88 | c.jd.prev_month.should be_kind_of(c) 89 | end 90 | end 91 | 92 | describe "Date#next_year" do 93 | it "should add a single year to a Date if no arguments" do 94 | (Date.civil(2007,2,27).next_year).should == Date.civil(2008, 2, 27) 95 | end 96 | 97 | it "should add the given number of years to a Date if an argument" do 98 | (Date.civil(2007,2,27).next_year(2)).should == Date.civil(2009, 2, 27) 99 | end 100 | 101 | it "should handle a negative argument by subtracting years" do 102 | (Date.civil(2007,2,27).next_year(-2)).should == Date.civil(2005, 2, 27) 103 | end 104 | 105 | it "should handle adding a year where the new date is not a valid date" do 106 | (Date.civil(2008,2,29).next_year).should == Date.civil(2009, 2, 28) 107 | end 108 | 109 | it "should keep the same class as the receiver" do 110 | c = Class.new(Date) 111 | c.jd.next_year.should be_kind_of(c) 112 | end 113 | end 114 | 115 | describe "Date#prev_year" do 116 | it "should add a single year to a Date if no arguments" do 117 | (Date.civil(2007,2,27).prev_year).should == Date.civil(2006, 2, 27) 118 | end 119 | 120 | it "should add the given number of years to a Date if an argument" do 121 | (Date.civil(2007,2,27).prev_year(2)).should == Date.civil(2005, 2, 27) 122 | end 123 | 124 | it "should handle a negative argument by subtracting years" do 125 | (Date.civil(2007,2,27).prev_year(-2)).should == Date.civil(2009, 2, 27) 126 | end 127 | 128 | it "should handle adding a year where the new date is not a valid date" do 129 | (Date.civil(2008,2,29).prev_year).should == Date.civil(2007, 2, 28) 130 | end 131 | 132 | it "should keep the same class as the receiver" do 133 | c = Class.new(Date) 134 | c.jd.prev_year.should be_kind_of(c) 135 | end 136 | end 137 | end 138 | -------------------------------------------------------------------------------- /spec/date/ordinal_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date.ordinal" do 4 | 5 | it "should be able to construct a Date object from an ordinal date" do 6 | Date.ordinal(1582, 274).should == Date.civil(1582, 10, 1) 7 | Date.ordinal(1582, 277).should == Date.civil(1582, 10, 4) 8 | Date.ordinal(1582, 288).should == Date.civil(1582, 10, 15) 9 | Date.ordinal(1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND) 10 | end 11 | 12 | it "should have defaults and an optional sg value" do 13 | Date.ordinal.should == Date.jd 14 | Date.ordinal(2008).should == Date.ordinal(2008, 1) 15 | Date.ordinal(2008, 1, 1).should == Date.ordinal(2008, 1) 16 | end 17 | 18 | it "should not accept more than 3 arguments" do 19 | proc{Date.ordinal(2008, 1, 1, 1)}.should raise_error(ArgumentError) 20 | end 21 | 22 | it "raises errors for invalid dates" do 23 | lambda { Date.ordinal(2007, 366) }.should raise_error(ArgumentError) 24 | lambda { Date.ordinal(2008, 366) }.should_not raise_error(ArgumentError) 25 | lambda { Date.ordinal(2008, 367) }.should raise_error(ArgumentError) 26 | end 27 | 28 | it "should keep the same class as the receiver" do 29 | c = Class.new(Date) 30 | c.ordinal.should be_kind_of(c) 31 | end 32 | 33 | ruby_version_is "" ... "1.9" do 34 | it ".new2 should be the same as ordinal" do 35 | Date.new2(2008, 10).should == Date.ordinal(2008, 10) 36 | end 37 | end 38 | end 39 | 40 | describe "Date.valid_ordinal?" do 41 | 42 | ruby_version_is "" ... "1.9" do 43 | it "should be able to determine if the date is a valid ordinal date" do 44 | Date.valid_ordinal?(1582, 277).should == Date.civil(1582, 10, 4).jd 45 | Date.valid_ordinal?(1582, 278).should == Date.civil(1582, 10, 5).jd 46 | Date.valid_ordinal?(1582, 287).should == Date.civil(1582, 10, 14).jd 47 | Date.valid_ordinal?(1582, 288).should == Date.civil(1582, 10, 15).jd 48 | Date.valid_ordinal?(1582, 287, Date::ENGLAND).should_not == nil 49 | Date.valid_ordinal?(1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd 50 | 51 | Date.valid_ordinal?(2007, 55).should == 2454156 52 | Date.valid_ordinal?(2007, 55, 1).should == 2454156 53 | Date.valid_ordinal?(2007, 367, 1).should == nil 54 | end 55 | 56 | it "#exist2? should be the same as valid_ordinal?" do 57 | Date.exist2?(2007, 55, 1).should == Date.valid_ordinal?(2007, 55) 58 | end 59 | 60 | it "should be able to handle negative day numbers" do 61 | Date.valid_ordinal?(1582, -89).should == Date.civil(1582, 10, 4).jd 62 | Date.valid_ordinal?(1582, -88).should == Date.civil(1582, 10, 5).jd 63 | Date.valid_ordinal?(1582, -79).should == Date.civil(1582, 10, 14).jd 64 | Date.valid_ordinal?(1582, -78).should == Date.civil(1582, 10, 15).jd 65 | Date.valid_ordinal?(2007, -100).should == Date.valid_ordinal?(2007, 266) 66 | end 67 | end 68 | 69 | ruby_version_is "1.9" do 70 | it "should be able to determine if the date is a valid ordinal date" do 71 | Date.valid_ordinal?(1582, 277).should == true 72 | Date.valid_ordinal?(1582, 278).should == true 73 | Date.valid_ordinal?(1582, 287).should == true 74 | Date.valid_ordinal?(1582, 288).should == true 75 | 76 | Date.valid_ordinal?(2007, 55).should == true 77 | Date.valid_ordinal?(2007, 55, 1).should == true 78 | Date.valid_ordinal?(2007, 367, 1).should == false 79 | end 80 | 81 | it "should be able to handle negative day numbers" do 82 | Date.valid_ordinal?(1582, -79).should == true 83 | Date.valid_ordinal?(1582, -78).should == true 84 | Date.valid_ordinal?(2007, -100).should == true 85 | end 86 | end 87 | 88 | end 89 | -------------------------------------------------------------------------------- /spec/date/parsing_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "Date parsing methods" do 5 | it "._httpdate should parse an HTTP format" do 6 | Date._httpdate("Fri, 02 Jan 2009 00:00:00 GMT").should == 7 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'GMT'} 8 | Date._httpdate("Friday, 02-Jan-09 00:00:00 GMT").should == 9 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'GMT'} 10 | Date._httpdate("Fri Jan 2 00:00:00 2009").should == 11 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0} 12 | end 13 | 14 | it "._iso8601 should parse an ISO8601 format" do 15 | Date._iso8601("2009-01-02").should == {:year=>2009, :mon=>1, :mday=>2} 16 | Date._iso8601("--1002").should == {:mon=>10, :mday=>2} 17 | end 18 | 19 | it "._jisx03010 should parse an JIS X 0301 format" do 20 | Date._jisx0301("H21.01.02").should == {:year=>2009, :mon=>1, :mday=>2} 21 | Date._jisx0301("S63.01.02").should == {:year=>1988, :mon=>1, :mday=>2} 22 | Date._jisx0301("T14.01.02").should == {:year=>1925, :mon=>1, :mday=>2} 23 | Date._jisx0301("M44.01.02").should == {:year=>1911, :mon=>1, :mday=>2} 24 | Date._jisx0301("M06.01.02").should == {:year=>1873, :mon=>1, :mday=>2} 25 | Date._jisx0301("1872-01-02").should == {:year=>1872, :mon=>1, :mday=>2} 26 | Date._jisx0301("1867-01-02").should == {:year=>1867, :mon=>1, :mday=>2} 27 | 28 | Date._jisx0301("21.01.02").should == {:year=>2009, :mon=>1, :mday=>2} 29 | end 30 | 31 | it "._rfc2822 should parse an RFC2822 format" do 32 | Date._rfc2822("Fri, 2 Jan 2009 00:00:00 +0000").should == 33 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'+0000'} 34 | Date._rfc2822("Fri, 2 Jan 09 00:00:00 +0000").should == 35 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'+0000'} 36 | Date._rfc2822("Fri, 2 Jan 109 00:00:00 +0000").should == 37 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'+0000'} 38 | end 39 | 40 | it "._rfc822 should parse an RFC822 format" do 41 | Date._rfc822("Fri, 2 Jan 2009 00:00:00 +0000").should == 42 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'+0000'} 43 | end 44 | 45 | it "._rfc3339 should parse an RFC3339 format" do 46 | Date._rfc3339("2009-01-02T00:00:00+00:00").should == 47 | {:year=>2009, :mon=>1, :mday=>2, :hour=>0, :min=>0, :sec=>0, :offset=>0, :zone=>'+00:00'} 48 | end 49 | 50 | it "._xmlschema should parse an ISO8601 format" do 51 | Date._xmlschema("2009-01-02").should == {:year=>2009, :mon=>1, :mday=>2} 52 | end 53 | 54 | it ".httpdate should parse an HTTP format" do 55 | Date.httpdate("Fri, 02 Jan 2009 00:00:00 GMT").should == Date.new(2009, 1, 2) 56 | end 57 | 58 | it ".iso8601 should parse an ISO8601 format" do 59 | Date.iso8601("2009-01-02").should == Date.new(2009, 1, 2) 60 | end 61 | 62 | it ".jisx03010 should parse an JIS X 0301 format" do 63 | Date.jisx0301("H21.01.02").should == Date.new(2009, 1, 2) 64 | Date.jisx0301("S63.01.02").should == Date.new(1988, 1, 2) 65 | Date.jisx0301("T14.01.02").should == Date.new(1925, 1, 2) 66 | Date.jisx0301("M44.01.02").should == Date.new(1911, 1, 2) 67 | Date.jisx0301("M06.01.02").should == Date.new(1873, 1, 2) 68 | Date.jisx0301("1872-01-02").should == Date.new(1872, 1, 2) 69 | Date.jisx0301("1867-01-02").should == Date.new(1867, 1, 2) 70 | end 71 | 72 | it ".rfc2822 should parse an RFC2822 format" do 73 | Date.rfc2822("Fri, 2 Jan 2009 00:00:00 +0000").should == Date.new(2009, 1, 2) 74 | end 75 | 76 | it ".rfc822 should parse an RFC822 format" do 77 | Date.rfc822("Fri, 2 Jan 2009 00:00:00 +0000").should == Date.new(2009, 1, 2) 78 | end 79 | 80 | it ".rfc3339 should parse an RFC3339 format" do 81 | Date.rfc3339("2009-01-02T00:00:00+00:00").should == Date.new(2009, 1, 2) 82 | end 83 | 84 | it ".xmlschema should parse an ISO8601 format" do 85 | Date.xmlschema("2009-01-02").should == Date.new(2009, 1, 2) 86 | end 87 | 88 | it "should keep the same class as the receiver" do 89 | c = Class.new(Date) 90 | c.httpdate("Fri, 02 Jan 2009 00:00:00 GMT").should be_kind_of(c) 91 | c.iso8601("2009-01-02").should be_kind_of(c) 92 | c.jisx0301("H21.01.02").should be_kind_of(c) 93 | c.rfc2822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c) 94 | c.rfc822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c) 95 | c.rfc3339("2009-01-02T00:00:00+00:00").should be_kind_of(c) 96 | c.xmlschema("2009-01-02").should be_kind_of(c) 97 | end 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /spec/date/relationship_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#===" do 4 | 5 | it "should be true for the two same dates" do 6 | (Date.civil(2000, 04, 06) === Date.civil(2000, 04, 06)).should == true 7 | end 8 | 9 | it "should be true if comparison is a DateTime on the same date" do 10 | (Date.civil(2000, 04, 06) === DateTime.civil(2000, 04, 06, 10)).should == true 11 | end 12 | 13 | it "should be true if comparison is a Numeric with the same integer value as JD" do 14 | (Date.civil(2000, 04, 06) === Date.civil(2000, 04, 06).jd).should == true 15 | end 16 | 17 | it "should be false for different dates" do 18 | (Date.civil(2000, 04, 05) === Date.civil(2000, 04, 06)).should == false 19 | end 20 | 21 | it "should be false if comparison is a DateTime with a different date" do 22 | (Date.civil(2000, 04, 06) === DateTime.civil(2000, 04, 07, 10)).should == false 23 | end 24 | 25 | it "should be false if comparison is a Numeric with the different integer value as JD" do 26 | (Date.civil(2000, 04, 06) === Date.civil(2000, 04, 07).jd).should == false 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/date/step_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#step" do 4 | 5 | ruby_version_is "" ... "1.9" do 6 | it "should require a block" do 7 | proc{Date.today.step(Date.today)}.should raise_error(LocalJumpError) 8 | end 9 | end 10 | 11 | ruby_version_is "1.9" do 12 | it "should return an enumerator without a block" do 13 | ds = Date.civil(2008, 10, 11) 14 | de = Date.civil(2008, 9, 29) 15 | e = de.step(ds) 16 | e.should be_kind_of(Enumerator) 17 | count = 0 18 | e.each do |d| 19 | d.should <= ds 20 | d.should >= de 21 | count += 1 22 | end.should == de 23 | count.should == 13 24 | end 25 | end 26 | 27 | it "should be able to step forward in time" do 28 | ds = Date.civil(2008, 10, 11) 29 | de = Date.civil(2008, 9, 29) 30 | count = 0 31 | de.step(ds) do |d| 32 | d.should <= ds 33 | d.should >= de 34 | count += 1 35 | end.should == de 36 | count.should == 13 37 | 38 | count = 0 39 | de.step(ds, 5) do |d| 40 | d.should <= ds 41 | d.should >= de 42 | count += 1 43 | end.should == de 44 | count.should == 3 45 | 46 | count = 0 47 | ds.step(de) do |d|; count += 1; end.should == ds 48 | count.should == 0 49 | 50 | end 51 | 52 | it "should be able to step backward in time" do 53 | ds = Date.civil(2000, 4, 14) 54 | de = Date.civil(2000, 3, 29) 55 | count = 0 56 | ds.step(de, -1) do |d| 57 | d.should <= ds 58 | d.should >= de 59 | count += 1 60 | end.should == ds 61 | count.should == 17 62 | 63 | count = 0 64 | ds.step(de, -5) do |d| 65 | d.should <= ds 66 | d.should >= de 67 | count += 1 68 | end.should == ds 69 | count.should == 4 70 | 71 | count = 0 72 | de.step(ds, -1) do |d|; count += 1; end.should == de 73 | count.should == 0 74 | 75 | end 76 | 77 | it "should yield once if the dates are the same, regardless of step" do 78 | ds = Date.civil(2008, 10, 11) 79 | count = 0 80 | ds.step(ds, 1) do |d| 81 | d.should == ds 82 | count += 1 83 | end.should == ds 84 | count.should == 1 85 | 86 | count = 0 87 | ds.step(ds, -1) do |d| 88 | d.should == ds 89 | count += 1 90 | end.should == ds 91 | count.should == 1 92 | end 93 | 94 | it "should not yield if the target date is greater than the receiver, and step is not positive" do 95 | ds = Date.civil(2008, 10, 11) 96 | count = 0 97 | ds.step(ds.next, -1) do |d| 98 | count += 1 99 | end.should == ds 100 | count.should == 0 101 | end 102 | 103 | it "should not yield if the target date is less than the receiver, and step is not negative" do 104 | ds = Date.civil(2008, 10, 11) 105 | count = 0 106 | ds.next.step(ds, 1) do |d| 107 | count += 1 108 | end.should == ds.next 109 | count.should == 0 110 | end 111 | 112 | it "should raise an ArgumentError for a 0 step" do 113 | ds = Date.civil(2008, 10, 11) 114 | proc{ds.step(ds, 0){|d|}}.should raise_error(ArgumentError) 115 | proc{ds.step(ds+1, 0){|d|}}.should raise_error(ArgumentError) 116 | proc{ds.step(ds-1, 0){|d|}}.should raise_error(ArgumentError) 117 | end 118 | 119 | it "should keep the same class as the receiver" do 120 | c = Class.new(Date) 121 | c.jd.step(c.jd + 2) do |d| 122 | d.should be_kind_of(c) 123 | end.should be_kind_of(c) 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /spec/date/strftime_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#strftime" do 4 | 5 | it "should be able to print the date" do 6 | Date.civil(2000, 4, 6).strftime.should == "2000-04-06" 7 | Date.civil(2000, 4, 6).strftime.should == Date.civil(2000, 4, 6).to_s 8 | end 9 | 10 | it "should be able to print the full day name" do 11 | Date.civil(2000, 4, 6).strftime("%A").should == "Thursday" 12 | end 13 | 14 | it "should be able to print the short day name" do 15 | Date.civil(2000, 4, 6).strftime("%a").should == "Thu" 16 | end 17 | 18 | it "should be able to print the full month name" do 19 | Date.civil(2000, 4, 6).strftime("%B").should == "April" 20 | end 21 | 22 | it "should be able to print the short month name" do 23 | Date.civil(2000, 4, 6).strftime("%b").should == "Apr" 24 | Date.civil(2000, 4, 6).strftime("%h").should == "Apr" 25 | Date.civil(2000, 4, 6).strftime("%b").should == Date.civil(2000, 4, 6).strftime("%h") 26 | end 27 | 28 | it "should be able to print the century" do 29 | Date.civil(2000, 4, 6).strftime("%C").should == "20" 30 | end 31 | 32 | it "should be able to print the month day with leading zeroes" do 33 | Date.civil(2000, 4, 6).strftime("%d").should == "06" 34 | end 35 | 36 | it "should be able to print the month day with leading spaces" do 37 | Date.civil(2000, 4, 6).strftime("%e").should == " 6" 38 | end 39 | 40 | it "should be able to print the commercial year with leading zeroes" do 41 | Date.civil(2000, 4, 6).strftime("%G").should == "2000" 42 | Date.civil( 200, 4, 6).strftime("%G").should == "0200" 43 | end 44 | 45 | it "should be able to print the commercial year with only two digits" do 46 | Date.civil(2000, 4, 6).strftime("%g").should == "00" 47 | Date.civil( 200, 4, 6).strftime("%g").should == "00" 48 | end 49 | 50 | it "should be able to print the hour with leading zeroes (hour is always 00)" do 51 | Date.civil(2000, 4, 6).strftime("%H").should == "00" 52 | end 53 | 54 | it "should be able to print the hour in 12 hour notation with leading zeroes" do 55 | Date.civil(2000, 4, 6).strftime("%I").should == "12" 56 | end 57 | 58 | it "should be able to print the year day with leading zeroes" do 59 | Date.civil(2000, 4, 6).strftime("%j").should == "097" 60 | end 61 | 62 | it "should be able to print the hour in 24 hour notation with leading spaces" do 63 | Date.civil(2000, 4, 6).strftime("%k").should == " 0" 64 | end 65 | 66 | it "should be able to print the hour in 12 hour notation with leading spaces" do 67 | Date.civil(2000, 4, 6).strftime("%l").should == "12" 68 | end 69 | 70 | it "should be able to print the milliseconds of the second with leading zeroes" do 71 | Date.civil(2000, 4, 6).strftime("%L").should == "000" 72 | end 73 | 74 | it "should be able to print the minutes with leading zeroes" do 75 | Date.civil(2000, 4, 6).strftime("%M").should == "00" 76 | end 77 | 78 | it "should be able to print the month with leading zeroes" do 79 | Date.civil(2000, 4, 6).strftime("%m").should == "04" 80 | end 81 | 82 | it "should be able to print the nanoseconds of the second with leading zeroes" do 83 | Date.civil(2000, 4, 6).strftime("%N").should == "000000000" 84 | end 85 | 86 | it "should be able to add a newline" do 87 | Date.civil(2000, 4, 6).strftime("%n").should == "\n" 88 | end 89 | 90 | it "should be able to show AM/PM" do 91 | Date.civil(2000, 4, 6).strftime("%P").should == "am" 92 | end 93 | 94 | it "should be able to show am/pm" do 95 | Date.civil(2000, 4, 6).strftime("%p").should == "AM" 96 | end 97 | 98 | it "should be able to show the number of milliseconds since the unix epoch" do 99 | Date.civil(2000, 4, 6).strftime("%Q").should == "954979200000" 100 | Date.civil(3000, 4, 6).strftime("%Q").should == "32511888000000" 101 | end 102 | 103 | it "should be able to show the number of seconds with leading zeroes" do 104 | Date.civil(2000, 4, 6).strftime("%S").should == "00" 105 | end 106 | 107 | it "should be able to show the number of seconds since the unix epoch" do 108 | Date.civil(2000, 4, 6).strftime("%s").should == "954979200" 109 | Date.civil(3000, 4, 6).strftime("%s").should == "32511888000" 110 | end 111 | 112 | it "should be able to add a tab" do 113 | Date.civil(2000, 4, 6).strftime("%t").should == "\t" 114 | end 115 | 116 | it "should be able to show the week number with the week starting on sunday and monday" do 117 | Date.civil(2000, 4, 6).strftime("%U").should == "14" 118 | Date.civil(2000, 4, 6).strftime("%W").should == "14" 119 | Date.civil(2000, 4, 6).strftime("%U").should == Date.civil(2000, 4, 6).strftime("%W") 120 | Date.civil(2000, 4, 9).strftime("%U").should == "15" 121 | Date.civil(2000, 4, 9).strftime("%W").should == "14" 122 | Date.civil(2000, 4, 9).strftime("%U").should_not == Date.civil(2000, 4, 9).strftime("%W") 123 | end 124 | 125 | it "should be able to show the commercial week day" do 126 | Date.civil(2000, 4, 9).strftime("%u").should == "7" 127 | Date.civil(2000, 4, 10).strftime("%u").should == "1" 128 | end 129 | 130 | it "should be able to show the commercial week" do 131 | Date.civil(2000, 4, 9).strftime("%V").should == "14" 132 | Date.civil(2000, 4, 10).strftime("%V").should == "15" 133 | end 134 | 135 | it "should be able to show the week day" do 136 | Date.civil(2000, 4, 9).strftime("%w").should == "0" 137 | Date.civil(2000, 4, 10).strftime("%w").should == "1" 138 | end 139 | 140 | it "should be able to show the year in YYYY format" do 141 | Date.civil(2000, 4, 9).strftime("%Y").should == "2000" 142 | end 143 | 144 | it "should be able to show the year in YY format" do 145 | Date.civil(2000, 4, 9).strftime("%y").should == "00" 146 | end 147 | 148 | it "should be able to show the timezone of the date with a : separator" do 149 | Date.civil(2000, 4, 9).strftime("%Z").should == "+00:00" 150 | end 151 | 152 | it "should be able to show the timezone of the date with a : separator" do 153 | Date.civil(2000, 4, 9).strftime("%z").should == "+0000" 154 | end 155 | 156 | it "should be able to escape the % character" do 157 | Date.civil(2000, 4, 9).strftime("%%").should == "%" 158 | end 159 | 160 | it "should remove % from other %X sequences if it doesn't have a conversion" do 161 | Date.civil(2000, 4, 9).strftime("%5").should == "5" 162 | Date.civil(2000, 4, 9).strftime("%f").should == "f" 163 | end 164 | 165 | it "should leave other text alone if it doesn't have a conversion" do 166 | Date.civil(2000, 4, 9).strftime("15").should == "15" 167 | end 168 | 169 | ############################ 170 | # Specs that combine stuff # 171 | ############################ 172 | 173 | it "should be able to print the date in full" do 174 | Date.civil(2000, 4, 6).strftime("%c").should == "Thu Apr 6 00:00:00 2000" 175 | Date.civil(2000, 4, 6).strftime("%c").should == Date.civil(2000, 4, 6).strftime('%a %b %e %H:%M:%S %Y') 176 | end 177 | 178 | it "should be able to print the date with slashes" do 179 | Date.civil(2000, 4, 6).strftime("%D").should == "04/06/00" 180 | Date.civil(2000, 4, 6).strftime("%D").should == Date.civil(2000, 4, 6).strftime('%m/%d/%y') 181 | end 182 | 183 | it "should be able to print the date as YYYY-MM-DD" do 184 | Date.civil(2000, 4, 6).strftime("%F").should == "2000-04-06" 185 | Date.civil(2000, 4, 6).strftime("%F").should == Date.civil(2000, 4, 6).strftime('%Y-%m-%d') 186 | end 187 | 188 | it "should be able to show HH:MM" do 189 | Date.civil(2000, 4, 6).strftime("%R").should == "00:00" 190 | Date.civil(2000, 4, 6).strftime("%R").should == Date.civil(2000, 4, 6).strftime('%H:%M') 191 | end 192 | 193 | it "should be able to show HH:MM:SS AM/PM" do 194 | Date.civil(2000, 4, 6).strftime("%r").should == "12:00:00 AM" 195 | Date.civil(2000, 4, 6).strftime("%r").should == Date.civil(2000, 4, 6).strftime('%I:%M:%S %p') 196 | end 197 | 198 | it "should be able to show HH:MM:SS" do 199 | Date.civil(2000, 4, 6).strftime("%T").should == "00:00:00" 200 | Date.civil(2000, 4, 6).strftime("%T").should == Date.civil(2000, 4, 6).strftime('%H:%M:%S') 201 | end 202 | 203 | it "should be able to show the commercial week" do 204 | Date.civil(2000, 4, 9).strftime("%v").should == " 9-Apr-2000" 205 | Date.civil(2000, 4, 9).strftime("%v").should == Date.civil(2000, 4, 9).strftime('%e-%b-%Y') 206 | end 207 | 208 | it "should be able to show HH:MM:SS" do 209 | Date.civil(2000, 4, 6).strftime("%X").should == "00:00:00" 210 | Date.civil(2000, 4, 6).strftime("%X").should == Date.civil(2000, 4, 6).strftime('%H:%M:%S') 211 | end 212 | 213 | it "should be able to show MM/DD/YY" do 214 | Date.civil(2000, 4, 6).strftime("%x").should == "04/06/00" 215 | Date.civil(2000, 4, 6).strftime("%x").should == Date.civil(2000, 4, 6).strftime('%m/%d/%y') 216 | end 217 | 218 | it "should be able to show a full notation" do 219 | Date.civil(2000, 4, 9).strftime("%+").should == "Sun Apr 9 00:00:00 +00:00 2000" 220 | Date.civil(2000, 4, 9).strftime("%+").should == Date.civil(2000, 4, 9).strftime('%a %b %e %H:%M:%S %Z %Y') 221 | end 222 | 223 | end 224 | -------------------------------------------------------------------------------- /spec/date/strptime_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#strptime" do 4 | 5 | it "._strptime should not accept less than 1 arguments" do 6 | proc{Date._strptime}.should raise_error(ArgumentError) 7 | end 8 | 9 | it "._strptime should not accept more than 2 arguments" do 10 | proc{Date._strptime('2008-10-11', '%Y-%m-%d', '1')}.should raise_error(ArgumentError) 11 | end 12 | 13 | it "._strptime should be a hash of values" do 14 | Date._strptime('2008-10-11').should == {:year=>2008, :mon=>10, :mday=>11} 15 | Date._strptime('2008-10-11', '%Y-%m-%d').should == {:year=>2008, :mon=>10, :mday=>11} 16 | end 17 | 18 | it "should have defaults and an optional sg value" do 19 | Date.strptime.should == Date.jd 20 | Date.strptime('2008-10-11').should == Date.civil(2008, 10, 11) 21 | Date.strptime('2008-10-11', '%Y-%m-%d').should == Date.civil(2008, 10, 11) 22 | Date.strptime('2008-10-11', '%Y-%m-%d', 1).should == Date.civil(2008, 10, 11) 23 | end 24 | 25 | it "should keep the same class as the receiver" do 26 | c = Class.new(Date) 27 | c.strptime.should be_kind_of(c) 28 | c.strptime('20081011', '%Y%m%d').should be_kind_of(c) 29 | end 30 | 31 | it "raises errors for invalid dates" do 32 | lambda { Date.strptime("") }.should raise_error(ArgumentError) 33 | lambda { Date.strptime("", "") }.should raise_error(ArgumentError) 34 | lambda { Date.strptime("2009-02-29") }.should raise_error(ArgumentError) 35 | end 36 | 37 | it "uses the default format when not given a date format" do 38 | Date.strptime("2000-04-06").should == Date.civil(2000, 4, 6) 39 | Date.civil(2000, 4, 6).strftime.should == Date.civil(2000, 4, 6).to_s 40 | end 41 | 42 | it "parses a full day name" do 43 | d = Date.today 44 | expected_date = Date.commercial(d.cwyear, d.cweek, 4) 45 | # strptime assumed week that start on sunday, not monday 46 | expected_date += 7 if d.cwday == 7 47 | Date.strptime("Thursday", "%A").should == expected_date 48 | end 49 | 50 | it "parses a short day name" do 51 | d = Date.today 52 | expected_date = Date.commercial(d.cwyear, d.cweek, 4) 53 | # strptime assumed week that start on sunday, not monday 54 | expected_date += 7 if d.cwday == 7 55 | Date.strptime("Thu", "%a").should == expected_date 56 | end 57 | 58 | it "parses only the short part of the day name" do 59 | Date._strptime("Friday", "%aday").should == {:wday=>5} 60 | end 61 | 62 | it "parses a full month name" do 63 | d = Date.today 64 | Date.strptime("April", "%B").should == Date.civil(d.year, 4, 1) 65 | end 66 | 67 | it "parses a short month name" do 68 | d = Date.today 69 | Date.strptime("Apr", "%b").should == Date.civil(d.year, 4, 1) 70 | Date.strptime("Apr", "%h").should == Date.civil(d.year, 4, 1) 71 | end 72 | 73 | it "parses only the short part of the month name" do 74 | d = Date.today 75 | Date.strptime("April", "%bil").should == Date.civil(d.year, 4, 1) 76 | Date.strptime("April", "%hil").should == Date.civil(d.year, 4, 1) 77 | end 78 | 79 | it "parses a century" do 80 | Date.strptime("06 20", "%y %C").should == Date.civil(2006, 1, 1) 81 | end 82 | 83 | it "parses a month day with leading zeroes" do 84 | d = Date.today 85 | Date.strptime("06", "%d").should == Date.civil(d.year, d.month, 6) 86 | end 87 | 88 | it "parses a month day with leading spaces" do 89 | d = Date.today 90 | Date.strptime(" 6", "%e").should == Date.civil(d.year, d.month, 6) 91 | end 92 | 93 | it "parses a commercial year" do 94 | Date.strptime("2000", "%G").should == Date.civil(2000, 1, 3) 95 | Date.strptime("2002", "%G").should == Date.civil(2001, 12, 31) 96 | Date.strptime("20000", "%G").should == Date.civil(20000, 1, 3) 97 | end 98 | 99 | it "parses a commercial year with trailing numbers" do 100 | Date.strptime("20000", "%G0").should == Date.civil(2000, 1, 3) 101 | Date.strptime("20023", "%G%u").should == Date.civil(2002, 1, 2) 102 | end 103 | 104 | it "parses a commercial year with only two digits" do 105 | Date.strptime("68", "%g").should == Date.civil(2068, 1, 2) 106 | Date.strptime("69", "%g").should == Date.civil(1968, 12, 30) 107 | end 108 | 109 | it "parses a year day with leading zeroes" do 110 | d = Date.today 111 | if Date.gregorian_leap?(Date.today.year) 112 | Date.strptime("097", "%j").should == Date.civil(d.year, 4, 6) 113 | else 114 | Date.strptime("097", "%j").should == Date.civil(d.year, 4, 7) 115 | end 116 | end 117 | 118 | it "parses a month with leading zeroes" do 119 | d = Date.today 120 | Date.strptime("04", "%m").should == Date.civil(d.year, 4, 1) 121 | end 122 | 123 | it "should be able to parse the number of seconds since the unix epoch" do 124 | Date.strptime("954979200000", "%Q").should == Date.civil(2000, 4, 6) 125 | Date.strptime("32511888000000", "%Q").should == Date.civil(3000, 4, 6) 126 | end 127 | 128 | it "should be able to parse the number of seconds since the unix epoch" do 129 | Date.strptime("954979200", "%s").should == Date.civil(2000, 4, 6) 130 | Date.strptime("32511888000", "%s").should == Date.civil(3000, 4, 6) 131 | end 132 | 133 | it "should be able to pase the commercial day" do 134 | Date.strptime("1", "%u").should == Date.commercial(Date.today.year, 1, 1) 135 | Date.strptime("15 3", "%V %u").should == Date.commercial(Date.today.year, 15, 3) 136 | end 137 | 138 | it "should be able to show the commercial week" do 139 | d = Date.commercial(Date.today.year,1,1) 140 | Date.strptime("1", "%V").should == d 141 | Date.strptime("15", "%V").should == Date.commercial(d.cwyear, 15, 1) 142 | end 143 | 144 | it "parses a week number for a week starting on Sunday" do 145 | Date.strptime("2010/1", "%Y/%U").should == Date.civil(2010, 1, 3) 146 | end 147 | 148 | it "parses a week number for a week starting on Monday" do 149 | Date.strptime("2010/1", "%Y/%W").should == Date.civil(2010, 1, 4) 150 | end 151 | 152 | it "parses a commercial week day" do 153 | Date.strptime("2008 1", "%G %u").should == Date.civil(2007, 12, 31) 154 | end 155 | 156 | it "parses a commercial week" do 157 | d = Date.commercial(Date.today.cwyear,1,1) 158 | Date.strptime("1", "%V").should == d 159 | Date.strptime("15", "%V").should == Date.commercial(d.cwyear, 15, 1) 160 | end 161 | 162 | it "parses a week day" do 163 | d = Date.today 164 | Date.strptime("2007 4", "%Y %w").should == Date.civil(2007, 1, 4) 165 | end 166 | 167 | it "parses a full year " do 168 | Date.strptime("2007", "%Y").should == Date.civil(2007, 1, 1) 169 | Date.strptime("200", "%Y").should == Date.civil(200, 1, 1) 170 | Date.strptime("20000", "%Y").should == Date.civil(20000, 1, 1) 171 | end 172 | 173 | it "parses a full year with trailing numbers" do 174 | Date.strptime("20000", "%Y0").should == Date.civil(2000, 1, 1) 175 | Date.strptime("200002", "%Y%m").should == Date.civil(2000, 2, 1) 176 | end 177 | 178 | it "parses a year in YY format" do 179 | Date.strptime("00", "%y").should == Date.civil(2000, 1, 1) 180 | end 181 | 182 | it "should be able to parse escapes" do 183 | Date.strptime("00 % \n \t %1", "%y %% %n %t %%1").should == Date.civil(2000, 1, 1) 184 | end 185 | 186 | it "parse a %Y%m%d date" do 187 | Date.strptime("20000203", "%Y%m%d").should == Date.civil(2000, 2, 3) 188 | end 189 | 190 | 191 | ############################ 192 | # Specs that combine stuff # 193 | ############################ 194 | 195 | it "parses a full date" do 196 | Date.strptime("Thu Apr 6 00:00:00 2000", "%c").should == Date.civil(2000, 4, 6) 197 | Date.strptime("Thu Apr 6 00:00:00 2000", "%a %b %e %H:%M:%S %Y").should == Date.civil(2000, 4, 6) 198 | end 199 | 200 | it "parses a full date with trailing digits" do 201 | Date.strptime("Thu Apr 6 00:00:00 20000", "%c0").should == Date.civil(2000, 4, 6) 202 | Date.strptime("Thu Apr 6 00:00:00 200012", "%c%m").should == Date.civil(2000, 12, 6) 203 | end 204 | 205 | it "parses a date with slashes" do 206 | Date.strptime("04/06/00", "%D").should == Date.civil(2000, 4, 6) 207 | Date.strptime("04/06/00", "%m/%d/%y").should == Date.civil(2000, 4, 6) 208 | end 209 | 210 | it "parses a date given as YYYY-MM-DD" do 211 | Date.strptime("2000-04-06", "%F").should == Date.civil(2000, 4, 6) 212 | Date.strptime("2000-04-06", "%Y-%m-%d").should == Date.civil(2000, 4, 6) 213 | end 214 | 215 | it "parses a civil format with month name" do 216 | Date.strptime(" 9-Apr-2000", "%v").should == Date.civil(2000, 4, 9) 217 | Date.strptime(" 9-Apr-2000", "%e-%b-%Y").should == Date.civil(2000, 4, 9) 218 | end 219 | 220 | it "parses a civil format with month name with trailing digits" do 221 | Date.strptime(" 9-Apr-20000", "%v0").should == Date.civil(2000, 4, 9) 222 | Date.strptime(" 9-Apr-200012", "%v%m").should == Date.civil(2000, 12, 9) 223 | end 224 | 225 | it "parses a date given MM/DD/YY" do 226 | Date.strptime("04/06/00", "%x").should == Date.civil(2000, 4, 6) 227 | Date.strptime("04/06/00", "%m/%d/%y").should == Date.civil(2000, 4, 6) 228 | end 229 | 230 | it "parses a date given in full notation" do 231 | Date.strptime("Sun Apr 9 00:00:00 +00:00 2000", "%+").should == Date.civil(2000, 4, 9) 232 | Date.strptime("Sun Apr 9 00:00:00 +00:00 2000", "%a %b %e %H:%M:%S %Z %Y").should == Date.civil(2000, 4, 9) 233 | end 234 | 235 | it "parses a date given in full notation with trailing digits" do 236 | Date.strptime("Sun Apr 9 00:00:00 +00:00 20000", "%+0").should == Date.civil(2000, 4, 9) 237 | Date.strptime("Sun Apr 9 00:00:00 +00:00 200012", "%+%m").should == Date.civil(2000, 12, 9) 238 | end 239 | end 240 | -------------------------------------------------------------------------------- /spec/date/succ_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#succ" do 4 | it "should be the next day" do 5 | ds = Date.civil(2008, 10, 11) 6 | ds.succ.should == Date.civil(2008, 10, 12) 7 | ds = Date.civil(2008, 10, 31) 8 | ds.succ.should == Date.civil(2008, 11, 1) 9 | ds = Date.commercial(2008, 2, 7) 10 | ds.succ.should == Date.commercial(2008, 3, 1) 11 | ds = Date.jd(2008) 12 | ds.succ.should == Date.jd(2009) 13 | ds = Date.ordinal(2008, 366) 14 | ds.succ.should == Date.ordinal(2009, 1) 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(Date) 19 | c.jd.succ.should be_kind_of(c) 20 | end 21 | 22 | it "should be aliased as next" do 23 | Date.civil(2008, 10, 11).next.should == Date.civil(2008, 10, 12) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/date/today_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date.today" do 4 | it "should be today's date" do 5 | t = Time.now 6 | d = Date.today 7 | d.year.should == t.year 8 | d.mon.should == t.mon 9 | d.day.should == t.day 10 | end 11 | 12 | it ".today should have an optional sg value" do 13 | Date.today(1).should == Date.today 14 | end 15 | 16 | it "should keep the same class as the receiver" do 17 | c = Class.new(Date) 18 | c.today.should be_kind_of(c) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/date/upto_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "Date#upto" do 4 | 5 | it "should be able to step forward in time" do 6 | ds = Date.civil(2008, 10, 11) 7 | de = Date.civil(2008, 9, 29) 8 | count = 0 9 | de.upto(ds) do |d| 10 | d.should <= ds 11 | d.should >= de 12 | count += 1 13 | end 14 | count.should == 13 15 | end 16 | 17 | 18 | it "should keep the same class as the receiver" do 19 | c = Class.new(Date) 20 | c.jd.upto(c.jd + 2) do |d| 21 | d.should be_kind_of(c) 22 | end.should be_kind_of(c) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/datetime/accessor_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#day_fraction" do 4 | it "should be able to determine the fraction of the day" do 5 | DateTime.new(2008, 1, 1).day_fraction.should == 0.0 6 | DateTime.new(2008, 1, 1, 12).day_fraction.should == 0.5 7 | DateTime.new(2008, 1, 1, 6).day_fraction.should == 0.25 8 | end 9 | end 10 | 11 | describe "DateTime#hour" do 12 | it "should be able to determine the hour of the day" do 13 | DateTime.jd(2007, 1).hour.should == 1 14 | end 15 | end 16 | 17 | describe "DateTime#min" do 18 | it "should be able to determine the minute of the day" do 19 | DateTime.jd(2007, 1, 2).min.should == 2 20 | end 21 | end 22 | 23 | describe "DateTime#offset" do 24 | it "should be able to determine the offset of the day from UTC" do 25 | DateTime.jd(2007, 1, 2, 3, 6/24.0).offset.should == 6/24.0 26 | DateTime.parse('2008-01-01 00:00:00+12:00').offset.should == 0.5 27 | end 28 | 29 | ruby_version_is "" ... "1.9" do 30 | it "#of should be the offset as a float fraction of the day" do 31 | DateTime.parse('2008-01-01 00:00:00+12:00').of.should == 0.5 32 | end 33 | end 34 | end 35 | 36 | describe "DateTime#sec" do 37 | it "should be able to determine the second of the day" do 38 | DateTime.jd(2007, 1, 2, 3).sec.should == 3 39 | end 40 | end 41 | 42 | describe "DateTime#sec_fraction" do 43 | ruby_version_is "" ... "1.9" do 44 | it "should be the fraction of a second as a fraction of the day" do 45 | DateTime.new(2008, 1, 1).sec_fraction.should == 0.0 46 | DateTime.parse('12:13:15.678900').sec_fraction.should be_close(7.85763888888889e-06, 0.0000000000001) 47 | end 48 | end 49 | 50 | ruby_version_is "1.9" do 51 | it "should be the fraction of a second" do 52 | DateTime.new(2008, 1, 1).sec_fraction.should == 0.0 53 | DateTime.parse('12:13:15.678900').sec_fraction.should be_close(0.6789, 0.0000000000001) 54 | end 55 | end 56 | end 57 | 58 | describe "DateTime#zone" do 59 | it "should give the offset as a string" do 60 | DateTime.jd(0).zone.should == '+00:00' 61 | DateTime.jd(2007, 0, 0, 0, -1/24.0).zone.should == '-01:00' 62 | end 63 | end 64 | 65 | describe "DateTime#cwyear" do 66 | it "should be able to determine the commercial year for a date" do 67 | DateTime.civil(2007, 1, 17).cwyear.should == 2007 68 | DateTime.civil(2008, 10, 28).cwyear.should == 2008 69 | DateTime.civil(2007, 12, 31).cwyear.should == 2008 70 | DateTime.civil(2010, 1, 1).cwyear.should == 2009 71 | DateTime.commercial(2008, 1, 1).cwyear.should == 2008 72 | DateTime.commercial(2008, 52, 1).cwyear.should == 2008 73 | DateTime.jd(2454782).cwyear.should == 2008 74 | DateTime.jd(2454832).cwyear.should == 2009 75 | DateTime.ordinal(2008, 1).cwyear.should == 2008 76 | DateTime.ordinal(2008, 359).cwyear.should == 2008 77 | DateTime.ordinal(2008, 366).cwyear.should == 2009 78 | end 79 | end 80 | 81 | describe "DateTime#cweek" do 82 | it "should be able to determine the commercial week for a date" do 83 | DateTime.civil(2007, 1, 17).cweek.should == 3 84 | DateTime.civil(2008, 10, 28).cweek.should == 44 85 | DateTime.civil(2007, 12, 31).cweek.should == 1 86 | DateTime.civil(2010, 1, 1).cweek.should == 53 87 | DateTime.commercial(2008, 1, 1).cweek.should == 1 88 | DateTime.commercial(2008, 10, 5).cweek.should == 10 89 | DateTime.jd(2454782).cweek.should == 46 90 | DateTime.jd(2454789).cweek.should == 47 91 | DateTime.ordinal(2008, 1).cweek.should == 1 92 | DateTime.ordinal(2008, 359).cweek.should == 52 93 | DateTime.ordinal(2008, 366).cweek.should == 1 94 | end 95 | end 96 | 97 | describe "DateTime#cwday" do 98 | it "should be able to determine the commercial week day for a date" do 99 | DateTime.civil(2007, 1, 17).cwday.should == 3 100 | DateTime.civil(2008, 10, 26).cwday.should == 7 101 | DateTime.commercial(2008, 1, 1).cwday.should == 1 102 | DateTime.commercial(2008, 10, 5).cwday.should == 5 103 | DateTime.jd(2454782).cwday.should == 2 104 | DateTime.jd(2454786).cwday.should == 6 105 | DateTime.ordinal(2008, 1).cwday.should == 2 106 | DateTime.ordinal(2008, 317).cwday.should == 3 107 | end 108 | end 109 | 110 | describe "DateTime#mday and #day" do 111 | it "should be able to determine the day of the month for a date" do 112 | DateTime.civil(2007, 1, 17).mday.should == 17 113 | DateTime.civil(2008, 10, 28).mday.should == 28 114 | DateTime.civil(2007, 1, 17).day.should == 17 115 | DateTime.civil(2008, 10, 28).day.should == 28 116 | DateTime.commercial(2008, 1, 1).day.should == 31 117 | DateTime.commercial(2008, 52, 1).day.should == 22 118 | DateTime.jd(2454782).day.should == 11 119 | DateTime.jd(2454832).day.should == 31 120 | DateTime.ordinal(2008, 1).day.should == 1 121 | DateTime.ordinal(2008, 359).day.should == 24 122 | DateTime.ordinal(2008, 366).day.should == 31 123 | end 124 | end 125 | 126 | describe "DateTime#jd" do 127 | it "should be able to determine the julian date for a date" do 128 | DateTime.civil(2007, 1, 17).jd.should == 2454118 129 | DateTime.civil(2008, 10, 28).jd.should == 2454768 130 | DateTime.commercial(2008, 1, 1).jd.should == 2454466 131 | DateTime.commercial(2008, 52, 1).jd.should == 2454823 132 | DateTime.jd(2454782).jd.should == 2454782 133 | DateTime.jd(2454832).jd.should == 2454832 134 | DateTime.ordinal(2008, 1).jd.should == 2454467 135 | DateTime.ordinal(2008, 359).jd.should == 2454825 136 | DateTime.ordinal(2008, 366).jd.should == 2454832 137 | end 138 | end 139 | 140 | describe "DateTime#ajd" do 141 | it "should be a float of the astronomical julian day" do 142 | DateTime.jd(2008).ajd.should == 2007.5 143 | DateTime.jd(2008, 12).ajd.should == 2008 144 | DateTime.jd(2008, 0, 0, 0, -0.5).ajd.should == 2008 145 | DateTime.jd(2008, 12, 0, 0, -0.5).ajd.should == 2008.5 146 | end 147 | end 148 | 149 | describe "DateTime#amjd" do 150 | it "#amjd should be a float of the astronomical julian day" do 151 | DateTime.jd(2008).amjd.should == -2397993.0 152 | DateTime.jd(2008, 12).amjd.should == -2397992.5 153 | DateTime.jd(2008, 0, 0, 0, -0.5).amjd.should == -2397992.5 154 | DateTime.jd(2008, 12, 0, 0, -0.5).amjd.should == -2397992.0 155 | end 156 | end 157 | 158 | describe "DateTime#mjd" do 159 | it "should be able to determine the Modified Julian day for a date" do 160 | DateTime.civil(2007, 1, 17).mjd.should == 54117 161 | end 162 | end 163 | 164 | describe "DateTime#ld" do 165 | it "should be able to determine the Modified Julian day for a date" do 166 | DateTime.civil(2007, 1, 17).ld.should == 154958 167 | end 168 | end 169 | 170 | describe "DateTime#wday" do 171 | it "should be able to determine the week day for a date" do 172 | DateTime.civil(2007, 1, 17).wday.should == 3 173 | DateTime.civil(2008, 10, 26).wday.should == 0 174 | DateTime.commercial(2008, 1, 1).wday.should == 1 175 | DateTime.commercial(2008, 52, 1).wday.should == 1 176 | DateTime.jd(2454782).wday.should == 2 177 | DateTime.jd(2454832).wday.should == 3 178 | DateTime.ordinal(2008, 1).wday.should == 2 179 | DateTime.ordinal(2008, 170).wday.should == 3 180 | DateTime.ordinal(2008, 366).wday.should == 3 181 | end 182 | end 183 | 184 | describe "DateTime#year" do 185 | it "should be able to determine the year for a date" do 186 | DateTime.civil(2007, 1, 17).year.should == 2007 187 | DateTime.civil(2008, 1, 17).year.should == 2008 188 | DateTime.commercial(2008, 1, 1).year.should == 2007 189 | DateTime.commercial(2008, 52, 1).year.should == 2008 190 | DateTime.jd(2454782).year.should == 2008 191 | DateTime.jd(2454833).year.should == 2009 192 | DateTime.ordinal(2008, 1).year.should == 2008 193 | DateTime.ordinal(2008, 170).year.should == 2008 194 | DateTime.ordinal(2008, 366).year.should == 2008 195 | end 196 | end 197 | 198 | describe "DateTime#yday" do 199 | it "should be able to determine the year for a date" do 200 | DateTime.civil(2007, 1, 17).yday.should == 17 201 | DateTime.civil(2008, 10, 28).yday.should == 302 202 | DateTime.commercial(2008, 1, 1).yday.should == 365 203 | DateTime.commercial(2008, 52, 1).yday.should == 357 204 | DateTime.jd(2454782).yday.should == 316 205 | DateTime.jd(2454832).yday.should == 366 206 | DateTime.ordinal(2008, 1).yday.should == 1 207 | DateTime.ordinal(2008, 170).yday.should == 170 208 | DateTime.ordinal(2008, 366).yday.should == 366 209 | end 210 | end 211 | 212 | describe "DateTime#mon and #month" do 213 | it "should be able to determine the month for a date" do 214 | DateTime.civil(2007, 1, 17).mon.should == 1 215 | DateTime.civil(2008, 10, 28).mon.should == 10 216 | DateTime.civil(2007, 1, 17).month.should == 1 217 | DateTime.civil(2008, 10, 28).month.should == 10 218 | DateTime.commercial(2008, 1, 1).mon.should == 12 219 | DateTime.commercial(2008, 52, 1).mon.should == 12 220 | DateTime.jd(2454782).mon.should == 11 221 | DateTime.jd(2454832).mon.should == 12 222 | DateTime.ordinal(2008, 1).mon.should == 1 223 | DateTime.ordinal(2008, 170).mon.should == 6 224 | DateTime.ordinal(2008, 366).mon.should == 12 225 | end 226 | end 227 | 228 | -------------------------------------------------------------------------------- /spec/datetime/add_month_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#>>" do 4 | 5 | it "should add a number of months to a DateTime" do 6 | (DateTime.civil(2007,2,27) >> 10).should == DateTime.civil(2007, 12, 27) 7 | (DateTime.civil(2007,2,27) >> 10).should == DateTime.civil(2007, 12, 27) 8 | (DateTime.commercial(2007,2,2) >> 10).should == DateTime.commercial(2007, 45, 5) 9 | (DateTime.jd(2454782) >> 10).should == DateTime.jd(2455086) 10 | (DateTime.ordinal(2008, 10) >> 10).should == DateTime.ordinal(2008, 315) 11 | (DateTime.civil(2007,2,27) >> 22).should == DateTime.civil(2008, 12, 27) 12 | (DateTime.civil(2007,2,27) >> -2).should == DateTime.civil(2006, 12, 27) 13 | end 14 | 15 | it "should result in the last day of a month if the day doesn't exist" do 16 | d = DateTime.civil(2008,3,31) >> 1 17 | d.should == DateTime.civil(2008, 4, 30) 18 | end 19 | 20 | it "should keep the same class as the receiver" do 21 | c = Class.new(DateTime) 22 | c.jd.>>(10).should be_kind_of(c) 23 | end 24 | 25 | it "should raise an error on non numeric parameters" do 26 | lambda { DateTime.civil(2007,2,27) >> "hello" }.should raise_error(TypeError) 27 | lambda { DateTime.civil(2007,2,27) >> DateTime.new }.should raise_error(TypeError) 28 | lambda { DateTime.civil(2007,2,27) >> Object.new }.should raise_error(TypeError) 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /spec/datetime/add_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#+" do 4 | 5 | it "should add a number of days to a Date" do 6 | (DateTime.civil(2007,2,27) + 315).should == DateTime.civil(2008, 1, 8) 7 | (DateTime.commercial(2007,2,2) + 315).should == DateTime.commercial(2007, 47, 2) 8 | (DateTime.jd(2454782) + 315).should == DateTime.jd(2455097) 9 | (DateTime.ordinal(2008, 10) + 315).should == DateTime.ordinal(2008, 325) 10 | end 11 | 12 | it "should add a fractional number of days to a Date" do 13 | (DateTime.civil(2007,2,27) + 315.5).should == DateTime.civil(2008, 1, 8, 12) 14 | (DateTime.commercial(2007,2,2) + 315.75).should == DateTime.commercial(2007, 47, 2, 18) 15 | (DateTime.jd(2454782) + 315.25).should == DateTime.jd(2455097, 6) 16 | (DateTime.ordinal(2008, 10) + 315.25).should == DateTime.ordinal(2008, 325, 6) 17 | end 18 | 19 | it "should add a negative number of days to a Date" do 20 | d = DateTime.civil(2007,2,27).+(-10) 21 | d.should == DateTime.civil(2007, 2, 17) 22 | end 23 | 24 | it "should add a fractional negative number of days to a Date" do 25 | d = DateTime.civil(2007,2,27).+(-10.5) 26 | d.should == DateTime.civil(2007, 2, 16, 12) 27 | end 28 | 29 | it "should keep the same class as the receiver" do 30 | c = Class.new(DateTime) 31 | c.jd.+(10).should be_kind_of(c) 32 | end 33 | 34 | it "should raise an error on non numeric parameters" do 35 | lambda { DateTime.civil(2007,2,27) + :hello }.should raise_error 36 | lambda { DateTime.civil(2007,2,27) + "hello" }.should raise_error 37 | lambda { DateTime.civil(2007,2,27) + DateTime.new(2007,2,27) }.should raise_error 38 | lambda { DateTime.civil(2007,2,27) + Object.new }.should raise_error 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /spec/datetime/allocate_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime.allocate" do 4 | it "should be the same as jd" do 5 | DateTime.allocate.should == DateTime.jd 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/datetime/boat_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#<=>" do 4 | 5 | it "should be able to compare two same DateTimes" do 6 | (DateTime.civil(2000, 04, 06) <=> DateTime.civil(2000, 04, 06)).should == 0 7 | (DateTime.civil(2000, 04, 06, 10, 12, 11) <=> DateTime.civil(2000, 04, 06, 10, 12, 11)).should == 0 8 | end 9 | 10 | it "should be able to compute the difference between two DateTimes" do 11 | (DateTime.civil(2000, 04, 05) <=> DateTime.civil(2000, 04, 06)).should == -1 12 | (DateTime.civil(2001, 04, 05) <=> DateTime.civil(2000, 04, 06)).should == 1 13 | (DateTime.civil(2000, 04, 05, 10, 12, 13, 1/24.0) <=> DateTime.civil(2000, 04, 05, 10, 12, 13, 2/24.0)).should == 1 14 | (DateTime.civil(2001, 04, 05, 10, 12, 13, 1/24.0) <=> DateTime.civil(2001, 04, 05, 10, 12, 13, 0)).should == -1 15 | end 16 | 17 | it "should be able to compare to another numeric" do 18 | (DateTime.civil(2000, 04, 05) <=> DateTime.civil(2000, 04, 06).jd).should == -1 19 | (DateTime.civil(2001, 04, 05) <=> DateTime.civil(2000, 04, 06).jd).should == 1 20 | 21 | (DateTime.civil(2000, 04, 05).jd <=> 2451640).should == 0 22 | (DateTime.civil(2000, 04, 05) <=> 2451640.00000001).should == -1 23 | (DateTime.civil(2000, 04, 05) <=> 2451639.99999999).should == 1 24 | end 25 | 26 | end 27 | 28 | describe "DateTime#between?" do 29 | it "should be true if the DateTime falls in between the two given DateTimes" do 30 | (DateTime.civil(2000, 04, 06).between?(DateTime.civil(2000, 04, 05), DateTime.civil(2000, 04, 07))).should == true 31 | (DateTime.civil(2000, 04, 06).between?(DateTime.civil(2000, 04, 06), DateTime.civil(2000, 04, 07))).should == true 32 | (DateTime.civil(2000, 04, 06).between?(DateTime.civil(2000, 04, 05), DateTime.civil(2000, 04, 06))).should == true 33 | 34 | (DateTime.civil(2000, 04, 06, 10, 12, 11, 3/24.0).between?(DateTime.civil(2000, 04, 06, 10, 12, 11, 4/24.0), DateTime.civil(2000, 04, 06, 10, 12, 11, 2/24.0))).should == true 35 | (DateTime.civil(2000, 04, 06, 10, 12, 11, 2/24.0).between?(DateTime.civil(2000, 04, 06, 10, 12, 11, 4/24.0), DateTime.civil(2000, 04, 06, 10, 12, 11, 2/24.0))).should == true 36 | (DateTime.civil(2000, 04, 06, 10, 12, 11, 4/24.0).between?(DateTime.civil(2000, 04, 06, 10, 12, 11, 4/24.0), DateTime.civil(2000, 04, 06, 10, 12, 11, 2/24.0))).should == true 37 | end 38 | 39 | it "should be false if the DateTime does not fall in between the two given DateTimes" do 40 | (DateTime.civil(2000, 04, 05).between?(DateTime.civil(2000, 04, 06), DateTime.civil(2000, 04, 07))).should == false 41 | (DateTime.civil(2000, 04, 06, 10, 12, 11, 5/24.0).between?(DateTime.civil(2000, 04, 06, 10, 12, 11, 4/24.0), DateTime.civil(2000, 04, 06, 10, 12, 11, 2/24.0))).should == false 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/datetime/clone_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#clone" do 4 | before do 5 | @d = DateTime.now 6 | end 7 | 8 | it "should return a copy of the date" do 9 | @d.clone.should == @d 10 | end 11 | 12 | it "should return a different object_id" do 13 | @d.clone.object_id.should_not == @d.object_id 14 | end 15 | 16 | it "should keep frozen status" do 17 | @d.freeze 18 | @d.clone.frozen?.should be_true 19 | end 20 | 21 | it "should keep singleton_methods" do 22 | class << @d; def foo() 1 end end 23 | @d.clone.respond_to?(:foo).should be_true 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/datetime/constructor_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime constructors" do 4 | it ".civil creates a datetime with arguments" do 5 | d = DateTime.civil(2000, 3, 5, 6, 7, 8, 1/24.0) 6 | d.year.should == 2000 7 | d.month.should == 3 8 | d.day.should == 5 9 | d.hour.should == 6 10 | d.min.should == 7 11 | d.sec.should == 8 12 | d.offset.should == 1/24.0 13 | end 14 | 15 | it ".civil should have defaults and an optional sg value" do 16 | DateTime.civil.should == DateTime.jd 17 | DateTime.civil(2008).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 18 | DateTime.civil(2008, 1).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 19 | DateTime.civil(2008, 1, 1).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 20 | DateTime.civil(2008, 1, 1, 0).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 21 | DateTime.civil(2008, 1, 1, 0, 0).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 22 | DateTime.civil(2008, 1, 1, 0, 0, 0).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 23 | DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0).should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.0) 24 | DateTime.civil(2008, 1, 1, 1, 1, 1, 0.5, 1).should == DateTime.civil(2008, 1, 1, 1, 1, 1, 0.5) 25 | end 26 | 27 | it ".commercial creates a datetime with arguments" do 28 | d = DateTime.commercial(2000, 3, 5, 6, 7, 8, 1/24.0) 29 | d.cwyear.should == 2000 30 | d.cweek.should == 3 31 | d.cwday.should == 5 32 | d.hour.should == 6 33 | d.min.should == 7 34 | d.sec.should == 8 35 | d.offset.should == 1/24.0 36 | end 37 | 38 | ruby_version_is "1.9" do 39 | it ".commercial should have defaults and an optional sg value" do 40 | DateTime.commercial.should == DateTime.jd 41 | DateTime.commercial(2008).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 42 | DateTime.commercial(2008, 1).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 43 | DateTime.commercial(2008, 1, 1).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 44 | DateTime.commercial(2008, 1, 1, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 45 | DateTime.commercial(2008, 1, 1, 0, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 46 | DateTime.commercial(2008, 1, 1, 0, 0, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 47 | DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 48 | DateTime.commercial(2008, 1, 1, 1, 1, 1, 0.5, 1).should == DateTime.commercial(2008, 1, 1, 1, 1, 1, 0.5) 49 | end 50 | end 51 | 52 | ruby_version_is "" ... "1.9" do 53 | it ".commercial should have defaults and an optional sg value" do 54 | DateTime.commercial.should == DateTime.commercial(1582, 41, 5) 55 | DateTime.commercial(2008).should == DateTime.commercial(2008, 41, 5, 0, 0, 0, 0.0) 56 | DateTime.commercial(2008, 1).should == DateTime.commercial(2008, 1, 5, 0, 0, 0, 0.0) 57 | DateTime.commercial(2008, 1, 1).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 58 | DateTime.commercial(2008, 1, 1, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 59 | DateTime.commercial(2008, 1, 1, 0, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 60 | DateTime.commercial(2008, 1, 1, 0, 0, 0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 61 | DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0).should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.0) 62 | DateTime.commercial(2008, 1, 1, 1, 1, 1, 0.5, 1).should == DateTime.commercial(2008, 1, 1, 1, 1, 1, 0.5) 63 | end 64 | end 65 | 66 | it ".jd creates a datetime with arguments" do 67 | d = DateTime.jd(2000, 6, 7, 8, 1/24.0) 68 | d.jd.should == 2000 69 | d.hour.should == 6 70 | d.min.should == 7 71 | d.sec.should == 8 72 | d.offset.should == 1/24.0 73 | end 74 | 75 | it ".jd handles a fractional date as first argument" do 76 | d = DateTime.jd(2000.5) 77 | d.jd.should == 2000 78 | d.hour.should == 12 79 | d.min.should == 0 80 | d.sec.should == 0 81 | d.offset.should == 0 82 | end 83 | 84 | it ".jd should raise an error if given a float as first argument and any additional arguments" do 85 | proc{DateTime.jd(2000.5, 1)}.should raise_error(ArgumentError) 86 | end 87 | 88 | it ".jd should have defaults and an optional sg value" do 89 | DateTime.jd.should == DateTime.jd(0, 0, 0, 0, 0) 90 | DateTime.jd(0).should == DateTime.jd(0, 0, 0, 0, 0) 91 | DateTime.jd(0, 0).should == DateTime.jd(0, 0, 0, 0, 0) 92 | DateTime.jd(0, 0, 0).should == DateTime.jd(0, 0, 0, 0, 0) 93 | DateTime.jd(0, 0, 0, 0).should == DateTime.jd(0, 0, 0, 0, 0) 94 | DateTime.jd(0, 0, 0, 0, 0).should == DateTime.jd(0, 0, 0, 0, 0) 95 | DateTime.jd(2008, 1, 1, 1, 0.5, 1).should == DateTime.jd(2008, 1, 1, 1, 0.5) 96 | end 97 | 98 | it ".new! creates a datetime with arguments" do 99 | d = DateTime.new!(2422222) 100 | d.jd.should == 2422222 101 | d.hour.should == 12 102 | d.min.should == 0 103 | d.sec.should == 0 104 | d.offset.should == 0 105 | 106 | d = DateTime.new!(2422222.5) 107 | d.jd.should == 2422223 108 | d.hour.should == 0 109 | d.min.should == 0 110 | d.sec.should == 0 111 | d.offset.should == 0 112 | 113 | d = DateTime.new!(2422222, 0.5) 114 | d.jd.should == 2422223 115 | d.hour.should == 0 116 | d.min.should == 0 117 | d.sec.should == 0 118 | d.offset.should == 0.5 119 | 120 | d = DateTime.new!(2422222.5, 0.5) 121 | d.jd.should == 2422223 122 | d.hour.should == 12 123 | d.min.should == 0 124 | d.sec.should == 0 125 | d.offset.should == 0.5 126 | end 127 | 128 | it ".new! should have defaults and an optional sg value" do 129 | DateTime.new!.should == DateTime.jd 130 | DateTime.new!(0).should == DateTime.new!(0, 0) 131 | DateTime.new!(0, 0).should == DateTime.new!(0, 0) 132 | DateTime.new!(2008, 0.5, 1).should == DateTime.new!(2008, 0.5) 133 | end 134 | 135 | it ".ordinal creates a datetime with arguments" do 136 | d = DateTime.ordinal(2000, 100, 6, 7, 8, 1/24.0) 137 | d.year.should == 2000 138 | d.yday.should == 100 139 | d.hour.should == 6 140 | d.min.should == 7 141 | d.sec.should == 8 142 | d.offset.should == 1/24.0 143 | end 144 | 145 | it ".ordinal should have defaults and an optional sg value" do 146 | DateTime.ordinal.should == DateTime.jd 147 | DateTime.ordinal(2008).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 148 | DateTime.ordinal(2008, 1).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 149 | DateTime.ordinal(2008, 1, 0).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 150 | DateTime.ordinal(2008, 1, 0, 0).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 151 | DateTime.ordinal(2008, 1, 0, 0, 0).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 152 | DateTime.ordinal(2008, 1, 0, 0, 0, 0).should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 153 | DateTime.ordinal(2008, 1, 1, 1, 1, 0.5, 1).should == DateTime.ordinal(2008, 1, 1, 1, 1, 0.5) 154 | end 155 | 156 | it "should keep the same class as the receiver" do 157 | c = Class.new(DateTime) 158 | c.jd.should be_kind_of(c) 159 | c.civil.should be_kind_of(c) 160 | c.commercial.should be_kind_of(c) 161 | c.ordinal.should be_kind_of(c) 162 | c.new!.should be_kind_of(c) 163 | c.new.should be_kind_of(c) 164 | end 165 | 166 | it "should handle strings for the offset" do 167 | DateTime.jd(2008, 0, 0, 0, 'Z').should == DateTime.jd(2008, 0, 0, 0, 0) 168 | DateTime.civil(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0) 169 | DateTime.commercial(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0) 170 | DateTime.ordinal(2008, 1, 0, 0, 0, 'Z').should == DateTime.ordinal(2008, 1, 0, 0, 0, 0) 171 | DateTime.new(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.new(2008, 1, 1, 0, 0, 0, 0) 172 | 173 | DateTime.jd(2008, 0, 0, 0, '+1200').should == DateTime.jd(2008, 0, 0, 0, 0.5) 174 | DateTime.civil(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.5) 175 | DateTime.commercial(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.5) 176 | DateTime.ordinal(2008, 1, 0, 0, 0, '+1200').should == DateTime.ordinal(2008, 1, 0, 0, 0, 0.5) 177 | DateTime.new(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.new(2008, 1, 1, 0, 0, 0, 0.5) 178 | end 179 | 180 | it "should handle fractional seconds in seconds" do 181 | DateTime.jd(2008, 0, 0, 1.5).should == DateTime.jd(2008, 0, 0, 1) + (0.5/86400) 182 | DateTime.civil(2008, 1, 1, 0, 0, 1.5).should == DateTime.civil(2008, 1, 1, 0, 0, 1) + (0.5/86400) 183 | DateTime.commercial(2008, 1, 1, 0, 0, 1.5).should == DateTime.commercial(2008, 1, 1, 0, 0, 1) + (0.5/86400) 184 | DateTime.ordinal(2008, 1, 0, 0, 1.5).should == DateTime.ordinal(2008, 1, 0, 0, 1) + (0.5/86400) 185 | DateTime.new(2008, 1, 1, 0, 0, 1.5).should == DateTime.new(2008, 1, 1, 0, 0, 1) + (0.5/86400) 186 | end 187 | end 188 | -------------------------------------------------------------------------------- /spec/datetime/conversions_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime conversions" do 4 | it "#new_offset should be a separate datetime with a modified offset" do 5 | DateTime.new(2008, 1, 1).new_offset(0.5).to_s.should == DateTime.new(2008, 1, 1, 12, 0, 0, 0.5).to_s 6 | end 7 | 8 | it "#new_offset should work with strings" do 9 | DateTime.new(2008, 1, 1).new_offset('+12:00').to_s.should == DateTime.new(2008, 1, 1, 12, 0, 0, 0.5).to_s 10 | end 11 | 12 | it "#new_offset result should be equal to the receiver" do 13 | DateTime.new(2008, 1, 1).new_offset(0.5).should == DateTime.new(2008, 1, 1) 14 | end 15 | 16 | it "should keep the same class as the receiver" do 17 | c = Class.new(DateTime) 18 | c.jd.new_offset.should be_kind_of(c) 19 | end 20 | 21 | ruby_version_is "" ... "1.9" do 22 | it "#newof should be a separate datetime with a modified offset" do 23 | DateTime.new(2008, 1, 1).newof(0.5).to_s.should == DateTime.new(2008, 1, 1, 12, 0, 0, 0.5).to_s 24 | end 25 | end 26 | end 27 | 28 | describe "DateTime marshalling" do 29 | it "should marshal and unmarshal correctly" do 30 | Marshal.load(Marshal.dump(DateTime.jd)).should == DateTime.civil 31 | d = DateTime.now 32 | Marshal.load(Marshal.dump(d)).should == d 33 | Marshal.load(Marshal.dump(DateTime.civil(2010, 2, 4, 1, 2, 4, 4/24.0))).should == DateTime.civil(2010, 2, 4, 1, 2, 4, 4/24.0) 34 | end 35 | end 36 | 37 | ruby_version_is "1.9" do 38 | describe "DateTime#to_datetime" do 39 | it " should return the receiver" do 40 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).to_datetime.should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 41 | end 42 | end 43 | 44 | describe "DateTime#to_date" do 45 | it " should return a Date with the same date as receiver" do 46 | DateTime.new(2009, 1, 2, 12).to_date.should == Date.new(2009, 1, 2) 47 | end 48 | end 49 | 50 | describe "DateTime#to_time" do 51 | it " should return a Time in local time with the same year, month, day as the receiver" do 52 | DateTime.new(2009, 1, 2, 3, 4, 5).to_time.should == Time.utc(2009, 1, 2, 3, 4, 5).getlocal 53 | end 54 | end 55 | 56 | describe "Time#to_datetime" do 57 | it " should return a Date with the same year, month, and day as the receiver" do 58 | Time.utc(2009, 1, 2, 3, 4, 5).to_datetime.should == DateTime.new(2009, 1, 2, 3, 4, 5) 59 | Time.utc(2009, 1, 2, 3, 4, 5).getlocal.to_datetime.should == DateTime.new(2009, 1, 2, 3, 4, 5) 60 | end 61 | end 62 | end 63 | 64 | -------------------------------------------------------------------------------- /spec/datetime/day_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "DateTime#sunday?" do 5 | it "should return true if the day is a Sunday" do 6 | DateTime.civil(2009,1,4).sunday?.should == true 7 | end 8 | 9 | it "should return false if the day is not a Sunday" do 10 | DateTime.civil(2009,1,2).sunday?.should == false 11 | end 12 | end 13 | 14 | describe "DateTime#monday?" do 15 | it "should return true if the day is a Monday" do 16 | DateTime.civil(2009,1,5).monday?.should == true 17 | end 18 | 19 | it "should return false if the day is not a Monday" do 20 | DateTime.civil(2009,1,2).monday?.should == false 21 | end 22 | end 23 | 24 | describe "DateTime#tuesday?" do 25 | it "should return true if the day is a Tuesday" do 26 | DateTime.civil(2009,1,6).tuesday?.should == true 27 | end 28 | 29 | it "should return false if the day is not a Tuesday" do 30 | DateTime.civil(2009,1,2).tuesday?.should == false 31 | end 32 | end 33 | 34 | describe "DateTime#wednesday?" do 35 | it "should return true if the day is a Wednesday" do 36 | DateTime.civil(2009,1,7).wednesday?.should == true 37 | end 38 | 39 | it "should return false if the day is not a Tuesday" do 40 | DateTime.civil(2009,1,2).wednesday?.should == false 41 | end 42 | end 43 | 44 | describe "DateTime#thursday?" do 45 | it "should return true if the day is a Thursday" do 46 | DateTime.civil(2009,1,1).thursday?.should == true 47 | end 48 | 49 | it "should return false if the day is not a Thursday" do 50 | DateTime.civil(2009,1,2).thursday?.should == false 51 | end 52 | end 53 | 54 | describe "DateTime#friday?" do 55 | it "should return true if the day is a Friday" do 56 | DateTime.civil(2009,1,2).friday?.should == true 57 | end 58 | 59 | it "should return false if the day is not a Friday" do 60 | DateTime.civil(2009,1,1).friday?.should == false 61 | end 62 | end 63 | 64 | describe "DateTime#saturday?" do 65 | it "should return true if the day is a Saturday" do 66 | DateTime.civil(2009,1,3).saturday?.should == true 67 | end 68 | 69 | it "should return false if the day is not a Saturday" do 70 | DateTime.civil(2009,1,2).saturday?.should == false 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /spec/datetime/downto_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#downto" do 4 | 5 | it "should be able to step backward in time" do 6 | ds = DateTime.civil(2000, 4, 14) 7 | de = DateTime.civil(2000, 3, 29) 8 | count = 0 9 | ds.downto(de) do |d| 10 | d.should <= ds 11 | d.should >= de 12 | count += 1 13 | end 14 | count.should == 17 15 | end 16 | 17 | it "should respect fractional days" do 18 | ds = DateTime.civil(2000, 4, 14, 0) 19 | de = DateTime.civil(2000, 3, 29, 12) 20 | count = 0 21 | ds.downto(de) do |d| 22 | d.should <= ds 23 | d.should >= de 24 | count += 1 25 | end 26 | count.should == 16 27 | 28 | ds = DateTime.civil(2000, 4, 14, 12) 29 | de = DateTime.civil(2000, 3, 29, 0) 30 | count = 0 31 | ds.downto(de) do |d| 32 | d.should <= ds 33 | d.should >= de 34 | count += 1 35 | end 36 | count.should == 17 37 | end 38 | 39 | it "should keep the same class as the receiver" do 40 | c = Class.new(DateTime) 41 | c.jd.downto(c.jd - 2) do |d| 42 | d.should be_kind_of(c) 43 | end.should be_kind_of(c) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/datetime/dup_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#dup" do 4 | before do 5 | @d = DateTime.now 6 | end 7 | 8 | it "should return a copy of the date" do 9 | @d.dup.should == @d 10 | end 11 | 12 | it "should return a different object_id" do 13 | @d.dup.object_id.should_not == @d.object_id 14 | end 15 | 16 | it "should not keep frozen status" do 17 | @d.freeze 18 | @d.dup.frozen?.should be_false 19 | end 20 | 21 | it "should not keep singleton_methods" do 22 | class << @d; def foo() 1 end end 23 | @d.dup.respond_to?(:foo).should be_false 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/datetime/encoding_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "DateTime string encoding methods" do 5 | it "should return strings in US-ASCII encoding by default" do 6 | d = DateTime.now 7 | d.asctime.encoding.name.should == 'US-ASCII' 8 | d.ctime.encoding.name.should == 'US-ASCII' 9 | d.httpdate.encoding.name.should == 'US-ASCII' 10 | d.inspect.encoding.name.should == 'US-ASCII' 11 | d.iso8601.encoding.name.should == 'US-ASCII' 12 | d.jisx0301.encoding.name.should == 'US-ASCII' 13 | d.rfc2822.encoding.name.should == 'US-ASCII' 14 | d.rfc3339.encoding.name.should == 'US-ASCII' 15 | d.rfc822.encoding.name.should == 'US-ASCII' 16 | d.strftime('%S:%M:%H').encoding.name.should == 'US-ASCII' 17 | d.to_s.encoding.name.should == 'US-ASCII' 18 | d.xmlschema.encoding.name.should == 'US-ASCII' 19 | end 20 | 21 | it "should return strings in default_internal encoding if set" do 22 | begin 23 | Encoding.default_internal = 'UTF-8' 24 | d = DateTime.now 25 | d.asctime.encoding.name.should == 'UTF-8' 26 | d.ctime.encoding.name.should == 'UTF-8' 27 | d.httpdate.encoding.name.should == 'UTF-8' 28 | d.inspect.encoding.name.should == 'UTF-8' 29 | d.iso8601.encoding.name.should == 'UTF-8' 30 | d.jisx0301.encoding.name.should == 'UTF-8' 31 | d.rfc2822.encoding.name.should == 'UTF-8' 32 | d.rfc3339.encoding.name.should == 'UTF-8' 33 | d.rfc822.encoding.name.should == 'UTF-8' 34 | d.strftime('%S:%M:%H').encoding.name.should == 'UTF-8' 35 | d.to_s.encoding.name.should == 'UTF-8' 36 | d.xmlschema.encoding.name.should == 'UTF-8' 37 | ensure 38 | Encoding.default_internal = nil 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/datetime/eql_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#eql?" do 4 | it "should be able determine equality between date objects" do 5 | DateTime.civil(2007, 10, 11).should eql(DateTime.civil(2007, 10, 11)) 6 | DateTime.civil(2007, 10, 11, 10, 11, 12, 0.5).should eql(DateTime.civil(2007, 10, 11, 10, 11, 12, 0.5)) 7 | DateTime.civil(2007, 10, 11, 10, 11, 12, 0.5).should eql(DateTime.civil(2007, 10, 12, 10, 11, 12, 0.5) - 1) 8 | DateTime.civil(2007, 10, 11, 10, 11, 12, 0.5).should_not eql(DateTime.civil(2007, 10, 11, 10, 11, 12, 0.4)) 9 | end 10 | 11 | it "should be able determine equality between a date and a datetime objects" do 12 | DateTime.civil(2007, 10, 11).should eql(Date.civil(2007, 10, 11)) 13 | DateTime.civil(2007, 10, 11).should eql(Date.civil(2007, 10, 12) - 1) 14 | DateTime.civil(2007, 10, 11).should_not eql(Date.civil(2007, 10, 12)) 15 | DateTime.civil(2007, 10, 11, 1).should_not eql(Date.civil(2007, 10, 11)) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/datetime/format_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime formatting methods" do 4 | it "#asctime and #ctime should use a format similar to Time" do 5 | DateTime.new(2008, 1, 2, 10, 20, 30).asctime.should == 'Wed Jan 2 10:20:30 2008' 6 | DateTime.new(2008, 1, 2, 10, 20, 30).ctime.should == 'Wed Jan 2 10:20:30 2008' 7 | end 8 | 9 | it "#to_s should use an ISO8601 format" do 10 | DateTime.new(2008, 1, 2, 10, 20, 30, 8/24.0).to_s.should == '2008-01-02T10:20:30+08:00' 11 | end 12 | 13 | it "#inspect should use an ISO8601 format" do 14 | DateTime.new(2008, 1, 2, 10, 20, 30, 8/24.0).inspect.should == '#' 15 | end 16 | 17 | ruby_version_is "1.9" do 18 | it "#httpdate should use an HTTP format" do 19 | DateTime.new(2009, 1, 2, 3, 4, 5).httpdate.should == "Fri, 02 Jan 2009 03:04:05 GMT" 20 | end 21 | 22 | it "#iso8601 should use an ISO8601 format" do 23 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).iso8601.should == "2009-01-02T03:04:05+12:00" 24 | end 25 | 26 | it "#jisx03010 should use an JIS X 0301 format" do 27 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "H21.01.02T03:04:05+12:00" 28 | DateTime.new(1988, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "S63.01.02T03:04:05+12:00" 29 | DateTime.new(1925, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "T14.01.02T03:04:05+12:00" 30 | DateTime.new(1911, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "M44.01.02T03:04:05+12:00" 31 | DateTime.new(1873, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "M06.01.02T03:04:05+12:00" 32 | DateTime.new(1872, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "1872-01-02T03:04:05+12:00" 33 | DateTime.new(1867, 1, 2, 3, 4, 5, 0.5).jisx0301.should == "1867-01-02T03:04:05+12:00" 34 | end 35 | 36 | it "#rfc2822 should use an RFC2822 format" do 37 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).rfc2822.should == "Fri, 2 Jan 2009 03:04:05 +1200" 38 | end 39 | 40 | it "#rfc822 should use an RFC822 format" do 41 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).rfc822.should == "Fri, 2 Jan 2009 03:04:05 +1200" 42 | end 43 | 44 | it "#rfc3339 should use an RFC3339 format" do 45 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).rfc3339.should == "2009-01-02T03:04:05+12:00" 46 | end 47 | 48 | it "#xmlschema should use an ISO8601 format" do 49 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).xmlschema.should == "2009-01-02T03:04:05+12:00" 50 | end 51 | 52 | it "should handle fractional seconds if given an argument for iso8601, jisx0301, rfc3339, and xmlschema" do 53 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).iso8601(4).should == "2009-01-02T03:04:05.0000+12:00" 54 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).jisx0301(4).should == "H21.01.02T03:04:05.0000+12:00" 55 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).rfc3339(4).should == "2009-01-02T03:04:05.0000+12:00" 56 | DateTime.new(2009, 1, 2, 3, 4, 5, 0.5).xmlschema(4).should == "2009-01-02T03:04:05.0000+12:00" 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /spec/datetime/hash_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#hash" do 4 | it "should use the same hash value for equal datetimes" do 5 | DateTime.civil(2004, 7, 12, 13, 14, 15).hash.should == DateTime.civil(2004, 7, 12, 13, 14, 15).hash 6 | end 7 | 8 | it "should use a different hash value for different dates" do 9 | DateTime.civil(2004, 7, 12, 13, 14, 15).hash.should_not == DateTime.civil(2004, 7, 12, 13, 14, 16).hash 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/datetime/leap_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#leap?" do 4 | it "should be true if the current date is a leap year and no argument is given" do 5 | DateTime.civil(2000, 10, 11).leap?.should == true 6 | DateTime.civil(2004, 10, 11).leap?.should == true 7 | DateTime.civil(2008, 10, 11).leap?.should == true 8 | DateTime.civil(1996, 10, 11).leap?.should == true 9 | DateTime.civil(1600, 10, 11).leap?.should == true 10 | end 11 | 12 | it "should be false if the current date is not a leap year and no argument is given" do 13 | DateTime.civil(1700, 10, 11).leap?.should == false 14 | DateTime.civil(1800, 10, 11).leap?.should == false 15 | DateTime.civil(1900, 10, 11).leap?.should == false 16 | DateTime.civil(1999, 10, 11).leap?.should == false 17 | DateTime.civil(2001, 10, 11).leap?.should == false 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/datetime/limits_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime limits: " do 4 | before do 5 | @d1 = DateTime.jd(DateTime::JULIAN - 1) 6 | @d2 = DateTime.jd(DateTime::GREGORIAN + 1) 7 | end 8 | 9 | it "#+ and #- should raise RangeError for dates that are too large or small" do 10 | proc{DateTime.jd(@d1.jd) + 1}.should raise_error(RangeError) 11 | proc{DateTime.jd(@d2.jd) - 1}.should raise_error(RangeError) 12 | end 13 | 14 | it "#<< and #>> should raise RangeError for dates that are too large or small" do 15 | proc{DateTime.jd(@d1.jd) >> 1}.should raise_error(RangeError) 16 | proc{DateTime.jd(@d2.jd) << 1}.should raise_error(RangeError) 17 | end 18 | 19 | ruby_version_is "1.9" do 20 | it "#next_year and #prev_year should raise RangeError for dates that are too large or small" do 21 | proc{DateTime.jd(@d1.jd).next_year}.should raise_error(RangeError) 22 | proc{DateTime.jd(@d2.jd).prev_year}.should raise_error(RangeError) 23 | end 24 | end 25 | 26 | it ".jd should raise RangeError for dates that are too large or small" do 27 | proc{DateTime.jd(@d1.jd + 1)}.should raise_error(RangeError) 28 | proc{DateTime.jd(@d2.jd - 1)}.should raise_error(RangeError) 29 | end 30 | 31 | it ".jd should not raise for dates that are not too large or small" do 32 | proc{DateTime.jd(@d1.jd)}.should_not raise_error 33 | proc{DateTime.jd(@d2.jd)}.should_not raise_error 34 | end 35 | 36 | it ".new! should raise RangeError for dates that are too large or small" do 37 | proc{DateTime.new!(@d1.jd + 1)}.should raise_error(RangeError) 38 | # Need to use 1.5 instead of 1 because new! adds a half day 39 | proc{DateTime.new!(@d2.jd - 1.5)}.should raise_error(RangeError) 40 | end 41 | 42 | it ".new! should not raise for dates that are not too large or small" do 43 | proc{DateTime.new!(@d1.jd)}.should_not raise_error 44 | proc{DateTime.new!(@d2.jd)}.should_not raise_error 45 | end 46 | 47 | it ".civil should raise RangeError for dates that are too large or small" do 48 | proc{DateTime.civil(@d1.year, @d1.month, @d1.day + 1)}.should raise_error(RangeError) 49 | proc{DateTime.civil(@d2.year, @d2.month, @d2.day - 1)}.should raise_error(RangeError) 50 | end 51 | 52 | it ".civil should not raise for dates that are not too large or small" do 53 | proc{DateTime.civil(@d1.year, @d1.month, @d1.day)}.should_not raise_error 54 | proc{DateTime.civil(@d2.year, @d2.month, @d2.day)}.should_not raise_error 55 | end 56 | 57 | it ".civil should correctly convert dates within limits to JD" do 58 | DateTime.civil(@d1.year, @d1.month, @d1.day).jd.should == @d1.jd 59 | DateTime.civil(@d2.year, @d2.month, @d2.day).jd.should == @d2.jd 60 | end 61 | 62 | it ".commercial should raise RangeError for dates that are too large or small" do 63 | proc{DateTime.commercial(@d1.cwyear, @d1.cwday == 6 ? @d1.cweek + 1 : @d1.cweek, @d1.cwday == 6 ? 1 : @d1.cwday + 1)}.should raise_error(RangeError) 64 | proc{DateTime.commercial(@d2.cwyear, @d2.cwday == 1 ? @d2.cweek - 1 : @d2.cweek, @d2.cwday == 1 ? 7 : @d2.cwday - 1)}.should raise_error(RangeError) 65 | end 66 | 67 | it ".commercial should not raise for dates that are not too large or small" do 68 | proc{DateTime.commercial(@d1.cwyear, @d1.cweek, @d1.cwday)}.should_not raise_error 69 | proc{DateTime.commercial(@d2.cwyear, @d2.cweek, @d2.cwday)}.should_not raise_error 70 | end 71 | 72 | it ".commercial should correctly convert dates within limits to JD" do 73 | DateTime.commercial(@d1.cwyear, @d1.cweek, @d1.cwday).jd.should == @d1.jd 74 | DateTime.commercial(@d2.cwyear, @d2.cweek, @d2.cwday).jd.should == @d2.jd 75 | end 76 | 77 | it ".ordinal should raise RangeError for dates that are too large or small" do 78 | proc{DateTime.ordinal(@d1.year, @d1.yday + 1)}.should raise_error(RangeError) 79 | proc{DateTime.ordinal(@d2.year, @d2.yday - 1)}.should raise_error(RangeError) 80 | end 81 | 82 | it ".ordinal should not raise for dates that are not too large or small" do 83 | proc{DateTime.ordinal(@d1.year, @d1.yday)}.should_not raise_error 84 | proc{DateTime.ordinal(@d2.year, @d2.yday)}.should_not raise_error 85 | end 86 | 87 | it ".ordinal should correctly convert dates within limits to JD" do 88 | DateTime.ordinal(@d1.year, @d1.yday).jd.should == @d1.jd 89 | DateTime.ordinal(@d2.year, @d2.yday).jd.should == @d2.jd 90 | end 91 | 92 | it ".parse should raise RangeError for civil dates that are too large or small" do 93 | proc{DateTime.parse("#{@d1.year}-#{@d1.month}-#{@d1.day+1}")}.should raise_error(RangeError) 94 | proc{DateTime.parse("#{@d2.year}-#{@d2.month}-#{@d2.day-1}")}.should raise_error(RangeError) 95 | end 96 | 97 | it ".parse should not raise for civil dates that are not too large or small" do 98 | proc{DateTime.parse("#{@d1.year}-#{@d1.month}-#{@d1.day}")}.should_not raise_error 99 | proc{DateTime.parse("#{@d2.year}-#{@d2.month}-#{@d2.day}")}.should_not raise_error 100 | end 101 | 102 | it ".parse should correctly convert civil dates within limits to JD" do 103 | DateTime.parse("#{@d1.year}-#{@d1.month}-#{@d1.day}").jd.should == @d1.jd 104 | DateTime.parse("#{@d2.year}-#{@d2.month}-#{@d2.day}").jd.should == @d2.jd 105 | end 106 | 107 | it ".strptime should raise RangeError for civil dates that are too large or small" do 108 | proc{DateTime.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day+1}", "%Y-%m-%d")}.should raise_error(RangeError) 109 | proc{DateTime.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day-1}", "%Y-%m-%d")}.should raise_error(RangeError) 110 | end 111 | 112 | it ".strptime should not raise for civil dates that are not too large or small" do 113 | proc{DateTime.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day}", "%Y-%m-%d")}.should_not raise_error 114 | proc{DateTime.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day}", "%Y-%m-%d")}.should_not raise_error 115 | end 116 | 117 | it ".strptime should correctly convert civil dates within limits to JD" do 118 | DateTime.strptime("#{@d1.year}-#{@d1.month}-#{@d1.day}", "%Y-%m-%d").jd.should == @d1.jd 119 | DateTime.strptime("#{@d2.year}-#{@d2.month}-#{@d2.day}", "%Y-%m-%d").jd.should == @d2.jd 120 | end 121 | 122 | end 123 | 124 | describe "DateTime offset limits: " do 125 | it "methods should raise ArgumentError for offets that are too large or small" do 126 | max = (14 + 1.0/60)/24 127 | min = -(14 + 1.0/60)/24 128 | proc{DateTime.civil(2009, 1, 1, 0, 0, 0, max)}.should raise_error(ArgumentError) 129 | proc{DateTime.civil(2009, 1, 1, 0, 0, 0, min)}.should raise_error(ArgumentError) 130 | proc{DateTime.commercial(2009, 1, 1, 0, 0, 0, max)}.should raise_error(ArgumentError) 131 | proc{DateTime.commercial(2009, 1, 1, 0, 0, 0, min)}.should raise_error(ArgumentError) 132 | proc{DateTime.ordinal(2009, 1, 0, 0, 0, max)}.should raise_error(ArgumentError) 133 | proc{DateTime.ordinal(2009, 1, 0, 0, 0, min)}.should raise_error(ArgumentError) 134 | proc{DateTime.jd(2009, 0, 0, 0, max)}.should raise_error(ArgumentError) 135 | proc{DateTime.jd(2009, 0, 0, 0, min)}.should raise_error(ArgumentError) 136 | proc{DateTime.new!(2009, max)}.should raise_error(ArgumentError) 137 | proc{DateTime.new!(2009, min)}.should raise_error(ArgumentError) 138 | proc{DateTime.parse("00:00:00+14:01", "%H:%M:%S%z")}.should raise_error(ArgumentError) 139 | proc{DateTime.parse("00:00:00-14:01", "%H:%M:%S%z")}.should raise_error(ArgumentError) 140 | proc{DateTime.strptime("00:00:00+14:01", "%H:%M:%S%z")}.should raise_error(ArgumentError) 141 | proc{DateTime.strptime("00:00:00-14:01", "%H:%M:%S%z")}.should raise_error(ArgumentError) 142 | 143 | d = DateTime.jd(2009) 144 | proc{d.new_offset(max)}.should raise_error(ArgumentError) 145 | proc{d.new_offset(min)}.should raise_error(ArgumentError) 146 | end 147 | 148 | it "methods should not raise for offsets that are not too large or small" do 149 | max = 14.0/24 150 | min = -14.0/24 151 | proc{DateTime.civil(2009, 1, 1, 0, 0, 0, max)}.should_not raise_error 152 | proc{DateTime.civil(2009, 1, 1, 0, 0, 0, min)}.should_not raise_error 153 | proc{DateTime.commercial(2009, 1, 1, 0, 0, 0, max)}.should_not raise_error 154 | proc{DateTime.commercial(2009, 1, 1, 0, 0, 0, min)}.should_not raise_error 155 | proc{DateTime.ordinal(2009, 1, 0, 0, 0, max)}.should_not raise_error 156 | proc{DateTime.ordinal(2009, 1, 0, 0, 0, min)}.should_not raise_error 157 | proc{DateTime.jd(2009, 0, 0, 0, max)}.should_not raise_error 158 | proc{DateTime.jd(2009, 0, 0, 0, min)}.should_not raise_error 159 | proc{DateTime.new!(2009, max)}.should_not raise_error 160 | proc{DateTime.new!(2009, min)}.should_not raise_error 161 | proc{DateTime.parse("00:00:00+14:00", "%H:%M:%S%z")}.should_not raise_error 162 | proc{DateTime.parse("00:00:00-14:00", "%H:%M:%S%z")}.should_not raise_error 163 | proc{DateTime.strptime("00:00:00+14:00", "%H:%M:%S%z")}.should_not raise_error 164 | proc{DateTime.strptime("00:00:00-14:00", "%H:%M:%S%z")}.should_not raise_error 165 | 166 | d = DateTime.jd(2009) 167 | proc{d.new_offset(max)}.should_not raise_error 168 | proc{d.new_offset(min)}.should_not raise_error 169 | end 170 | end 171 | -------------------------------------------------------------------------------- /spec/datetime/minus_month_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#<<" do 4 | it "should substract a number of months from a date" do 5 | (DateTime.civil(2007, 12, 27) << 10).should == DateTime.civil(2007,2,27) 6 | (DateTime.commercial(2007, 45, 5) << 10).should == DateTime.commercial(2007,2,2) 7 | (DateTime.jd(2455086) << 10).should == DateTime.jd(2454782) 8 | (DateTime.ordinal(2008, 315) << 10).should == DateTime.ordinal(2008, 10) 9 | (DateTime.civil(2007, 12, 27) << 12).should == DateTime.civil(2006,12,27) 10 | (DateTime.civil(2007, 12, 27) << -12).should == DateTime.civil(2008,12,27) 11 | end 12 | 13 | it "should result in the last day of a month if the day doesn't exist" do 14 | d = DateTime.civil(2008,3,31) << 1 15 | d.should == DateTime.civil(2008, 2, 29) 16 | end 17 | 18 | it "should keep the same class as the receiver" do 19 | c = Class.new(DateTime) 20 | c.jd.<<(10).should be_kind_of(c) 21 | end 22 | 23 | it "should raise an error on non numeric parameters" do 24 | lambda { DateTime.civil(2007,2,27) << "hello" }.should raise_error(TypeError) 25 | lambda { DateTime.civil(2007,2,27) << DateTime.new }.should raise_error(TypeError) 26 | lambda { DateTime.civil(2007,2,27) << Object.new }.should raise_error(TypeError) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/datetime/minus_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#-" do 4 | 5 | it "should substract a number of days from a DateTime" do 6 | (DateTime.civil(2008, 1, 8) - 315).should == DateTime.civil(2007,2,27) 7 | (DateTime.commercial(2007, 47, 2) - 315).should == DateTime.commercial(2007,2,2) 8 | (DateTime.jd(2455097) - 315).should == DateTime.jd(2454782) 9 | (DateTime.ordinal(2008, 325) - 315).should == DateTime.ordinal(2008, 10) 10 | end 11 | 12 | it "should subtract a fractional number of days to a Date" do 13 | (DateTime.civil(2008, 1, 8, 12) - 315.5).should == DateTime.civil(2007,2,27) 14 | (DateTime.commercial(2007, 47, 2, 18) - 315.75).should == DateTime.commercial(2007,2,2) 15 | (DateTime.jd(2455097, 6) - 315.25).should == DateTime.jd(2454782) 16 | (DateTime.ordinal(2008, 325, 6) - 315.25).should == DateTime.ordinal(2008, 10) 17 | end 18 | 19 | it "should keep the same class as the receiver" do 20 | c = Class.new(DateTime) 21 | c.jd.-(10).should be_kind_of(c) 22 | end 23 | 24 | it "should substract a negative number of days from a DateTime" do 25 | d = DateTime.civil(2007, 4, 19).-(-13) 26 | d.should == DateTime.civil(2007, 5 ,2) 27 | end 28 | 29 | it "should subtract a fractional negative number of days to a Date" do 30 | d = DateTime.civil(2007, 2, 16, 12).-(-10.5) 31 | d.should == DateTime.civil(2007,2,27) 32 | end 33 | 34 | it "should be able to compute the different between two DateTimes" do 35 | (DateTime.civil(2007,2,27) - DateTime.civil(2007,2,27)).should be_close(0.0, 0.00000001) 36 | (DateTime.civil(2007,2,27) - DateTime.civil(2007,2,26)).should be_close(1.0, 0.00000001) 37 | (DateTime.civil(2006,2,27) - DateTime.civil(2007,2,27)).should be_close(-365.0, 0.00000001) 38 | (DateTime.civil(2008,2,27) - DateTime.civil(2007,2,27)).should be_close(365.0, 0.00000001) 39 | (DateTime.civil(2009,2,27) - DateTime.civil(2008,2,27)).should be_close(366.0, 0.00000001) 40 | 41 | (DateTime.civil(2009,2,27) - DateTime.commercial(2008,2,1)).should be_close(417.0, 0.00000001) 42 | (DateTime.civil(2009,2,27) - DateTime.jd(2454782)).should be_close(108.0, 0.00000001) 43 | (DateTime.civil(2009,2,27) - DateTime.ordinal(2008, 10)).should be_close(414.0, 0.00000001) 44 | 45 | (DateTime.commercial(2008,2,1) - DateTime.civil(2008,2,27)).should be_close(-51.0, 0.00000001) 46 | (DateTime.commercial(2008,2,1) - DateTime.jd(2454782)).should be_close(-309.0, 0.00000001) 47 | (DateTime.commercial(2008,2,1) - DateTime.ordinal(2008, 10)).should be_close(-3.0, 0.00000001) 48 | 49 | (DateTime.jd(2454782) - DateTime.commercial(2008,2,1)).should be_close(309.0, 0.00000001) 50 | (DateTime.jd(2454782) - DateTime.civil(2009,2,27)).should be_close(-108.0, 0.00000001) 51 | (DateTime.jd(2454782) - DateTime.ordinal(2008, 10)).should be_close(306.0, 0.00000001) 52 | 53 | (DateTime.ordinal(2008, 10) - DateTime.commercial(2008,2,1)).should be_close(3.0, 0.00000001) 54 | (DateTime.ordinal(2008, 10) - DateTime.jd(2454782)).should be_close(-306.0, 0.00000001) 55 | (DateTime.ordinal(2008, 10) - DateTime.civil(2009,2,27)).should be_close(-414.0, 0.00000001) 56 | end 57 | 58 | it "should consider the offset when computing the different between two DateTimes" do 59 | (DateTime.civil(2007,2,27, 0, 0, 0, 0.5) - DateTime.civil(2007,2,27,0,0,0)).should be_close(-0.5, 0.00000001) 60 | (DateTime.civil(2007,2,27, 0, 0, 0, -0.5) - DateTime.civil(2007,2,27,12,0,0)).should be_close(0.0, 0.00000001) 61 | (DateTime.civil(2007,2,27,0,0,0,-0.5) - DateTime.civil(2007,2,27,0,0,0,0.5)).should be_close(1.0, 0.00000001) 62 | end 63 | 64 | it "should be able to subtract a Date from a DateTime" do 65 | (DateTime.ordinal(2008, 10) - Date.commercial(2008,2,1)).should be_close(3.0, 0.00000001) 66 | (DateTime.ordinal(2008, 10) - Date.jd(2454782)).should be_close(-306.0, 0.00000001) 67 | (DateTime.ordinal(2008, 10) - Date.civil(2009,2,27)).should be_close(-414.0, 0.00000001) 68 | end 69 | 70 | it "should assume a Date is in the same offset as the receiver" do 71 | (DateTime.ordinal(2008, 10, 0, 0, 0, 0.5) - Date.commercial(2008,2,1)).should be_close(3.0, 0.00000001) 72 | (DateTime.ordinal(2008, 10, 0, 0, 0, 0.1) - Date.jd(2454782)).should be_close(-306.0, 0.00000001) 73 | (DateTime.ordinal(2008, 10, 0, 0, 0, -0.5) - Date.civil(2009,2,27)).should be_close(-414.0, 0.00000001) 74 | end 75 | 76 | it "should raise an error on non numeric parameters" do 77 | lambda { DateTime.civil(2007,2,27) - :hello }.should raise_error(TypeError) 78 | lambda { DateTime.civil(2007,2,27) - "hello" }.should raise_error(TypeError) 79 | lambda { DateTime.civil(2007,2,27) - Object.new }.should raise_error(TypeError) 80 | end 81 | 82 | end 83 | -------------------------------------------------------------------------------- /spec/datetime/next_prev_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "DateTime#next_day" do 5 | it "should add a single day to a DateTime if no arguments" do 6 | (DateTime.civil(2007,2,27).next_day).should == DateTime.civil(2007, 2, 28) 7 | end 8 | 9 | it "should add the given number of days to a DateTime if an argument" do 10 | (DateTime.civil(2007,2,27).next_day(2)).should == DateTime.civil(2007, 3, 1) 11 | end 12 | 13 | it "should handle a negative argument by subtracting days" do 14 | (DateTime.civil(2007,2,27).next_day(-2)).should == DateTime.civil(2007, 2, 25) 15 | end 16 | 17 | it "should keep the same fractional part and offset" do 18 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_day).day_fraction.should == 0.5 19 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_day).offset.should == 0.5 20 | end 21 | 22 | it "should keep the same class as the receiver" do 23 | c = Class.new(DateTime) 24 | c.jd.next_day.should be_kind_of(c) 25 | end 26 | end 27 | 28 | describe "DateTime#prev_day" do 29 | it "should subtract a single day to a DateTime if no arguments" do 30 | (DateTime.civil(2007,2,27).prev_day).should == DateTime.civil(2007, 2, 26) 31 | end 32 | 33 | it "should subtract the given number of days to a DateTime if an argument" do 34 | (DateTime.civil(2007,2,27).prev_day(2)).should == DateTime.civil(2007, 2, 25) 35 | end 36 | 37 | it "should handle a negative argument by adding days" do 38 | (DateTime.civil(2007,2,27).prev_day(-2)).should == DateTime.civil(2007, 3, 1) 39 | end 40 | 41 | it "should keep the same fractional part and offset" do 42 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_day).day_fraction.should == 0.5 43 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_day).offset.should == 0.5 44 | end 45 | 46 | it "should keep the same class as the receiver" do 47 | c = Class.new(DateTime) 48 | c.jd.prev_day.should be_kind_of(c) 49 | end 50 | end 51 | 52 | describe "DateTime#next_month" do 53 | it "should add a single month to a DateTime if no arguments" do 54 | (DateTime.civil(2007,2,27).next_month).should == DateTime.civil(2007, 3, 27) 55 | end 56 | 57 | it "should add the given number of months to a DateTime if an argument" do 58 | (DateTime.civil(2007,2,27).next_month(2)).should == DateTime.civil(2007, 4, 27) 59 | end 60 | 61 | it "should handle a negative argument by subtracting months" do 62 | (DateTime.civil(2007,2,27).next_month(-2)).should == DateTime.civil(2006, 12, 27) 63 | end 64 | 65 | it "should handle adding a month where the new date is not a valid date" do 66 | (DateTime.civil(2007,1,31).next_month).should == DateTime.civil(2007, 2, 28) 67 | (DateTime.civil(2008,1,31).next_month).should == DateTime.civil(2008, 2, 29) 68 | (DateTime.civil(2007,1,31).next_month(3)).should == DateTime.civil(2007, 4, 30) 69 | end 70 | 71 | it "should keep the same fractional part and offset" do 72 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_month).day_fraction.should == 0.5 73 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_month).offset.should == 0.5 74 | end 75 | 76 | it "should keep the same class as the receiver" do 77 | c = Class.new(DateTime) 78 | c.jd.next_month.should be_kind_of(c) 79 | end 80 | end 81 | 82 | describe "DateTime#prev_month" do 83 | it "should subtract a single month to a DateTime if no arguments" do 84 | (DateTime.civil(2007,2,27).prev_month).should == DateTime.civil(2007, 1, 27) 85 | end 86 | 87 | it "should subtract the given number of months to a DateTime if an argument" do 88 | (DateTime.civil(2007,2,27).prev_month(2)).should == DateTime.civil(2006, 12, 27) 89 | end 90 | 91 | it "should handle a negative argument by adding months" do 92 | (DateTime.civil(2007,2,27).prev_month(-2)).should == DateTime.civil(2007, 4, 27) 93 | end 94 | 95 | it "should handle subtracting a month where the new date is not a valid date" do 96 | (DateTime.civil(2007,3,31).prev_month).should == DateTime.civil(2007, 2, 28) 97 | (DateTime.civil(2008,3,31).prev_month).should == DateTime.civil(2008, 2, 29) 98 | (DateTime.civil(2007,3,31).prev_month(4)).should == DateTime.civil(2006, 11, 30) 99 | end 100 | 101 | it "should keep the same fractional part and offset" do 102 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_month).day_fraction.should == 0.5 103 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_month).offset.should == 0.5 104 | end 105 | 106 | it "should keep the same class as the receiver" do 107 | c = Class.new(DateTime) 108 | c.jd.prev_month.should be_kind_of(c) 109 | end 110 | end 111 | 112 | describe "DateTime#next_year" do 113 | it "should add a single year to a DateTime if no arguments" do 114 | (DateTime.civil(2007,2,27).next_year).should == DateTime.civil(2008, 2, 27) 115 | end 116 | 117 | it "should add the given number of years to a DateTime if an argument" do 118 | (DateTime.civil(2007,2,27).next_year(2)).should == DateTime.civil(2009, 2, 27) 119 | end 120 | 121 | it "should handle a negative argument by subtracting years" do 122 | (DateTime.civil(2007,2,27).next_year(-2)).should == DateTime.civil(2005, 2, 27) 123 | end 124 | 125 | it "should handle adding a year where the new date is not a valid date" do 126 | (DateTime.civil(2008,2,29).next_year).should == DateTime.civil(2009, 2, 28) 127 | end 128 | 129 | it "should keep the same fractional part and offset" do 130 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_year).day_fraction.should == 0.5 131 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).next_year).offset.should == 0.5 132 | end 133 | 134 | it "should keep the same class as the receiver" do 135 | c = Class.new(DateTime) 136 | c.jd.next_year.should be_kind_of(c) 137 | end 138 | end 139 | 140 | describe "DateTime#prev_year" do 141 | it "should add a single year to a DateTime if no arguments" do 142 | (DateTime.civil(2007,2,27).prev_year).should == DateTime.civil(2006, 2, 27) 143 | end 144 | 145 | it "should add the given number of years to a DateTime if an argument" do 146 | (DateTime.civil(2007,2,27).prev_year(2)).should == DateTime.civil(2005, 2, 27) 147 | end 148 | 149 | it "should handle a negative argument by subtracting years" do 150 | (DateTime.civil(2007,2,27).prev_year(-2)).should == DateTime.civil(2009, 2, 27) 151 | end 152 | 153 | it "should handle adding a year where the new date is not a valid date" do 154 | (DateTime.civil(2008,2,29).prev_year).should == DateTime.civil(2007, 2, 28) 155 | end 156 | 157 | it "should keep the same fractional part and offset" do 158 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_year).day_fraction.should == 0.5 159 | (DateTime.civil(2007,2,27, 12, 0, 0, 0.5).prev_year).offset.should == 0.5 160 | end 161 | 162 | it "should keep the same class as the receiver" do 163 | c = Class.new(DateTime) 164 | c.jd.prev_year.should be_kind_of(c) 165 | end 166 | end 167 | 168 | end 169 | -------------------------------------------------------------------------------- /spec/datetime/now_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime.now" do 4 | it "should be right now as a DateTime" do 5 | t = Time.now 6 | d = DateTime.now 7 | d.year.should == t.year 8 | d.mon.should == t.mon 9 | d.day.should == t.day 10 | d.hour.should == t.hour 11 | d.min.should == t.min 12 | d.sec.should == t.sec 13 | end 14 | 15 | it "should accept an optional sg value" do 16 | DateTime.now(1).to_s.should == DateTime.now.to_s 17 | end 18 | 19 | it "should keep the same class as the receiver" do 20 | c = Class.new(DateTime) 21 | c.now.should be_kind_of(c) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/datetime/parsing_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | ruby_version_is "1.9" do 4 | describe "DateTime parsing methods" do 5 | it "._httpdate should parse an HTTP format" do 6 | DateTime._httpdate("Fri, 02 Jan 2009 03:04:05 GMT").should == 7 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>3, :min=>4, :sec=>5, :offset=>0, :zone=>'GMT'} 8 | end 9 | 10 | it "._iso8601 should parse an ISO8601 format" do 11 | DateTime._iso8601("2009-01-02T03:04:05+12:00").should == {:year=>2009, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 12 | DateTime._iso8601("03:04:05+12:00").should == {:hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 13 | DateTime._iso8601(" 030405.1+1200").should == {:hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+1200', :sec_fraction=>0.1} 14 | end 15 | 16 | it "._jisx03010 should parse an JIS X 0301 format" do 17 | DateTime._jisx0301("H21.01.02T03:04:05+12:00").should == {:year=>2009, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 18 | DateTime._jisx0301("S63.01.02T03:04:05+12:00").should == {:year=>1988, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 19 | DateTime._jisx0301("T14.01.02T03:04:05+12:00").should == {:year=>1925, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 20 | DateTime._jisx0301("M44.01.02T03:04:05+12:00").should == {:year=>1911, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 21 | DateTime._jisx0301("M06.01.02T03:04:05+12:00").should == {:year=>1873, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 22 | DateTime._jisx0301("1872-01-02T03:04:05+12:00").should == {:year=>1872, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 23 | DateTime._jisx0301("1867-01-02T03:04:05+12:00").should == {:year=>1867, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 24 | end 25 | 26 | it "._rfc2822 should parse an RFC2822 format" do 27 | DateTime._rfc2822("Fri, 2 Jan 2009 03:04:05 +1200").should == 28 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+1200'} 29 | end 30 | 31 | it "._rfc822 should parse an RFC822 format" do 32 | DateTime._rfc822("Fri, 2 Jan 2009 03:04:05 +1200").should == 33 | {:year=>2009, :mon=>1, :mday=>2, :wday=>5, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+1200'} 34 | end 35 | 36 | it "._rfc3339 should parse an RFC3339 format" do 37 | DateTime._rfc3339("2009-01-02T03:04:05+12:00").should == 38 | {:year=>2009, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 39 | end 40 | 41 | it "._xmlschema should parse an ISO8601 format" do 42 | DateTime._xmlschema("2009-01-02T03:04:05+12:00").should == {:year=>2009, :mon=>1, :mday=>2, :hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 43 | DateTime._xmlschema("03:04:05+12:00").should == {:hour=>3, :min=>4, :sec=>5, :offset=>43200, :zone=>'+12:00'} 44 | DateTime._xmlschema("---01+12:00").should == {:mday=>1, :offset=>43200, :zone=>'+12:00'} 45 | end 46 | 47 | it ".httpdate should parse an HTTP format" do 48 | DateTime.httpdate("Fri, 02 Jan 2009 03:04:05 GMT").should == DateTime.new(2009, 1, 2, 3, 4, 5) 49 | end 50 | 51 | it ".iso8601 should parse an ISO8601 format" do 52 | DateTime.iso8601("2009-01-02T03:04:05+12:00").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 53 | end 54 | 55 | it ".jisx03010 should parse an JIS X 0301 format" do 56 | DateTime.jisx0301("H21.01.02T03:04:05+12:00").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 57 | DateTime.jisx0301("S63.01.02T03:04:05+12:00").should == DateTime.new(1988, 1, 2, 3, 4, 5, 0.5) 58 | DateTime.jisx0301("T14.01.02T03:04:05+12:00").should == DateTime.new(1925, 1, 2, 3, 4, 5, 0.5) 59 | DateTime.jisx0301("M44.01.02T03:04:05+12:00").should == DateTime.new(1911, 1, 2, 3, 4, 5, 0.5) 60 | DateTime.jisx0301("M06.01.02T03:04:05+12:00").should == DateTime.new(1873, 1, 2, 3, 4, 5, 0.5) 61 | DateTime.jisx0301("1872-01-02T03:04:05+12:00").should == DateTime.new(1872, 1, 2, 3, 4, 5, 0.5) 62 | DateTime.jisx0301("1867-01-02T03:04:05+12:00").should == DateTime.new(1867, 1, 2, 3, 4, 5, 0.5) 63 | end 64 | 65 | it ".rfc2822 should parse an RFC2822 format" do 66 | DateTime.rfc2822("Fri, 2 Jan 2009 03:04:05 +1200").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 67 | end 68 | 69 | it ".rfc822 should parse an RFC822 format" do 70 | DateTime.rfc822("Fri, 2 Jan 2009 03:04:05 +1200").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 71 | end 72 | 73 | it ".rfc3339 should parse an RFC3339 format" do 74 | DateTime.rfc3339("2009-01-02T03:04:05+12:00").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 75 | end 76 | 77 | it ".xmlschema should parse an ISO8601 format" do 78 | DateTime.xmlschema("2009-01-02T03:04:05+12:00").should == DateTime.new(2009, 1, 2, 3, 4, 5, 0.5) 79 | end 80 | 81 | it "should keep the same class as the receiver" do 82 | c = Class.new(DateTime) 83 | c.httpdate("Fri, 02 Jan 2009 00:00:00 GMT").should be_kind_of(c) 84 | c.iso8601("2009-01-02").should be_kind_of(c) 85 | c.jisx0301("H21.01.02").should be_kind_of(c) 86 | c.rfc2822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c) 87 | c.rfc822("Fri, 2 Jan 2009 00:00:00 +0000").should be_kind_of(c) 88 | c.rfc3339("2009-01-02T00:00:00+00:00").should be_kind_of(c) 89 | c.xmlschema("2009-01-02").should be_kind_of(c) 90 | end 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /spec/datetime/relationship_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#===" do 4 | 5 | it "should be true for the two same dates" do 6 | (DateTime.civil(2000, 04, 06) === DateTime.civil(2000, 04, 06)).should == true 7 | end 8 | 9 | it "should be true if comparison is a Date on the same date" do 10 | (DateTime.civil(2000, 04, 06, 10) === Date.civil(2000, 04, 06)).should == true 11 | end 12 | 13 | it "should be true if comparison is a Numeric with the same integer value as JD" do 14 | (DateTime.civil(2000, 04, 06) === DateTime.civil(2000, 04, 06).jd).should == true 15 | end 16 | 17 | it "should be false for different dates" do 18 | (DateTime.civil(2000, 04, 05) === DateTime.civil(2000, 04, 06)).should == false 19 | end 20 | 21 | it "should be false if comparison is a Date with a different date" do 22 | (DateTime.civil(2000, 04, 06, 10) === Date.civil(2000, 04, 07)).should == false 23 | end 24 | 25 | it "should be false if comparison is a Numeric with the different integer value as JD" do 26 | (DateTime.civil(2000, 04, 06) === DateTime.civil(2000, 04, 07).jd).should == false 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/datetime/step_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#step" do 4 | 5 | ruby_version_is "" ... "1.9" do 6 | it "should require a block" do 7 | proc{DateTime.now.step(DateTime.now)}.should raise_error(LocalJumpError) 8 | end 9 | end 10 | 11 | ruby_version_is "1.9" do 12 | it "should return an enumerator without a block" do 13 | ds = DateTime.civil(2008, 10, 11) 14 | de = DateTime.civil(2008, 9, 29) 15 | e = de.step(ds) 16 | e.should be_kind_of(Enumerator) 17 | count = 0 18 | e.each do |d| 19 | d.should <= ds 20 | d.should >= de 21 | count += 1 22 | end.should == de 23 | count.should == 13 24 | end 25 | end 26 | 27 | it "should be able to step forward in time" do 28 | ds = DateTime.civil(2008, 10, 11) 29 | de = DateTime.civil(2008, 9, 29) 30 | count = 0 31 | de.step(ds) do |d| 32 | d.should <= ds 33 | d.should >= de 34 | count += 1 35 | end.should == de 36 | count.should == 13 37 | 38 | count = 0 39 | de.step(ds, 5) do |d| 40 | d.should <= ds 41 | d.should >= de 42 | count += 1 43 | end.should == de 44 | count.should == 3 45 | 46 | count = 0 47 | de.step(ds, 0.25) do |d| 48 | d.should <= ds 49 | d.should >= de 50 | count += 1 51 | end.should == de 52 | count.should == 49 53 | 54 | count = 0 55 | ds.step(de) do |d|; count += 1; end.should == ds 56 | count.should == 0 57 | 58 | end 59 | 60 | it "should be able to step backward in time" do 61 | ds = DateTime.civil(2000, 4, 14) 62 | de = DateTime.civil(2000, 3, 29) 63 | count = 0 64 | ds.step(de, -1) do |d| 65 | d.should <= ds 66 | d.should >= de 67 | count += 1 68 | end.should == ds 69 | count.should == 17 70 | 71 | count = 0 72 | ds.step(de, -5) do |d| 73 | d.should <= ds 74 | d.should >= de 75 | count += 1 76 | end.should == ds 77 | count.should == 4 78 | 79 | count = 0 80 | ds.step(de, -0.25) do |d| 81 | d.should <= ds 82 | d.should >= de 83 | count += 1 84 | end.should == ds 85 | count.should == 65 86 | 87 | count = 0 88 | de.step(ds, -1) do |d|; count += 1; end.should == de 89 | count.should == 0 90 | 91 | end 92 | 93 | it "should yield once if the dates are the same, regardless of step" do 94 | ds = DateTime.civil(2008, 10, 11) 95 | count = 0 96 | ds.step(ds, 1) do |d| 97 | d.should == ds 98 | count += 1 99 | end.should == ds 100 | count.should == 1 101 | 102 | count = 0 103 | ds.step(ds, -1) do |d| 104 | d.should == ds 105 | count += 1 106 | end.should == ds 107 | count.should == 1 108 | end 109 | 110 | it "should not yield if the target date is greater than the receiver, and step is not positive" do 111 | ds = DateTime.civil(2008, 10, 11) 112 | count = 0 113 | ds.step(ds.next, -1) do |d| 114 | count += 1 115 | end.should == ds 116 | count.should == 0 117 | end 118 | 119 | it "should not yield if the target date is less than the receiver, and step is not negative" do 120 | ds = DateTime.civil(2008, 10, 11) 121 | count = 0 122 | ds.next.step(ds, 1) do |d| 123 | count += 1 124 | end.should == ds.next 125 | count.should == 0 126 | end 127 | 128 | it "should correctly handle offsets" do 129 | ds = DateTime.civil(2008, 10, 11) 130 | de = DateTime.civil(2008, 10, 11, 0, 0, 0, 0.5) 131 | 132 | count = 0 133 | ds.step(de, 0.25) do |d| 134 | count += 1 135 | end.should == ds 136 | count.should == 0 137 | 138 | count = 0 139 | ds.step(de, -0.25) do |d| 140 | count += 1 141 | end.should == ds 142 | count.should == 3 143 | 144 | count = 0 145 | de.step(ds, -0.25) do |d| 146 | count += 1 147 | end.should == de 148 | count.should == 0 149 | 150 | count = 0 151 | de.step(ds, 0.25) do |d| 152 | count += 1 153 | end.should == de 154 | count.should == 3 155 | 156 | end 157 | 158 | it "should raise an ArgumentError for a 0 step" do 159 | ds = DateTime.civil(2008, 10, 11) 160 | proc{ds.step(ds, 0){|d|}}.should raise_error(ArgumentError) 161 | proc{ds.step(ds+1, 0){|d|}}.should raise_error(ArgumentError) 162 | proc{ds.step(ds-1, 0){|d|}}.should raise_error(ArgumentError) 163 | end 164 | 165 | it "should keep the same class as the receiver" do 166 | c = Class.new(DateTime) 167 | c.jd.step(c.jd + 2) do |d| 168 | d.should be_kind_of(c) 169 | end.should be_kind_of(c) 170 | end 171 | end 172 | -------------------------------------------------------------------------------- /spec/datetime/strftime_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#strftime" do 4 | 5 | it "should be able to print the date time" do 6 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime.should == "2000-04-06T10:11:12+00:00" 7 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime.should == DateTime.civil(2000, 4, 6, 10, 11, 12).to_s 8 | end 9 | 10 | it "should be able to print the hour in a 24 hour clock with leading zero" do 11 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%H').should == "10" 12 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%H').should == "13" 13 | end 14 | 15 | it "should be able to print the hour in a 12 hour clock with leading zero" do 16 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%I').should == "10" 17 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%I').should == "01" 18 | end 19 | 20 | it "should be able to print the hour in a 24 hour clock with leading space" do 21 | DateTime.civil(2000, 4, 6, 9, 11, 12).strftime('%k').should == " 9" 22 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%k').should == "13" 23 | end 24 | 25 | it "should be able to print the hour in a 12 hour clock with leading space" do 26 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%l').should == "10" 27 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%l').should == " 1" 28 | end 29 | 30 | it "should be able to print the number of milliseconds of the second" do 31 | DateTime.civil(2008, 11, 12, 14, 3, 30, -8/24.0).strftime('%L').should == "000" 32 | (DateTime.civil(2008, 11, 12, 14, 3, 31, 8/24.0) + (0.5/86400)).strftime('%L').should == "500" 33 | end 34 | 35 | it "should be able to print the minute with leading zero" do 36 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%M').should == "11" 37 | DateTime.civil(2000, 4, 6, 10, 14, 12).strftime('%M').should == "14" 38 | end 39 | 40 | it "should be able to print the number of nanoseconds of the second" do 41 | DateTime.civil(2008, 11, 12, 14, 3, 30, -8/24.0).strftime('%N').should == "000000000" 42 | (DateTime.civil(2008, 11, 12, 14, 3, 31, 8/24.0) + (0.5/86400)).strftime('%N').should == "500000000" 43 | end 44 | 45 | it "should be able to print the meridian indicator in lower case" do 46 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%P').should == "am" 47 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%P').should == "pm" 48 | end 49 | 50 | it "should be able to print the meridian indicator in upper case" do 51 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%p').should == "AM" 52 | DateTime.civil(2000, 4, 6, 13, 11, 12).strftime('%p').should == "PM" 53 | end 54 | 55 | it "should be able to print the number of milliseconds since the unix epoch" do 56 | DateTime.civil(2008, 11, 12, 14, 3, 30, -8/24.0).strftime('%Q').should == "1226527410000" 57 | (DateTime.civil(2008, 11, 12, 14, 3, 31, 8/24.0) + (0.5/86400)).strftime('%Q').should == "1226469811500" 58 | end 59 | 60 | it "should be able to print the second with leading zero" do 61 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%S').should == "12" 62 | DateTime.civil(2000, 4, 6, 10, 11, 13).strftime('%S').should == "13" 63 | end 64 | 65 | it "should be able to print the number of seconds since the unix epoch" do 66 | DateTime.civil(2008, 11, 12, 14, 3, 30, -8/24.0).strftime('%s').should == "1226527410" 67 | DateTime.civil(2008, 11, 12, 14, 3, 31, 8/24.0).strftime('%s').should == "1226469811" 68 | end 69 | 70 | it "should be able to print the time zone offset as a string of hours and minutes" do 71 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%z').should == "+0000" 72 | DateTime.civil(2000, 4, 6, 10, 11, 12, -0.5).strftime('%z').should == "-1200" 73 | DateTime.civil(2000, 4, 6, 10, 11, 12, 0.5).strftime('%z').should == "+1200" 74 | DateTime.civil(2000, 4, 6, 10, 11, 12, -1/24.0).strftime('%z').should == "-0100" 75 | DateTime.civil(2000, 4, 6, 10, 11, 12, 1/24.0).strftime('%z').should == "+0100" 76 | 77 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%Z').should == "+00:00" 78 | DateTime.civil(2000, 4, 6, 10, 11, 12, -0.5).strftime('%Z').should == "-12:00" 79 | DateTime.civil(2000, 4, 6, 10, 11, 12, 0.5).strftime('%Z').should == "+12:00" 80 | DateTime.civil(2000, 4, 6, 10, 11, 12, -1/24.0).strftime('%Z').should == "-01:00" 81 | DateTime.civil(2000, 4, 6, 10, 11, 12, 1/24.0).strftime('%Z').should == "+01:00" 82 | end 83 | 84 | ############################ 85 | # Specs that combine stuff # 86 | ############################ 87 | 88 | it "should be able to print the common date" do 89 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%c").should == "Thu Apr 6 10:11:12 2000" 90 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%c").should == DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%a %b %e %H:%M:%S %Y') 91 | end 92 | 93 | it "should be able to print the hour and minute" do 94 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%R").should == "10:11" 95 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%R").should == DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%H:%M') 96 | end 97 | 98 | it "should be able to show the hour, minute, second, and am/pm flag" do 99 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%r").should == "10:11:12 AM" 100 | DateTime.civil(2000, 4, 9, 13, 11, 12).strftime("%r").should == " 1:11:12 PM" 101 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%r").should == DateTime.civil(2000, 4, 9, 10, 11, 12).strftime('%I:%M:%S %p') 102 | end 103 | 104 | it "should be able to show the hour, minute, and second" do 105 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%T").should == "10:11:12" 106 | DateTime.civil(2000, 4, 9, 13, 11, 12).strftime("%T").should == "13:11:12" 107 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%T").should == DateTime.civil(2000, 4, 9, 10, 11, 12).strftime('%H:%M:%S') 108 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%X").should == "10:11:12" 109 | DateTime.civil(2000, 4, 9, 13, 11, 12).strftime("%X").should == "13:11:12" 110 | DateTime.civil(2000, 4, 9, 10, 11, 12).strftime("%X").should == DateTime.civil(2000, 4, 9, 10, 11, 12).strftime('%H:%M:%S') 111 | end 112 | 113 | it "should be able to print the common date and timezone" do 114 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%+").should == "Thu Apr 6 10:11:12 +00:00 2000" 115 | DateTime.civil(2000, 4, 6, 10, 11, 12, 0.5).strftime("%+").should == "Thu Apr 6 10:11:12 +12:00 2000" 116 | DateTime.civil(2000, 4, 6, 10, 11, 12).strftime("%+").should == DateTime.civil(2000, 4, 6, 10, 11, 12).strftime('%a %b %e %H:%M:%S %Z %Y') 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /spec/datetime/strptime_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime.strptime" do 4 | before do 5 | @t = Time.now 6 | end 7 | 8 | it "._strptime should be a hash of values" do 9 | DateTime._strptime('2008-10-11T01:00:02+0000').should == {:offset=>0, :zone=>"+0000", :sec=>2, :year=>2008, :hour=>1, :mday=>11, :min=>0, :mon=>10} 10 | DateTime._strptime('2008-10-11', '%Y-%m-%d').should == {:year=>2008, :mon=>10, :mday=>11} 11 | end 12 | 13 | it "should have defaults and an optional sg value" do 14 | DateTime.strptime('2008-10-11T00:00:00+00:00').should == DateTime.civil(2008, 10, 11) 15 | DateTime.strptime('2008-10-11', '%Y-%m-%d').should == DateTime.civil(2008, 10, 11) 16 | DateTime.strptime('2008-10-11', '%Y-%m-%d', 1).should == DateTime.civil(2008, 10, 11) 17 | DateTime.strptime.should == DateTime.jd 18 | end 19 | 20 | it "should be able to parse the date time" do 21 | DateTime.strptime("2000-04-06T10:11:12+00:00").should == DateTime.civil(2000, 4, 6, 10, 11, 12) 22 | end 23 | 24 | it "should keep the same class as the receiver" do 25 | c = Class.new(DateTime) 26 | c.strptime.should be_kind_of(c) 27 | c.strptime('2008-10-11', '%Y-%m-%d').should be_kind_of(c) 28 | end 29 | 30 | it "should be able to parse the hour in a 24 hour clock with leading zero" do 31 | DateTime.strptime("10", '%H').should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 0, 0) 32 | DateTime.strptime("09", '%H').should == DateTime.civil(@t.year, @t.mon, @t.day, 9, 0, 0) 33 | DateTime.strptime("2000 16", '%Y %H').should == DateTime.civil(2000, 1, 1, 16, 0, 0) 34 | end 35 | 36 | it "should be able to parse the hour in a 12 hour clock with leading zero with meridian indicator" do 37 | DateTime.strptime("10 AM", '%I %p').should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 0, 0) 38 | DateTime.strptime("03 04 04 PM", '%m %d %I %p').should == DateTime.civil(@t.year, 3, 4, 16, 0, 0) 39 | end 40 | 41 | it "should be able to parse the hour in a 24 hour clock with leading space" do 42 | DateTime.strptime("10", '%k').should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 0, 0) 43 | DateTime.strptime(" 9", '%k').should == DateTime.civil(@t.year, @t.mon, @t.day, 9, 0, 0) 44 | DateTime.strptime("10 16", '%d %k').should == DateTime.civil(@t.year, @t.mon, 10, 16, 0, 0) 45 | end 46 | 47 | it "should be able to parse the hour in a 12 hour clock with leading space with meridian indicator" do 48 | DateTime.strptime("10 am", '%l %P').should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 0, 0) 49 | DateTime.strptime(" 4 pm", '%l %P').should == DateTime.civil(@t.year, @t.mon, @t.day, 16, 0, 0) 50 | end 51 | 52 | it "should be able to parse the number of milliseconds of the second" do 53 | DateTime.strptime("10 000", '%M %L').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) 54 | DateTime.strptime("10 500", '%M %L').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) + (0.5/86400) 55 | end 56 | 57 | it "should be able to parse the number of milliseconds of the second with trailing numbers" do 58 | DateTime.strptime("10 0000", '%M %L0').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) 59 | DateTime.strptime("10 50012", '%M %L%m').should == DateTime.civil(@t.year, 12, 1, 0, 10, 0) + (0.5/86400) 60 | end 61 | 62 | it "should be able to parse the minute with leading zero" do 63 | DateTime.strptime("10", '%M').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) 64 | DateTime.strptime("09", '%M').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 9, 0) 65 | end 66 | 67 | it "should be able to parse the number of nanoseconds of the second" do 68 | DateTime.strptime("10 000000000", '%M %N').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) 69 | DateTime.strptime("10 500000000", '%M %N').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) + (0.5/86400) 70 | end 71 | 72 | it "should be able to parse the number of nanoseconds of the second with trailing numbers" do 73 | DateTime.strptime("10 0000000000", '%M %N0').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 10, 0) 74 | DateTime.strptime("10 50000000012", '%M %N%m').should == DateTime.civil(@t.year, 12, 1, 0, 10, 0) + (0.5/86400) 75 | end 76 | 77 | it "should be able to parse the number of seconds since the unix epoch" do 78 | Date.strptime("954979200", "%s").should == Date.civil(2000, 4, 6) 79 | end 80 | 81 | it "should be able to parse the number of milliseconds since the unix epoch" do 82 | DateTime.strptime("1226527410000", '%Q').should == DateTime.civil(2008, 11, 12, 22, 3, 30, 0) 83 | DateTime.strptime("1226527411000", '%Q').should == DateTime.civil(2008, 11, 12, 22, 3, 31, 0) 84 | DateTime.strptime("32511888001500", "%Q").should == DateTime.civil(3000, 4, 6, 0, 0, 1) + (0.5/86400) 85 | end 86 | 87 | it "should be able to parse the second with leading zero" do 88 | DateTime.strptime("10", '%S').should == DateTime.civil(@t.year, @t.mon, @t.day, 0, 0, 10) 89 | DateTime.strptime("10 09", '%H %S').should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 0, 9) 90 | end 91 | 92 | it "should be able to parse the number of seconds since the unix epoch" do 93 | DateTime.strptime("1226527410", '%s').should == DateTime.civil(2008, 11, 12, 22, 3, 30, 0) 94 | DateTime.strptime("1226527411", '%s').should == DateTime.civil(2008, 11, 12, 22, 3, 31, 0) 95 | DateTime.strptime("32511888001", "%s").should == DateTime.civil(3000, 4, 6, 0, 0, 1) 96 | end 97 | 98 | it "should be able to parse the time zone offset as a string of hours and minutes" do 99 | DateTime.strptime("2000 +0000", '%Y %z').offset.should == 0 100 | DateTime.strptime("2000 Z", '%Y %z').offset.should == 0 101 | DateTime.strptime("2000 -1200", '%Y %z').offset.should == -0.5 102 | DateTime.strptime("2000 +1200", '%Y %z').offset.should == 0.5 103 | DateTime.strptime("2000 -01:00", '%Y %z').offset.should == -1/24.0 104 | DateTime.strptime("2000 +01:00", '%Y %z').offset.should == 1/24.0 105 | end 106 | 107 | ############################ 108 | # Specs that combine stuff # 109 | ############################ 110 | 111 | it "should be able to parse the common date" do 112 | DateTime.strptime("Thu Apr 6 10:11:12 2000", "%c").should == DateTime.civil(2000, 4, 6, 10, 11, 12) 113 | end 114 | 115 | it "should be able to parse the hour and minute" do 116 | DateTime.strptime("10:11", "%R").should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 11, 0) 117 | end 118 | 119 | it "should be able to parse the hour, minute, second, and am/pm flag" do 120 | DateTime.strptime("10:11:12 AM", "%r").should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 11, 12) 121 | DateTime.strptime("01:11:12 PM", "%r").should == DateTime.civil(@t.year, @t.mon, @t.day, 13, 11, 12) 122 | end 123 | 124 | it "should be able to parse the hour, minute, and second" do 125 | DateTime.strptime("10:11:12", "%T").should == DateTime.civil(@t.year, @t.mon, @t.day, 10, 11, 12) 126 | DateTime.strptime("01:11:12", "%X").should == DateTime.civil(@t.year, @t.mon, @t.day, 1, 11, 12) 127 | end 128 | 129 | it "should be able to parse the common date and timezone" do 130 | DateTime.strptime("Thu Apr 6 10:11:12 +0000 2000", "%+").should == DateTime.civil(2000, 4, 6, 10, 11, 12) 131 | DateTime.strptime("Thu Apr 6 10:11:12 +1200 2000", "%+").should == DateTime.civil(2000, 4, 6, 10, 11, 12, 0.5) 132 | end 133 | end 134 | -------------------------------------------------------------------------------- /spec/datetime/succ_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#succ" do 4 | it "should be the next day" do 5 | ds = DateTime.civil(2008, 10, 11) 6 | ds.succ.should == DateTime.civil(2008, 10, 12) 7 | ds = DateTime.civil(2008, 10, 31) 8 | ds.succ.should == DateTime.civil(2008, 11, 1) 9 | ds = DateTime.commercial(2008, 2, 7) 10 | ds.succ.should == DateTime.commercial(2008, 3, 1) 11 | ds = DateTime.jd(2008) 12 | ds.succ.should == DateTime.jd(2009) 13 | ds = DateTime.ordinal(2008, 366) 14 | ds.succ.should == DateTime.ordinal(2009, 1) 15 | end 16 | 17 | it "should keep the same class as the receiver" do 18 | c = Class.new(DateTime) 19 | c.jd.succ.should be_kind_of(c) 20 | end 21 | 22 | it "should be aliased as next" do 23 | DateTime.civil(2008, 10, 11).next.should == DateTime.civil(2008, 10, 12) 24 | end 25 | 26 | it "should keep the same fractional component" do 27 | DateTime.civil(2008, 10, 11, 12, 13, 14).succ.should == DateTime.civil(2008, 10, 12, 12, 13, 14) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/datetime/upto_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../../spec_helper', __FILE__) 2 | 3 | describe "DateTime#upto" do 4 | 5 | it "should be able to step forward in time" do 6 | ds = DateTime.civil(2008, 10, 11) 7 | de = DateTime.civil(2008, 9, 29) 8 | count = 0 9 | de.upto(ds) do |d| 10 | d.should <= ds 11 | d.should >= de 12 | count += 1 13 | end 14 | count.should == 13 15 | end 16 | 17 | it "should respect fractional days" do 18 | ds = DateTime.civil(2008, 10, 11, 0) 19 | de = DateTime.civil(2008, 9, 29, 12) 20 | count = 0 21 | de.upto(ds) do |d| 22 | d.should <= ds 23 | d.should >= de 24 | count += 1 25 | end 26 | count.should == 12 27 | 28 | ds = DateTime.civil(2008, 10, 11, 12) 29 | de = DateTime.civil(2008, 9, 29, 0) 30 | count = 0 31 | de.upto(ds) do |d| 32 | d.should <= ds 33 | d.should >= de 34 | count += 1 35 | end 36 | count.should == 13 37 | end 38 | 39 | it "should keep the same class as the receiver" do 40 | c = Class.new(DateTime) 41 | c.jd.upto(c.jd + 2) do |d| 42 | d.should be_kind_of(c) 43 | end.should be_kind_of(c) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | unless ENV['MSPEC_RUNNER'] 2 | begin 3 | require "pp" 4 | require 'mspec/version' 5 | require 'mspec/helpers' 6 | require 'mspec/guards' 7 | require 'mspec/runner/shared' 8 | require 'mspec/matchers/be_ancestor_of' 9 | require 'mspec/matchers/output' 10 | require 'mspec/matchers/output_to_fd' 11 | require 'mspec/matchers/complain' 12 | require 'mspec/matchers/equal_element' 13 | require 'mspec/matchers/equal_utf16' 14 | require 'mspec/matchers/match_yaml' 15 | require 'mspec/matchers/have_class_variable' 16 | require 'mspec/matchers/have_constant' 17 | require 'mspec/matchers/have_instance_method' 18 | require 'mspec/matchers/have_instance_variable' 19 | require 'mspec/matchers/have_method' 20 | require 'mspec/matchers/have_private_instance_method' 21 | require 'mspec/matchers/have_protected_instance_method' 22 | require 'mspec/matchers/have_public_instance_method' 23 | 24 | # Code to setup HOME directory correctly on Windows 25 | # This duplicates Ruby 1.9 semantics for defining HOME 26 | platform_is :windows do 27 | if ENV['HOME'] 28 | ENV['HOME'] = ENV['HOME'].tr '\\', '/' 29 | elsif ENV['HOMEDIR'] && ENV['HOMEDRIVE'] 30 | ENV['HOME'] = File.join(ENV['HOMEDRIVE'], ENV['HOMEDIR']) 31 | elsif ENV['HOMEDIR'] 32 | ENV['HOME'] = ENV['HOMEDIR'] 33 | elsif ENV['HOMEDRIVE'] 34 | ENV['HOME'] = ENV['HOMEDRIVE'] 35 | elsif ENV['USERPROFILE'] 36 | ENV['HOME'] = ENV['USERPROFILE'] 37 | else 38 | puts "No suitable HOME environment found. This means that all of" 39 | puts "HOME, HOMEDIR, HOMEDRIVE, and USERPROFILE are not set" 40 | exit 1 41 | end 42 | end 43 | 44 | TOLERANCE = 0.00003 unless Object.const_defined?(:TOLERANCE) 45 | rescue LoadError 46 | puts "Please install the MSpec gem to run the specs." 47 | exit 1 48 | end 49 | end 50 | 51 | CODE_LOADING_DIR = File.expand_path "../fixtures/code", __FILE__ 52 | 53 | minimum_version = "1.5.17" 54 | unless MSpec::VERSION >= minimum_version 55 | puts "Please install MSpec version >= #{minimum_version} to run the specs" 56 | exit 1 57 | end 58 | 59 | $VERBOSE = nil unless ENV['OUTPUT_WARNINGS'] 60 | --------------------------------------------------------------------------------