1 require 'rubicon_testcase'
4 # NOTICE: These tests assume that your local time zone is *not* GMT.
11 def initialize(a1, anAmt, a2)
21 class TestTime < RubiconTestCase
23 ONEDAYSEC = 60 * 60 * 24
26 # Test month name to month number
44 # A random selection of interesting dates
47 # Source + amt == dest
48 T.new([1999, 12, 31, 23,59,59], 1, [2000, 1, 1, 0,0,0]),
49 T.new([2036, 12, 31, 23,59,59], 1, [2037, 1, 1, 0,0,0]),
50 T.new([2000, 2, 28, 23,59,59], 1, [2000, 2, 29, 0,0,0]),
51 T.new([1970, 2, 1, 0, 0, 0], ONEDAYSEC, [1970, 2, 2, 0,0,0]),
52 T.new([2000, 7, 1, 0, 0, 0], 32 * ONEDAYSEC, [2000, 8, 2, 0,0,0]),
53 T.new([2000, 1, 1, 0, 0, 0], 366 * ONEDAYSEC, [2001, 1, 1, 0,0,0]),
54 T.new([2001, 1, 1, 0, 0, 0], 365 * ONEDAYSEC, [2002, 1, 1, 0,0,0]),
56 T.new([2000, 1, 1, 0, 0, 0], 0, [2000, 1, 1, 0,0,0]),
57 T.new([2000, 2, 1, 0, 0, 0], 0, [2000, 2, 1, 0,0,0]),
58 T.new([2000, 3, 1, 0, 0, 0], 0, [2000, 3, 1, 0,0,0]),
59 T.new([2000, 4, 1, 0, 0, 0], 0, [2000, 4, 1, 0,0,0]),
60 T.new([2000, 5, 1, 0, 0, 0], 0, [2000, 5, 1, 0,0,0]),
61 T.new([2000, 6, 1, 0, 0, 0], 0, [2000, 6, 1, 0,0,0]),
62 T.new([2000, 7, 1, 0, 0, 0], 0, [2000, 7, 1, 0,0,0]),
63 T.new([2000, 8, 1, 0, 0, 0], 0, [2000, 8, 1, 0,0,0]),
64 T.new([2000, 9, 1, 0, 0, 0], 0, [2000, 9, 1, 0,0,0]),
65 T.new([2000, 10, 1, 0, 0, 0], 0, [2000, 10, 1, 0,0,0]),
66 T.new([2000, 11, 1, 0, 0, 0], 0, [2000, 11, 1, 0,0,0]),
67 T.new([2000, 12, 1, 0, 0, 0], 0, [2000, 12, 1, 0,0,0]),
69 T.new([2001, 1, 1, 0, 0, 0], 0, [2001, 1, 1, 0,0,0]),
70 T.new([2001, 2, 1, 0, 0, 0], 0, [2001, 2, 1, 0,0,0]),
71 T.new([2001, 3, 1, 0, 0, 0], 0, [2001, 3, 1, 0,0,0]),
72 T.new([2001, 4, 1, 0, 0, 0], 0, [2001, 4, 1, 0,0,0]),
73 T.new([2001, 5, 1, 0, 0, 0], 0, [2001, 5, 1, 0,0,0]),
74 T.new([2001, 6, 1, 0, 0, 0], 0, [2001, 6, 1, 0,0,0]),
75 T.new([2001, 7, 1, 0, 0, 0], 0, [2001, 7, 1, 0,0,0]),
76 T.new([2001, 8, 1, 0, 0, 0], 0, [2001, 8, 1, 0,0,0]),
77 T.new([2001, 9, 1, 0, 0, 0], 0, [2001, 9, 1, 0,0,0]),
78 T.new([2001, 10, 1, 0, 0, 0], 0, [2001, 10, 1, 0,0,0]),
79 T.new([2001, 11, 1, 0, 0, 0], 0, [2001, 11, 1, 0,0,0]),
80 T.new([2001, 12, 1, 0, 0, 0], 0, [2001, 12, 1, 0,0,0]),
84 @orig_zone = ENV['TZ']
86 @utc = Time.utc(2001, 2, 3, 4, 5, 6)
87 @loc = Time.local(2001, 2, 3, 4, 5, 6)
92 ENV['TZ'] = @orig_zone
96 # Check a particular date component -- m is the method (day, month, etc)
97 # and i is the index in the date specifications above.
99 def util_check_component(m, i)
101 assert_equal(x.orig[i], Time.local(*x.orig).send(m))
102 assert_equal(x.result[i], Time.local(*x.result).send(m))
103 assert_equal(x.orig[i], Time.gm(*x.orig).send(m))
104 assert_equal(x.result[i], Time.gm(*x.result).send(m))
108 def util_class_now(method)
110 max = min * 3.0 # some ruby impls will be SLOOOW
111 t1 = Time.send(method)
113 t2 = Time.send(method)
114 delta = t2.to_f - t1.to_f
115 assert(delta >= min, "time difference must be at least #{min}")
116 assert(max >= delta, "time difference should not be more than #{max}")
119 def util_os_specific_epoch
120 if $os == MsWin32 || $os == JRuby then
121 "Thu Jan 01 00:00:00 1970"
123 "Thu Jan 1 00:00:00 1970"
128 # If this test is failing, you've got big problems. Start with Time::at,
129 # Time::utc and Time::local before looking at bugs in any of your other
132 def test_00sanity # ZenTest SKIP
133 assert_equal(Time.at(981173106), Time.utc(2001, 2, 3, 4, 5, 6),
134 "If this test fails, don't bother debugging anything else.")
135 assert_equal(Time.at(981201906), Time.local(2001, 2, 3, 4, 5, 6),
136 "If this test fails, don't bother debugging anything else.")
140 expected = util_os_specific_epoch
141 assert_equal(expected, Time.at(0).gmtime.asctime)
145 # TODO: raise NotImplementedError, 'Need to write test_class__load'
150 assert_equal(0, Time.at(0).to_i)
151 assert_equal(@loc, Time.at(@loc))
152 assert_in_delta(Time.at(sec,1_000_000).to_f, Time.at(sec).to_f, 1.0)
154 # no arguments ==> error
155 assert_raise(ArgumentError) do
159 # one integer argument ==> seconds
160 t = Time.at(1_234_567)
161 assert_equal(1_234_567, t.tv_sec)
162 assert_equal( 0, t.tv_usec)
164 # two integer arguments ==> seconds & microseconds
165 t = Time.at(1_234_567, 888_999)
166 assert_equal(1_234_567, t.tv_sec)
167 assert_equal( 888_999, t.tv_usec)
169 # float argument ==> second & rounded microseconds
170 t = Time.at(1_234_567.5)
171 assert_equal(1_234_567, t.tv_sec)
172 assert_equal( 500_000, t.tv_usec)
174 # float + integer arguments ==> rounded seconds & microseconds
175 t = Time.at(1_234_567.5, 300_000)
176 assert_equal(1_234_567, t.tv_sec)
177 assert_equal( 300_000, t.tv_usec)
180 t1 = Time.at(1_234_567, 888_999)
182 assert_equal(1_234_567, t2.tv_sec)
183 assert_equal( 888_999, t2.tv_usec)
186 def test_class_at_utc
191 assert_equal(utc1.to_i, utc2.to_i)
195 assert_raises(ArgumentError) { Time.gm }
196 assert_not_equal(Time.gm(2000), Time.local(2000))
197 assert_equal(Time.gm(2000), Time.gm(2000,1,1,0,0,0))
198 assert_equal(Time.gm(2000,nil,nil,nil,nil,nil), Time.gm(2000,1,1,0,0,0))
199 assert_raises(ArgumentError) { Time.gm(2000,0) }
200 assert_raises(ArgumentError) { Time.gm(2000,13) }
201 assert_raises(ArgumentError) { Time.gm(2000,1,1,24) }
203 @@months.each do |month, num|
204 assert_equal(Time.gm(2000,month), Time.gm(2000,num,1,0,0,0))
205 assert_equal(Time.gm(1970,month), Time.gm(1970,num,1,0,0,0))
206 assert_equal(Time.gm(2037,month), Time.gm(2037,num,1,0,0,0))
208 t = Time.gm(2000,1,1)
210 assert_equal(Time.gm(*a),t)
214 assert_raises(ArgumentError) { Time.local }
215 assert_not_equal(Time.gm(2000), Time.local(2000))
216 assert_equal(Time.local(2000), Time.local(2000,1,1,0,0,0))
217 assert_equal(Time.local(2000,nil,nil,nil,nil,nil), Time.local(2000,1,1,0,0,0))
218 assert_raises(ArgumentError) { Time.local(2000,0) }
219 assert_raises(ArgumentError) { Time.local(2000,13) }
220 assert_raises(ArgumentError) { Time.local(2000,1,1,24) }
221 Time.local(2000,1,1,23)
222 @@months.each do |month, num|
223 assert_equal(Time.local(2000,month), Time.local(2000,num,1,0,0,0))
224 assert_equal(Time.local(1971,month), Time.local(1971,num,1,0,0,0))
225 assert_equal(Time.local(2037,month), Time.local(2037,num,1,0,0,0))
227 t = Time.local(2000,1,1)
229 assert_equal(Time.local(*a),t)
232 def test_class_mktime
234 # Test insufficient arguments
236 assert_raises(ArgumentError) { Time.mktime }
237 assert_not_equal(Time.gm(2000), Time.mktime(2000))
238 assert_equal(Time.mktime(2000), Time.mktime(2000,1,1,0,0,0))
239 assert_equal(Time.mktime(2000,nil,nil,nil,nil,nil), Time.mktime(2000,1,1,0,0,0))
240 assert_raises(ArgumentError) { Time.mktime(2000,0) }
241 assert_raises(ArgumentError) { Time.mktime(2000,13) }
242 assert_raises(ArgumentError) { Time.mktime(2000,1,1,24) }
243 Time.mktime(2000,1,1,23)
246 # Make sure spelled-out month names work
248 @@months.each do |month, num|
249 assert_equal(Time.mktime(2000,month), Time.mktime(2000,num,1,0,0,0))
250 assert_equal(Time.mktime(1971,month), Time.mktime(1971,num,1,0,0,0))
251 assert_equal(Time.mktime(2037,month), Time.mktime(2037,num,1,0,0,0))
253 t = Time.mktime(2000,1,1)
255 assert_equal(Time.mktime(*a),t)
259 util_class_now(:now) # Time.now
263 assert_instance_of(Struct::Tms, Process.times)
267 test_class_gm # TODO: refactor to ensure they really are synonyms
271 for taint in [ false, true ]
272 for frozen in [ false, true ]
279 assert_not_equal(a.__id__, b.__id__)
280 assert_equal(a.frozen?, b.frozen?)
281 assert_equal(a.tainted?, b.tainted?)
287 expected = util_os_specific_epoch
288 assert_equal(expected, Time.at(0).gmtime.ctime)
292 util_check_component(:day, 2)
296 test_isdst # TODO: refactor to test that they really are the same
300 # TODO: raise NotImplementedError, 'Need to write test__dump'
312 assert(t1.eql?(t1.getutc))
316 # TODO: this only tests local -> gm
323 assert_equal(t1, loc)
324 assert_equal(t1.asctime, loc.asctime)
325 assert_not_equal(t2.asctime, loc.asctime)
326 assert_not_equal(t1.asctime, t2.asctime)
331 # TODO: this only tests gm -> local
338 assert_equal(t1, utc)
339 assert_equal(t1.asctime, utc.asctime)
340 assert_not_equal(t2.asctime, utc.asctime)
341 assert_not_equal(t1.asctime, t2.asctime)
346 test_getgm # REFACTOR to test both calls
352 assert(!Time.local(2000).gmt?)
353 assert(Time.gm(2000).gmt?)
357 test_utc_offset # REFACTOR to test both methods
361 # TODO: this only tests local -> gm
367 assert_not_equal(t.asctime, loc.asctime)
371 test_utc_offset # REFACTOR to test both methods
378 assert_equal(t1.hash, t2.hash)
379 assert_not_equal(t1.hash, t3.hash)
383 util_check_component(:hour, 3)
387 util_class_now(:new) # Time.new
391 assert_equal("Sat Feb 03 04:05:06 UTC 2001", @utc.inspect)
392 assert_equal("Sat Feb 03 04:05:06 #{@zone} 2001", @loc.inspect)
396 # This code is problematic: how do I find out the exact
397 # date and time of the dst switch for all the possible
398 # timezones in which this code runs? For now, I'll just check
399 # midvalues, and add boundary checks for the US. I know this won't
400 # work in some parts of the US, even, so I'm looking for
407 "PST", "PDT"].include? @zone
412 [true, 2000, 4, 2, 4],
413 [false, 2000, 10, 29, 4],
414 [false, 2000, 4,2,1,59], # Spring forward
415 [true, 2000, 4,2,3,0],
416 [true, 2000, 10,29,0,59], # Fall back
417 [false, 2000, 10,29,2,0]
422 assert_equal(result, Time.local(*x).isdst,
423 "\nExpected Time.local(#{x.join(',')}).isdst == #{result}")
426 skipping("Don't know how to do timezones");
431 # TODO: this only tests gm -> local
437 assert_not_equal(t.asctime, utc.asctime)
441 util_check_component(:mday, 2)
445 util_check_component(:min, 4)
450 # Check subtracting an amount in seconds
451 assert_equal(Time.local(*x.result) - x.amt, Time.local(*x.orig))
452 assert_equal(Time.gm(*x.result) - x.amt, Time.gm(*x.orig))
453 # Check subtracting two times
454 assert_equal(Time.local(*x.result) - Time.local(*x.orig), x.amt)
455 assert_equal(Time.gm(*x.result) - Time.gm(*x.orig), x.amt)
459 t1 = Time.at(1_234_567, 500_000)
461 assert_equal( 1_234_000, t2.tv_sec)
462 assert_equal( 500_000, t2.tv_usec)
464 # float argument with fractional part
465 t1 = Time.at(1_234_567, 500_000)
467 assert_equal( 1_234_000, t2.tv_sec)
468 assert_equal( 750_000, t2.tv_usec)
471 t1 = Time.at(1_234_000, 750_000)
472 t2 = Time.at(1_234_567, 500_000)
474 assert_equal( 566.75, diff)
478 util_check_component(:mon, 1)
482 util_check_component(:month, 1)
487 assert_equal(Time.local(*x.orig) + x.amt, Time.local(*x.result))
488 assert_equal(Time.gm(*x.orig) + x.amt, Time.gm(*x.result))
492 t1 = Time.at(1_234_567, 500_000)
494 assert_equal( 1_235_000, t2.tv_sec)
495 assert_equal( 500_000, t2.tv_usec)
497 # float argument with fractional part
498 t1 = Time.at(1_234_567, 500_000)
500 assert_equal( 1_235_000, t2.tv_sec)
501 assert_equal( 750_000, t2.tv_usec)
505 util_check_component(:sec, 5)
508 def test_spaceship # '<=>'
511 assert_equal(1, Time.local(*x.result) <=> Time.local(*x.orig),
512 "#{x.result} should be > #{x.orig}")
514 assert_equal(-1, Time.local(*x.orig) <=> Time.local(*x.result))
515 assert_equal(0, Time.local(*x.orig) <=> Time.local(*x.orig))
516 assert_equal(0, Time.local(*x.result) <=> Time.local(*x.result))
518 assert_equal(1,Time.gm(*x.result) <=> Time.gm(*x.orig))
519 assert_equal(-1,Time.gm(*x.orig) <=> Time.gm(*x.result))
520 assert_equal(0,Time.gm(*x.orig) <=> Time.gm(*x.orig))
521 assert_equal(0,Time.gm(*x.result) <=> Time.gm(*x.result))
526 assert_equal( 1, Time.at(10_000, 500_000) <=> Time.at(10_000, 499_999))
527 assert_equal( 0, Time.at(10_000, 500_000) <=> Time.at(10_000, 500_000))
528 assert_equal(-1, Time.at(10_000, 500_000) <=> Time.at(10_000, 500_001))
530 # second diff & microsecond diffs
531 assert_equal(-1, Time.at(10_000, 500_000) <=> Time.at(10_001, 499_999))
532 assert_equal(-1, Time.at(10_000, 500_000) <=> Time.at(10_001, 500_000))
533 assert_equal(-1, Time.at(10_000, 500_000) <=> Time.at(10_001, 500_001))
535 # non-Time object gives nil
536 assert_nil(Time.at(10_000) <=> Object.new)
540 # Sat Jan 1 14:58:42 2000
541 t = Time.local(2000,1,1,14,58,42)
548 #'%c', The preferred local date and time representation,
560 #'%x', Preferred representation for the date alone, no time\\
561 #'%X', Preferred representation for the time alone, no date\\
564 #'%Z', Time zone name\\
568 stest.each {|flag,val|
569 assert_equal("Got "+val,t.strftime("Got " + flag))
584 assert_equal(t.sec, a[0])
585 assert_equal(t.min, a[1])
586 assert_equal(t.hour, a[2])
587 assert_equal(t.day, a[3])
588 assert_equal(t.month,a[4])
589 assert_equal(t.year, a[5])
590 assert_equal(t.wday, a[6])
591 assert_equal(t.yday, a[7])
592 assert_equal(t.isdst,a[8])
593 assert_equal(t.zone, a[9])
597 t = Time.at(10000,1066)
598 assert_in_delta(10000.001066, t.to_f, 1e-7)
603 assert_equal(0, t.to_i)
605 assert_equal(10000, t.to_i)
609 assert_equal("Sat Feb 03 04:05:06 UTC 2001", @utc.to_s)
610 assert_equal("Sat Feb 03 04:05:06 #{@zone} 2001", @loc.to_s)
615 assert_equal(0,t.tv_sec)
617 assert_equal(10000,t.tv_sec)
620 def util_usec(s, u, method)
622 assert_equal(u,t.send(method))
626 util_usec(10000, 1066, :tv_usec)
627 util_usec(10000, 0, :tv_usec)
631 util_usec(10000, 1066, :usec)
632 util_usec(10000, 0, :usec)
636 test_gmtime # REFACTOR to test both methods
640 test_gmt_eh # REFACTOR to test both methods
644 # TODO: figure out the year, month, & day edgecase setups
646 assert_equal(0, @utc.utc_offset)
647 assert_equal(off, @loc.utc_offset)
651 t = Time.local(2001, 4, 1)
654 assert_equal(i,t.wday)
660 # non-leap 1/1, 2/28, 3/1, 12/31
661 # leap 1/1, 2/28, 2/29, 3/1, 12/31
662 # leap century (2000)
663 # want to do a non-leap century, but they are out of range.
667 assert_equal( 1, Time.local(1999, 1, 1).yday)
668 assert_equal( 59, Time.local(1999, 2, 28).yday)
669 assert_equal( 60, Time.local(1999, 3, 1).yday)
670 assert_equal(365, Time.local(1999, 12, 31).yday)
673 assert_equal( 1, Time.local(2000, 1, 1).yday)
674 assert_equal( 59, Time.local(2000, 2, 28).yday)
675 assert_equal( 60, Time.local(2000, 2, 29).yday)
676 assert_equal( 61, Time.local(2000, 3, 1).yday)
677 assert_equal(366, Time.local(2000, 12, 31).yday)
680 assert_equal( 1, Time.local(2004, 1, 1).yday)
681 assert_equal( 59, Time.local(2004, 2, 28).yday)
682 assert_equal( 60, Time.local(2004, 2, 29).yday)
683 assert_equal( 61, Time.local(2004, 3, 1).yday)
684 assert_equal(366, Time.local(2004, 12, 31).yday)
688 util_check_component(:year, 0)
694 assert_equal(gmt, t.zone)
696 assert_not_equal(gmt, t.zone)