time_ext_test.rb 48.4 KB
Newer Older
1
require 'abstract_unit'
2
require 'active_support/time'
3
require 'core_ext/date_and_time_behavior'
4
require 'time_zone_test_helpers'
5

6
class TimeExtCalculationsTest < ActiveSupport::TestCase
7 8 9 10 11
  def date_time_init(year,month,day,hour,minute,second,usec=0)
    Time.local(year,month,day,hour,minute,second,usec)
  end

  include DateAndTimeBehavior
12
  include TimeZoneTestHelpers
13

14 15 16 17 18 19 20 21
  def test_seconds_since_midnight
    assert_equal 1,Time.local(2005,1,1,0,0,1).seconds_since_midnight
    assert_equal 60,Time.local(2005,1,1,0,1,0).seconds_since_midnight
    assert_equal 3660,Time.local(2005,1,1,1,1,0).seconds_since_midnight
    assert_equal 86399,Time.local(2005,1,1,23,59,59).seconds_since_midnight
    assert_equal 60.00001,Time.local(2005,1,1,0,1,0,10).seconds_since_midnight
  end

22
  def test_seconds_since_midnight_at_daylight_savings_time_start
23
    with_env_tz 'US/Eastern' do
24
      # dt: US: 2005 April 3rd 2:00am ST => April 3rd 3:00am DT
25 26 27 28
      assert_equal 2*3600-1, Time.local(2005,4,3,1,59,59).seconds_since_midnight, 'just before DST start'
      assert_equal 2*3600+1, Time.local(2005,4,3,3, 0, 1).seconds_since_midnight, 'just after DST start'
    end

29
    with_env_tz 'NZ' do
30 31 32
      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
      assert_equal 2*3600-1, Time.local(2006,10,1,1,59,59).seconds_since_midnight, 'just before DST start'
      assert_equal 2*3600+1, Time.local(2006,10,1,3, 0, 1).seconds_since_midnight, 'just after DST start'
33
    end
34 35 36
  end

  def test_seconds_since_midnight_at_daylight_savings_time_end
37
    with_env_tz 'US/Eastern' do
38 39
      # st: US: 2005 October 30th 2:00am DT => October 30th 1:00am ST
      # avoid setting a time between 1:00 and 2:00 since that requires specifying whether DST is active
40
      assert_equal 1*3600-1, Time.local(2005,10,30,0,59,59).seconds_since_midnight, 'just before DST end'
41
      assert_equal 3*3600+1, Time.local(2005,10,30,2, 0, 1).seconds_since_midnight, 'just after DST end'
42

43 44
      # now set a time between 1:00 and 2:00 by specifying whether DST is active
      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
45 46 47 48
      assert_equal 1*3600+30*60, Time.local(0,30,1,30,10,2005,0,0,true,ENV['TZ']).seconds_since_midnight, 'before DST end'
      assert_equal 2*3600+30*60, Time.local(0,30,1,30,10,2005,0,0,false,ENV['TZ']).seconds_since_midnight, 'after DST end'
    end

49
    with_env_tz 'NZ' do
50 51 52 53 54 55 56 57 58
      # st: New Zealand: 2006 March 19th 3:00am DT => March 19th 2:00am ST
      # avoid setting a time between 2:00 and 3:00 since that requires specifying whether DST is active
      assert_equal 2*3600-1, Time.local(2006,3,19,1,59,59).seconds_since_midnight, 'just before DST end'
      assert_equal 4*3600+1, Time.local(2006,3,19,3, 0, 1).seconds_since_midnight, 'just after DST end'

      # now set a time between 2:00 and 3:00 by specifying whether DST is active
      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
      assert_equal 2*3600+30*60, Time.local(0,30,2,19,3,2006,0,0,true, ENV['TZ']).seconds_since_midnight, 'before DST end'
      assert_equal 3*3600+30*60, Time.local(0,30,2,19,3,2006,0,0,false,ENV['TZ']).seconds_since_midnight, 'after DST end'
59
    end
60 61
  end

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  def test_seconds_until_end_of_day
    assert_equal 0, Time.local(2005,1,1,23,59,59).seconds_until_end_of_day
    assert_equal 1, Time.local(2005,1,1,23,59,58).seconds_until_end_of_day
    assert_equal 60, Time.local(2005,1,1,23,58,59).seconds_until_end_of_day
    assert_equal 3660, Time.local(2005,1,1,22,58,59).seconds_until_end_of_day
    assert_equal 86399, Time.local(2005,1,1,0,0,0).seconds_until_end_of_day
  end

  def test_seconds_until_end_of_day_at_daylight_savings_time_start
    with_env_tz 'US/Eastern' do
      # dt: US: 2005 April 3rd 2:00am ST => April 3rd 3:00am DT
      assert_equal 21*3600, Time.local(2005,4,3,1,59,59).seconds_until_end_of_day, 'just before DST start'
      assert_equal 21*3600-2, Time.local(2005,4,3,3,0,1).seconds_until_end_of_day, 'just after DST start'
    end

    with_env_tz 'NZ' do
      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
      assert_equal 21*3600, Time.local(2006,10,1,1,59,59).seconds_until_end_of_day, 'just before DST start'
      assert_equal 21*3600-2, Time.local(2006,10,1,3,0,1).seconds_until_end_of_day, 'just after DST start'
    end
  end

  def test_seconds_until_end_of_day_at_daylight_savings_time_end
    with_env_tz 'US/Eastern' do
      # st: US: 2005 October 30th 2:00am DT => October 30th 1:00am ST
      # avoid setting a time between 1:00 and 2:00 since that requires specifying whether DST is active
      assert_equal 24*3600, Time.local(2005,10,30,0,59,59).seconds_until_end_of_day, 'just before DST end'
      assert_equal 22*3600-2, Time.local(2005,10,30,2,0,1).seconds_until_end_of_day, 'just after DST end'

      # now set a time between 1:00 and 2:00 by specifying whether DST is active
      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
      assert_equal 24*3600-30*60-1, Time.local(0,30,1,30,10,2005,0,0,true,ENV['TZ']).seconds_until_end_of_day, 'before DST end'
      assert_equal 23*3600-30*60-1, Time.local(0,30,1,30,10,2005,0,0,false,ENV['TZ']).seconds_until_end_of_day, 'after DST end'
    end

    with_env_tz 'NZ' do
      # st: New Zealand: 2006 March 19th 3:00am DT => March 19th 2:00am ST
      # avoid setting a time between 2:00 and 3:00 since that requires specifying whether DST is active
      assert_equal 23*3600, Time.local(2006,3,19,1,59,59).seconds_until_end_of_day, 'just before DST end'
      assert_equal 21*3600-2, Time.local(2006,3,19,3,0,1).seconds_until_end_of_day, 'just after DST end'

      # now set a time between 2:00 and 3:00 by specifying whether DST is active
      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
      assert_equal 23*3600-30*60-1, Time.local(0,30,2,19,3,2006,0,0,true, ENV['TZ']).seconds_until_end_of_day, 'before DST end'
      assert_equal 22*3600-30*60-1, Time.local(0,30,2,19,3,2006,0,0,false,ENV['TZ']).seconds_until_end_of_day, 'after DST end'
    end
  end

110 111
  def test_beginning_of_day
    assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day
112
    with_env_tz 'US/Eastern' do
113 114 115
      assert_equal Time.local(2006,4,2,0,0,0), Time.local(2006,4,2,10,10,10).beginning_of_day, 'start DST'
      assert_equal Time.local(2006,10,29,0,0,0), Time.local(2006,10,29,10,10,10).beginning_of_day, 'ends DST'
    end
116
    with_env_tz 'NZ' do
117 118 119
      assert_equal Time.local(2006,3,19,0,0,0), Time.local(2006,3,19,10,10,10).beginning_of_day, 'ends DST'
      assert_equal Time.local(2006,10,1,0,0,0), Time.local(2006,10,1,10,10,10).beginning_of_day, 'start DST'
    end
120
  end
121

A
Anatoli Makarevich 已提交
122 123 124 125 126 127 128 129 130 131 132 133
  def test_middle_of_day
    assert_equal Time.local(2005,2,4,12,0,0), Time.local(2005,2,4,10,10,10).middle_of_day
    with_env_tz 'US/Eastern' do
      assert_equal Time.local(2006,4,2,12,0,0), Time.local(2006,4,2,10,10,10).middle_of_day, 'start DST'
      assert_equal Time.local(2006,10,29,12,0,0), Time.local(2006,10,29,10,10,10).middle_of_day, 'ends DST'
    end
    with_env_tz 'NZ' do
      assert_equal Time.local(2006,3,19,12,0,0), Time.local(2006,3,19,10,10,10).middle_of_day, 'ends DST'
      assert_equal Time.local(2006,10,1,12,0,0), Time.local(2006,10,1,10,10,10).middle_of_day, 'start DST'
    end
  end

134 135 136 137
  def test_beginning_of_hour
    assert_equal Time.local(2005,2,4,19,0,0), Time.local(2005,2,4,19,30,10).beginning_of_hour
  end

138 139 140 141
  def test_beginning_of_minute
    assert_equal Time.local(2005,2,4,19,30,0), Time.local(2005,2,4,19,30,10).beginning_of_minute
  end

142
  def test_end_of_day
143
    assert_equal Time.local(2007,8,12,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,12,10,10,10).end_of_day
144
    with_env_tz 'US/Eastern' do
145 146
      assert_equal Time.local(2007,4,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
      assert_equal Time.local(2007,10,29,23,59,59,Rational(999999999, 1000)), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
147 148
    end
    with_env_tz 'NZ' do
149 150
      assert_equal Time.local(2006,3,19,23,59,59,Rational(999999999, 1000)), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
      assert_equal Time.local(2006,10,1,23,59,59,Rational(999999999, 1000)), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
151 152 153
    end
  end

154
  def test_end_of_hour
155
    assert_equal Time.local(2005,2,4,19,59,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_hour
156 157
  end

158 159 160 161
  def test_end_of_minute
    assert_equal Time.local(2005,2,4,19,30,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_minute
  end

162 163 164 165
  def test_last_year
    assert_equal Time.local(2004,6,5,10),  Time.local(2005,6,5,10,0,0).last_year
  end

166 167 168 169 170
  def test_ago
    assert_equal Time.local(2005,2,22,10,10,9),  Time.local(2005,2,22,10,10,10).ago(1)
    assert_equal Time.local(2005,2,22,9,10,10),  Time.local(2005,2,22,10,10,10).ago(3600)
    assert_equal Time.local(2005,2,20,10,10,10), Time.local(2005,2,22,10,10,10).ago(86400*2)
    assert_equal Time.local(2005,2,20,9,9,45),   Time.local(2005,2,22,10,10,10).ago(86400*2 + 3600 + 25)
171 172
  end

173
  def test_daylight_savings_time_crossings_backward_start
174
    with_env_tz 'US/Eastern' do
175
      # dt: US: 2005 April 3rd 4:18am
176 177 178
      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(24.hours), 'dt-24.hours=>st'
      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(86400), 'dt-86400=>st'
      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(86400.seconds), 'dt-86400.seconds=>st'
179

180 181 182
      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(24.hours), 'st-24.hours=>st'
      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400), 'st-86400=>st'
      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400.seconds), 'st-86400.seconds=>st'
183
    end
184
    with_env_tz 'NZ' do
185
      # dt: New Zealand: 2006 October 1st 4:18am
186 187
      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(24.hours), 'dt-24.hours=>st'
      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(86400), 'dt-86400=>st'
G
Geoff Buesing 已提交
188
      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(86400.seconds), 'dt-86400.seconds=>st'
189

190
      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(24.hours), 'st-24.hours=>st'
G
Geoff Buesing 已提交
191
      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400), 'st-86400=>st'
192
      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400.seconds), 'st-86400.seconds=>st'
193
    end
194 195 196
  end

  def test_daylight_savings_time_crossings_backward_end
197
    with_env_tz 'US/Eastern' do
198
      # st: US: 2005 October 30th 4:03am
199 200 201
      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(24.hours), 'st-24.hours=>dt'
      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(86400), 'st-86400=>dt'
      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(86400.seconds), 'st-86400.seconds=>dt'
202

203 204 205
      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(24.hours), 'dt-24.hours=>dt'
      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400), 'dt-86400=>dt'
      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400.seconds), 'dt-86400.seconds=>dt'
206
    end
207
    with_env_tz 'NZ' do
208
      # st: New Zealand: 2006 March 19th 4:03am
209 210 211
      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(24.hours), 'st-24.hours=>dt'
      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(86400), 'st-86400=>dt'
      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(86400.seconds), 'st-86400.seconds=>dt'
212

213 214 215
      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(24.hours), 'dt-24.hours=>dt'
      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400), 'dt-86400=>dt'
      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400.seconds), 'dt-86400.seconds=>dt'
216
    end
217 218
  end

219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
  def test_daylight_savings_time_crossings_backward_start_1day
    with_env_tz 'US/Eastern' do
      # dt: US: 2005 April 3rd 4:18am
      assert_equal Time.local(2005,4,2,4,18,0), Time.local(2005,4,3,4,18,0).ago(1.day), 'dt-1.day=>st'
      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(1.day), 'st-1.day=>st'
    end
    with_env_tz 'NZ' do
      # dt: New Zealand: 2006 October 1st 4:18am
      assert_equal Time.local(2006,9,30,4,18,0), Time.local(2006,10,1,4,18,0).ago(1.day), 'dt-1.day=>st'
      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(1.day), 'st-1.day=>st'
    end
  end

  def test_daylight_savings_time_crossings_backward_end_1day
    with_env_tz 'US/Eastern' do
      # st: US: 2005 October 30th 4:03am
      assert_equal Time.local(2005,10,29,4,3), Time.local(2005,10,30,4,3,0).ago(1.day), 'st-1.day=>dt'
      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(1.day), 'dt-1.day=>dt'
    end
    with_env_tz 'NZ' do
      # st: New Zealand: 2006 March 19th 4:03am
      assert_equal Time.local(2006,3,18,4,3), Time.local(2006,3,19,4,3,0).ago(1.day), 'st-1.day=>dt'
      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(1.day), 'dt-1.day=>dt'
    end
  end
244

245 246 247 248 249
  def test_since
    assert_equal Time.local(2005,2,22,10,10,11), Time.local(2005,2,22,10,10,10).since(1)
    assert_equal Time.local(2005,2,22,11,10,10), Time.local(2005,2,22,10,10,10).since(3600)
    assert_equal Time.local(2005,2,24,10,10,10), Time.local(2005,2,22,10,10,10).since(86400*2)
    assert_equal Time.local(2005,2,24,11,10,35), Time.local(2005,2,22,10,10,10).since(86400*2 + 3600 + 25)
250 251
    # when out of range of Time, returns a DateTime
    assert_equal DateTime.civil(2038,1,20,11,59,59), Time.utc(2038,1,18,11,59,59).since(86400*2)
252 253
  end

254
  def test_daylight_savings_time_crossings_forward_start
255
    with_env_tz 'US/Eastern' do
256
      # st: US: 2005 April 2nd 7:27pm
257 258 259
      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(24.hours), 'st+24.hours=>dt'
      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(86400), 'st+86400=>dt'
      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(86400.seconds), 'st+86400.seconds=>dt'
260

G
Geoff Buesing 已提交
261
      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(24.hours), 'dt+24.hours=>dt'
262 263
      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400), 'dt+86400=>dt'
      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400.seconds), 'dt+86400.seconds=>dt'
264
    end
265
    with_env_tz 'NZ' do
266
      # st: New Zealand: 2006 September 30th 7:27pm
267 268 269
      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(24.hours), 'st+24.hours=>dt'
      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(86400), 'st+86400=>dt'
      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(86400.seconds), 'st+86400.seconds=>dt'
270

271 272 273
      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(24.hours), 'dt+24.hours=>dt'
      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400), 'dt+86400=>dt'
      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400.seconds), 'dt+86400.seconds=>dt'
274
    end
275 276
  end

277 278 279 280 281 282 283 284 285 286 287 288 289
  def test_daylight_savings_time_crossings_forward_start_1day
    with_env_tz 'US/Eastern' do
      # st: US: 2005 April 2nd 7:27pm
      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).since(1.day), 'st+1.day=>dt'
      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(1.day), 'dt+1.day=>dt'
    end
    with_env_tz 'NZ' do
      # st: New Zealand: 2006 September 30th 7:27pm
      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).since(1.day), 'st+1.day=>dt'
      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(1.day), 'dt+1.day=>dt'
    end
  end

290 291 292 293 294 295 296 297 298 299 300 301 302
  def test_daylight_savings_time_crossings_forward_start_tomorrow
    with_env_tz 'US/Eastern' do
      # st: US: 2005 April 2nd 7:27pm
      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).tomorrow, 'st+1.day=>dt'
      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).tomorrow, 'dt+1.day=>dt'
    end
    with_env_tz 'NZ' do
      # st: New Zealand: 2006 September 30th 7:27pm
      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).tomorrow, 'st+1.day=>dt'
      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).tomorrow, 'dt+1.day=>dt'
    end
  end

303
  def test_daylight_savings_time_crossings_backward_start_yesterday
304 305 306 307 308 309 310 311 312 313 314 315
    with_env_tz 'US/Eastern' do
      # st: US: 2005 April 2nd 7:27pm
      assert_equal Time.local(2005,4,2,19,27,0), Time.local(2005,4,3,19,27,0).yesterday, 'dt-1.day=>st'
      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,4,19,27,0).yesterday, 'dt-1.day=>dt'
    end
    with_env_tz 'NZ' do
      # st: New Zealand: 2006 September 30th 7:27pm
      assert_equal Time.local(2006,9,30,19,27,0), Time.local(2006,10,1,19,27,0).yesterday, 'dt-1.day=>st'
      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,10,2,19,27,0).yesterday, 'dt-1.day=>dt'
    end
  end

316
  def test_daylight_savings_time_crossings_forward_end
317
    with_env_tz 'US/Eastern' do
318
      # dt: US: 2005 October 30th 12:45am
319 320 321
      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(24.hours), 'dt+24.hours=>st'
      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(86400), 'dt+86400=>st'
      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(86400.seconds), 'dt+86400.seconds=>st'
322

323 324 325
      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(24.hours), 'st+24.hours=>st'
      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400), 'st+86400=>st'
      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400.seconds), 'st+86400.seconds=>st'
326
    end
327
    with_env_tz 'NZ' do
328
      # dt: New Zealand: 2006 March 19th 1:45am
329 330 331
      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(24.hours), 'dt+24.hours=>st'
      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(86400), 'dt+86400=>st'
      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(86400.seconds), 'dt+86400.seconds=>st'
332

333 334 335
      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(24.hours), 'st+24.hours=>st'
      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400), 'st+86400=>st'
      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400.seconds), 'st+86400.seconds=>st'
336
    end
337 338
  end

339 340 341 342 343 344 345 346 347 348 349 350 351
  def test_daylight_savings_time_crossings_forward_end_1day
    with_env_tz 'US/Eastern' do
      # dt: US: 2005 October 30th 12:45am
      assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).since(1.day), 'dt+1.day=>st'
      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(1.day), 'st+1.day=>st'
    end
    with_env_tz 'NZ' do
      # dt: New Zealand: 2006 March 19th 1:45am
      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).since(1.day), 'dt+1.day=>st'
      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(1.day), 'st+1.day=>st'
    end
  end

352 353 354 355 356 357 358 359 360 361 362 363 364
  def test_daylight_savings_time_crossings_forward_end_tomorrow
    with_env_tz 'US/Eastern' do
      # dt: US: 2005 October 30th 12:45am
      assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).tomorrow, 'dt+1.day=>st'
      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).tomorrow, 'st+1.day=>st'
    end
    with_env_tz 'NZ' do
      # dt: New Zealand: 2006 March 19th 1:45am
      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).tomorrow, 'dt+1.day=>st'
      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).tomorrow, 'st+1.day=>st'
    end
  end

365
  def test_daylight_savings_time_crossings_backward_end_yesterday
366 367 368 369 370 371 372 373 374 375 376 377
    with_env_tz 'US/Eastern' do
      # dt: US: 2005 October 30th 12:45am
      assert_equal Time.local(2005,10,30,0,45,0), Time.local(2005,10,31,0,45,0).yesterday, 'st-1.day=>dt'
      assert_equal Time.local(2005,10, 31,0,45,0), Time.local(2005,11,1,0,45,0).yesterday, 'st-1.day=>st'
    end
    with_env_tz 'NZ' do
      # dt: New Zealand: 2006 March 19th 1:45am
      assert_equal Time.local(2006,3,19,1,45,0), Time.local(2006,3,20,1,45,0).yesterday, 'st-1.day=>dt'
      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,21,1,45,0).yesterday, 'st-1.day=>st'
    end
  end

378 379 380 381
  def test_change
    assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2006)
    assert_equal Time.local(2005,6,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:month => 6)
    assert_equal Time.local(2012,9,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2012, :month => 9)
D
David Heinemeier Hansson 已提交
382 383 384
    assert_equal Time.local(2005,2,22,16),       Time.local(2005,2,22,15,15,10).change(:hour => 16)
    assert_equal Time.local(2005,2,22,16,45),    Time.local(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
    assert_equal Time.local(2005,2,22,15,45),    Time.local(2005,2,22,15,15,10).change(:min => 45)
385 386 387 388 389

    assert_equal Time.local(2005,1,2, 5, 0, 0, 0), Time.local(2005,1,2,11,22,33,44).change(:hour => 5)
    assert_equal Time.local(2005,1,2,11, 6, 0, 0), Time.local(2005,1,2,11,22,33,44).change(:min  => 6)
    assert_equal Time.local(2005,1,2,11,22, 7, 0), Time.local(2005,1,2,11,22,33,44).change(:sec  => 7)
    assert_equal Time.local(2005,1,2,11,22,33, 8), Time.local(2005,1,2,11,22,33,44).change(:usec => 8)
390 391
    assert_equal Time.local(2005,1,2,11,22,33, 8), Time.local(2005,1,2,11,22,33,2).change(:nsec => 8000)
    assert_raise(ArgumentError) { Time.local(2005,1,2,11,22,33, 8).change(:usec => 1, :nsec => 1) }
D
David Heinemeier Hansson 已提交
392
  end
393

D
David Heinemeier Hansson 已提交
394 395 396 397 398 399 400
  def test_utc_change
    assert_equal Time.utc(2006,2,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:year => 2006)
    assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:month => 6)
    assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:year => 2012, :month => 9)
    assert_equal Time.utc(2005,2,22,16),       Time.utc(2005,2,22,15,15,10).change(:hour => 16)
    assert_equal Time.utc(2005,2,22,16,45),    Time.utc(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
    assert_equal Time.utc(2005,2,22,15,45),    Time.utc(2005,2,22,15,15,10).change(:min => 45)
401
    assert_equal Time.utc(2005,1,2,11,22,33,8), Time.utc(2005,1,2,11,22,33,2).change(:nsec => 8000)
402
  end
403

404 405 406 407 408 409 410
  def test_offset_change
    assert_equal Time.new(2006,2,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2006)
    assert_equal Time.new(2005,6,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:month => 6)
    assert_equal Time.new(2012,9,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2012, :month => 9)
    assert_equal Time.new(2005,2,22,16,0,0,"-08:00"),   Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16)
    assert_equal Time.new(2005,2,22,16,45,0,"-08:00"),  Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16, :min => 45)
    assert_equal Time.new(2005,2,22,15,45,0,"-08:00"),  Time.new(2005,2,22,15,15,10,"-08:00").change(:min => 45)
411 412 413
    assert_equal Time.new(2005,2,22,15,15,10,"-08:00"),  Time.new(2005,2,22,15,15,0,"-08:00").change(:sec => 10)
    assert_equal 10, Time.new(2005,2,22,15,15,0,"-08:00").change(:usec => 10).usec
    assert_equal 10, Time.new(2005,2,22,15,15,0,"-08:00").change(:nsec => 10).nsec
414
    assert_raise(ArgumentError) { Time.new(2005, 2, 22, 15, 15, 45, "-08:00").change(:usec => 1000000) }
415
    assert_raise(ArgumentError) { Time.new(2005, 2, 22, 15, 15, 45, "-08:00").change(:nsec => 1000000000) }
416 417
  end

418
  def test_advance
419 420
    assert_equal Time.local(2006,2,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 1)
    assert_equal Time.local(2005,6,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:months => 4)
421
    assert_equal Time.local(2005,3,21,15,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3)
422
    assert_equal Time.local(2005,3,25,3,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.5)
J
Jeremy Kemper 已提交
423
    assert_in_delta Time.local(2005,3,26,12,51,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
424
    assert_equal Time.local(2005,3,5,15,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5)
425
    assert_equal Time.local(2005,3,6,3,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.5)
J
Jeremy Kemper 已提交
426
    assert_in_delta Time.local(2005,3,6,8,3,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.7), 1
427 428
    assert_equal Time.local(2012,9,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 7)
    assert_equal Time.local(2013,10,3,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5)
429
    assert_equal Time.local(2013,10,17,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
430
    assert_equal Time.local(2001,12,27,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => -3, :months => -2, :days => -1)
431
    assert_equal Time.local(2005,2,28,15,15,10), Time.local(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year
432 433 434 435 436
    assert_equal Time.local(2005,2,28,20,15,10), Time.local(2005,2,28,15,15,10).advance(:hours => 5)
    assert_equal Time.local(2005,2,28,15,22,10), Time.local(2005,2,28,15,15,10).advance(:minutes => 7)
    assert_equal Time.local(2005,2,28,15,15,19), Time.local(2005,2,28,15,15,10).advance(:seconds => 9)
    assert_equal Time.local(2005,2,28,20,22,19), Time.local(2005,2,28,15,15,10).advance(:hours => 5, :minutes => 7, :seconds => 9)
    assert_equal Time.local(2005,2,28,10,8,1), Time.local(2005,2,28,15,15,10).advance(:hours => -5, :minutes => -7, :seconds => -9)
437
    assert_equal Time.local(2013,10,17,20,22,19), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
438
  end
439

440
  def test_utc_advance
441 442
    assert_equal Time.utc(2006,2,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 1)
    assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:months => 4)
443
    assert_equal Time.utc(2005,3,21,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3)
444
    assert_equal Time.utc(2005,3,25,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.5)
J
Jeremy Kemper 已提交
445
    assert_in_delta Time.utc(2005,3,26,12,51,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
446
    assert_equal Time.utc(2005,3,5,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5)
447
    assert_equal Time.utc(2005,3,6,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.5)
J
Jeremy Kemper 已提交
448
    assert_in_delta Time.utc(2005,3,6,8,3,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.7), 1
449 450
    assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 7)
    assert_equal Time.utc(2013,10,3,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 19, :days => 11)
451
    assert_equal Time.utc(2013,10,17,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
452
    assert_equal Time.utc(2001,12,27,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:years => -3, :months => -2, :days => -1)
453
    assert_equal Time.utc(2005,2,28,15,15,10), Time.utc(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year
454 455 456 457 458
    assert_equal Time.utc(2005,2,28,20,15,10), Time.utc(2005,2,28,15,15,10).advance(:hours => 5)
    assert_equal Time.utc(2005,2,28,15,22,10), Time.utc(2005,2,28,15,15,10).advance(:minutes => 7)
    assert_equal Time.utc(2005,2,28,15,15,19), Time.utc(2005,2,28,15,15,10).advance(:seconds => 9)
    assert_equal Time.utc(2005,2,28,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:hours => 5, :minutes => 7, :seconds => 9)
    assert_equal Time.utc(2005,2,28,10,8,1), Time.utc(2005,2,28,15,15,10).advance(:hours => -5, :minutes => -7, :seconds => -9)
459
    assert_equal Time.utc(2013,10,17,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
460 461
  end

462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
  def test_offset_advance
    assert_equal Time.new(2006,2,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 1)
    assert_equal Time.new(2005,6,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:months => 4)
    assert_equal Time.new(2005,3,21,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3)
    assert_equal Time.new(2005,3,25,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.5)
    assert_in_delta Time.new(2005,3,26,12,51,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.7), 1
    assert_equal Time.new(2005,3,5,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5)
    assert_equal Time.new(2005,3,6,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.5)
    assert_in_delta Time.new(2005,3,6,8,3,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.7), 1
    assert_equal Time.new(2012,9,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 7)
    assert_equal Time.new(2013,10,3,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 19, :days => 11)
    assert_equal Time.new(2013,10,17,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
    assert_equal Time.new(2001,12,27,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => -3, :months => -2, :days => -1)
    assert_equal Time.new(2005,2,28,15,15,10,'-08:00'), Time.new(2004,2,29,15,15,10,'-08:00').advance(:years => 1) #leap day plus one year
    assert_equal Time.new(2005,2,28,20,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5)
    assert_equal Time.new(2005,2,28,15,22,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:minutes => 7)
    assert_equal Time.new(2005,2,28,15,15,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:seconds => 9)
    assert_equal Time.new(2005,2,28,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5, :minutes => 7, :seconds => 9)
    assert_equal Time.new(2005,2,28,10,8,1,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => -5, :minutes => -7, :seconds => -9)
    assert_equal Time.new(2013,10,17,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
  end

484 485 486 487 488
  def test_advance_with_nsec
    t = Time.at(0, Rational(108635108, 1000))
    assert_equal t, t.advance(:months => 0)
  end

489 490 491 492 493 494 495
  def test_advance_gregorian_proleptic
    assert_equal Time.local(1582,10,14,15,15,10), Time.local(1582,10,15,15,15,10).advance(:days => -1)
    assert_equal Time.local(1582,10,15,15,15,10), Time.local(1582,10,14,15,15,10).advance(:days => 1)
    assert_equal Time.local(1582,10,5,15,15,10), Time.local(1582,10,4,15,15,10).advance(:days => 1)
    assert_equal Time.local(1582,10,4,15,15,10), Time.local(1582,10,5,15,15,10).advance(:days => -1)
  end

496 497 498 499 500 501 502 503 504
  def test_last_week
    with_env_tz 'US/Eastern' do
      assert_equal Time.local(2005,2,21), Time.local(2005,3,1,15,15,10).last_week
      assert_equal Time.local(2005,2,22), Time.local(2005,3,1,15,15,10).last_week(:tuesday)
      assert_equal Time.local(2005,2,25), Time.local(2005,3,1,15,15,10).last_week(:friday)
      assert_equal Time.local(2006,10,30), Time.local(2006,11,6,0,0,0).last_week
      assert_equal Time.local(2006,11,15), Time.local(2006,11,23,0,0,0).last_week(:wednesday)
    end
  end
505

506
  def test_next_week_near_daylight_start
507
    with_env_tz 'US/Eastern' do
508 509
      assert_equal Time.local(2006,4,3), Time.local(2006,4,2,23,1,0).next_week, 'just crossed standard => daylight'
    end
510
    with_env_tz 'NZ' do
511 512
      assert_equal Time.local(2006,10,2), Time.local(2006,10,1,23,1,0).next_week, 'just crossed standard => daylight'
    end
513 514 515
  end

  def test_next_week_near_daylight_end
516
    with_env_tz 'US/Eastern' do
517 518
      assert_equal Time.local(2006,10,30), Time.local(2006,10,29,23,1,0).next_week, 'just crossed daylight => standard'
    end
519
    with_env_tz 'NZ' do
520 521
      assert_equal Time.local(2006,3,20), Time.local(2006,3,19,23,1,0).next_week, 'just crossed daylight => standard'
    end
522 523
  end

524
  def test_to_s
525
    time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901)
526 527
    assert_equal time.to_default_s,                 time.to_s
    assert_equal time.to_default_s,                 time.to_s(:doesnt_exist)
528 529 530
    assert_equal "2005-02-21 17:44:30",             time.to_s(:db)
    assert_equal "21 Feb 17:44",                    time.to_s(:short)
    assert_equal "17:44",                           time.to_s(:time)
531 532
    assert_equal "20050221174430",                  time.to_s(:number)
    assert_equal "20050221174430123456789",         time.to_s(:nsec)
533 534
    assert_equal "February 21, 2005 17:44",         time.to_s(:long)
    assert_equal "February 21st, 2005 17:44",       time.to_s(:long_ordinal)
535
    with_env_tz "UTC" do
536 537
      assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_s(:rfc822)
    end
538 539 540
    with_env_tz "US/Central" do
      assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822)
      assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822)
541 542 543
      assert_equal "2009-02-05T14:30:05-06:00", Time.local(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
      assert_equal "2008-06-09T04:05:01-05:00", Time.local(2008, 6, 9, 4, 5, 1).to_s(:iso8601)
      assert_equal "2009-02-05T14:30:05Z", Time.utc(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
544
    end
545
  end
546

547 548 549 550
  def test_custom_date_format
    Time::DATE_FORMATS[:custom] = '%Y%m%d%H%M%S'
    assert_equal '20050221143000', Time.local(2005, 2, 21, 14, 30, 0).to_s(:custom)
    Time::DATE_FORMATS.delete(:custom)
551
  end
552

553 554 555 556 557
  def test_to_date
    assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
  end

  def test_to_datetime
558
    assert_equal Time.utc(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, 0)
559
    with_env_tz 'US/Eastern' do
560
      assert_equal Time.local(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, Rational(Time.local(2005, 2, 21, 17, 44, 30).utc_offset, 86400))
561 562
    end
    with_env_tz 'NZ' do
563
      assert_equal Time.local(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, Rational(Time.local(2005, 2, 21, 17, 44, 30).utc_offset, 86400))
564 565
    end
    assert_equal ::Date::ITALY, Time.utc(2005, 2, 21, 17, 44, 30).to_datetime.start # use Ruby's default start value
566 567
  end

568
  def test_to_time
569 570 571 572 573
    with_env_tz 'US/Eastern' do
      assert_equal Time, Time.local(2005, 2, 21, 17, 44, 30).to_time.class
      assert_equal Time.local(2005, 2, 21, 17, 44, 30), Time.local(2005, 2, 21, 17, 44, 30).to_time
      assert_equal Time.local(2005, 2, 21, 17, 44, 30).utc_offset, Time.local(2005, 2, 21, 17, 44, 30).to_time.utc_offset
    end
574
  end
575 576 577 578 579 580 581

  # NOTE: this test seems to fail (changeset 1958) only on certain platforms,
  # like OSX, and FreeBSD 5.4.
  def test_fp_inaccuracy_ticket_1836
    midnight = Time.local(2005, 2, 21, 0, 0, 0)
    assert_equal midnight.midnight, (midnight + 1.hour + 0.000001).midnight
  end
582

583
  def test_days_in_month_with_year
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
    assert_equal 31, Time.days_in_month(1, 2005)

    assert_equal 28, Time.days_in_month(2, 2005)
    assert_equal 29, Time.days_in_month(2, 2004)
    assert_equal 29, Time.days_in_month(2, 2000)
    assert_equal 28, Time.days_in_month(2, 1900)

    assert_equal 31, Time.days_in_month(3, 2005)
    assert_equal 30, Time.days_in_month(4, 2005)
    assert_equal 31, Time.days_in_month(5, 2005)
    assert_equal 30, Time.days_in_month(6, 2005)
    assert_equal 31, Time.days_in_month(7, 2005)
    assert_equal 31, Time.days_in_month(8, 2005)
    assert_equal 30, Time.days_in_month(9, 2005)
    assert_equal 31, Time.days_in_month(10, 2005)
    assert_equal 30, Time.days_in_month(11, 2005)
    assert_equal 31, Time.days_in_month(12, 2005)
  end
602

603 604 605 606
  def test_days_in_month_feb_in_common_year_without_year_arg
    Time.stubs(:now).returns(Time.utc(2007))
    assert_equal 28, Time.days_in_month(2)
  end
607

608 609 610
  def test_days_in_month_feb_in_leap_year_without_year_arg
    Time.stubs(:now).returns(Time.utc(2008))
    assert_equal 29, Time.days_in_month(2)
611
  end
612

613 614 615 616
  def test_last_month_on_31st
    assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).last_month
  end

617 618 619
  def test_xmlschema_is_available
    assert_nothing_raised { Time.now.xmlschema }
  end
620

621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
  def test_today_with_time_local
    Date.stubs(:current).returns(Date.new(2000, 1, 1))
    assert_equal false, Time.local(1999,12,31,23,59,59).today?
    assert_equal true,  Time.local(2000,1,1,0).today?
    assert_equal true,  Time.local(2000,1,1,23,59,59).today?
    assert_equal false, Time.local(2000,1,2,0).today?
  end

  def test_today_with_time_utc
    Date.stubs(:current).returns(Date.new(2000, 1, 1))
    assert_equal false, Time.utc(1999,12,31,23,59,59).today?
    assert_equal true,  Time.utc(2000,1,1,0).today?
    assert_equal true,  Time.utc(2000,1,1,23,59,59).today?
    assert_equal false, Time.utc(2000,1,2,0).today?
  end

  def test_past_with_time_current_as_time_local
    with_env_tz 'US/Eastern' do
      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
      assert_equal true,  Time.local(2005,2,10,15,30,44).past?
      assert_equal false,  Time.local(2005,2,10,15,30,45).past?
      assert_equal false,  Time.local(2005,2,10,15,30,46).past?
      assert_equal true,  Time.utc(2005,2,10,20,30,44).past?
      assert_equal false,  Time.utc(2005,2,10,20,30,45).past?
      assert_equal false,  Time.utc(2005,2,10,20,30,46).past?
    end
  end

  def test_past_with_time_current_as_time_with_zone
    with_env_tz 'US/Eastern' do
      twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
      Time.stubs(:current).returns(twz)
      assert_equal true,  Time.local(2005,2,10,10,30,44).past?
      assert_equal false,  Time.local(2005,2,10,10,30,45).past?
      assert_equal false,  Time.local(2005,2,10,10,30,46).past?
      assert_equal true,  Time.utc(2005,2,10,15,30,44).past?
      assert_equal false,  Time.utc(2005,2,10,15,30,45).past?
      assert_equal false,  Time.utc(2005,2,10,15,30,46).past?
    end
  end

  def test_future_with_time_current_as_time_local
    with_env_tz 'US/Eastern' do
      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
      assert_equal false,  Time.local(2005,2,10,15,30,44).future?
      assert_equal false,  Time.local(2005,2,10,15,30,45).future?
      assert_equal true,  Time.local(2005,2,10,15,30,46).future?
      assert_equal false,  Time.utc(2005,2,10,20,30,44).future?
      assert_equal false,  Time.utc(2005,2,10,20,30,45).future?
      assert_equal true,  Time.utc(2005,2,10,20,30,46).future?
    end
  end

  def test_future_with_time_current_as_time_with_zone
    with_env_tz 'US/Eastern' do
      twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
      Time.stubs(:current).returns(twz)
      assert_equal false,  Time.local(2005,2,10,10,30,44).future?
      assert_equal false,  Time.local(2005,2,10,10,30,45).future?
      assert_equal true,  Time.local(2005,2,10,10,30,46).future?
      assert_equal false,  Time.utc(2005,2,10,15,30,44).future?
      assert_equal false,  Time.utc(2005,2,10,15,30,45).future?
      assert_equal true,  Time.utc(2005,2,10,15,30,46).future?
684 685 686
    end
  end

687 688
  def test_acts_like_time
    assert Time.new.acts_like_time?
689
  end
690

691 692 693 694 695
  def test_formatted_offset_with_utc
    assert_equal '+00:00', Time.utc(2000).formatted_offset
    assert_equal '+0000', Time.utc(2000).formatted_offset(false)
    assert_equal 'UTC', Time.utc(2000).formatted_offset(true, 'UTC')
  end
696

697
  def test_formatted_offset_with_local
698
    with_env_tz 'US/Eastern' do
699 700 701 702 703 704
      assert_equal '-05:00', Time.local(2000).formatted_offset
      assert_equal '-0500', Time.local(2000).formatted_offset(false)
      assert_equal '-04:00', Time.local(2000, 7).formatted_offset
      assert_equal '-0400', Time.local(2000, 7).formatted_offset(false)
    end
  end
705

706 707 708 709 710
  def test_compare_with_time
    assert_equal  1, Time.utc(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59, 999)
    assert_equal  0, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0)
    assert_equal(-1, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0, 001))
  end
711

712 713 714 715 716
  def test_compare_with_datetime
    assert_equal  1, Time.utc(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
    assert_equal  0, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
    assert_equal(-1, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
  end
717

718
  def test_compare_with_time_with_zone
719 720 721
    assert_equal  1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'] )
    assert_equal  0, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC'] )
    assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
722
  end
723

724 725 726 727 728 729 730 731 732 733 734
  def test_at_with_datetime
    assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0))

    # Only test this if the underlying Time.at raises a TypeError
    begin
      Time.at_without_coercion(Time.now, 0)
    rescue TypeError
      assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) }
    end
  end

735
  def test_at_with_datetime_returns_local_time
736
    with_env_tz 'US/Eastern' do
737 738 739 740 741 742 743 744 745 746
      dt = DateTime.civil(2000, 1, 1, 0, 0, 0, '+0')
      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(dt)
      assert_equal 'EST', Time.at(dt).zone
      assert_equal(-18000, Time.at(dt).utc_offset)

      # Daylight savings
      dt = DateTime.civil(2000, 7, 1, 1, 0, 0, '+1')
      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(dt)
      assert_equal 'EDT', Time.at(dt).zone
      assert_equal(-14400, Time.at(dt).utc_offset)
747 748 749
    end
  end

750 751 752 753 754 755 756 757 758 759 760
  def test_at_with_time_with_zone
    assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']))

    # Only test this if the underlying Time.at raises a TypeError
    begin
      Time.at_without_coercion(Time.now, 0)
    rescue TypeError
      assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']), 0)) }
    end
  end

761
  def test_at_with_time_with_zone_returns_local_time
762
    with_env_tz 'US/Eastern' do
763 764 765 766 767 768 769 770 771 772
      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['London'])
      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(twz)
      assert_equal 'EST', Time.at(twz).zone
      assert_equal(-18000, Time.at(twz).utc_offset)

      # Daylight savings
      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 7, 1, 0, 0, 0), ActiveSupport::TimeZone['London'])
      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(twz)
      assert_equal 'EDT', Time.at(twz).zone
      assert_equal(-14400, Time.at(twz).utc_offset)
773 774 775
    end
  end

776 777 778 779
  def test_at_with_time_microsecond_precision
    assert_equal Time.at(Time.utc(2000, 1, 1, 0, 0, 0, 111)).to_f, Time.utc(2000, 1, 1, 0, 0, 0, 111).to_f
  end

780 781 782 783
  def test_at_with_utc_time
    with_env_tz 'US/Eastern' do
      assert_equal Time.utc(2000), Time.at(Time.utc(2000))
      assert_equal 'UTC', Time.at(Time.utc(2000)).zone
784
      assert_equal(0, Time.at(Time.utc(2000)).utc_offset)
785 786 787 788 789 790 791
    end
  end

  def test_at_with_local_time
    with_env_tz 'US/Eastern' do
      assert_equal Time.local(2000), Time.at(Time.local(2000))
      assert_equal 'EST', Time.at(Time.local(2000)).zone
792
      assert_equal(-18000, Time.at(Time.local(2000)).utc_offset)
793 794 795

      assert_equal Time.local(2000, 7, 1), Time.at(Time.local(2000, 7, 1))
      assert_equal 'EDT', Time.at(Time.local(2000, 7, 1)).zone
796
      assert_equal(-14400, Time.at(Time.local(2000, 7, 1)).utc_offset)
797 798 799
    end
  end

800 801 802 803 804 805
  def test_eql?
    assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
    assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
    assert_equal false,Time.utc(2000, 1, 1, 0, 0, 1).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
  end

806
  def test_minus_with_time_with_zone
807
    assert_equal  86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
808
  end
809

810 811 812
  def test_minus_with_datetime
    assert_equal  86_400.0, Time.utc(2000, 1, 2) - DateTime.civil(2000, 1, 1)
  end
813

814 815 816 817 818 819 820 821 822
  def test_time_created_with_local_constructor_cannot_represent_times_during_hour_skipped_by_dst
    with_env_tz 'US/Eastern' do
      # On Apr 2 2006 at 2:00AM in US, clocks were moved forward to 3:00AM.
      # Therefore, 2AM EST doesn't exist for this date; Time.local fails over to 3:00AM EDT
      assert_equal Time.local(2006, 4, 2, 3), Time.local(2006, 4, 2, 2)
      assert Time.local(2006, 4, 2, 2).dst?
    end
  end

823 824
  def test_case_equality
    assert Time === Time.utc(2000)
825
    assert Time === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC'])
J
Jeremy Evans 已提交
826
    assert Time === Class.new(Time).utc(2000)
827
    assert_equal false, Time === DateTime.civil(2000)
J
Jeremy Evans 已提交
828 829
    assert_equal false, Class.new(Time) === Time.utc(2000)
    assert_equal false, Class.new(Time) === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC'])
830 831
  end

832
  def test_all_day
833
    assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_day
834 835
  end

836 837
  def test_all_day_with_timezone
    beginning_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,0,0,0))
838
    end_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)))
839

840 841
    assert_equal beginning_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.begin
    assert_equal end_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.end
842 843
  end

844
  def test_all_week
845 846
    assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week
    assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week(:sunday)
847 848
  end

849
  def test_all_month
850
    assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_month
851 852
  end

853
  def test_all_quarter
854
    assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_quarter
855 856
  end

857
  def test_all_year
858
    assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_year
859
  end
860
end
861

862
class TimeExtMarshalingTest < ActiveSupport::TestCase
863 864
  def test_marshaling_with_utc_instance
    t = Time.utc(2000)
865
    unmarshaled = Marshal.load(Marshal.dump(t))
866
    assert_equal "UTC", unmarshaled.zone
867
    assert_equal t, unmarshaled
868
  end
869 870

  def test_marshaling_with_local_instance
871
    t = Time.local(2000)
872
    unmarshaled = Marshal.load(Marshal.dump(t))
873
    assert_equal t.zone, unmarshaled.zone
874
    assert_equal t, unmarshaled
875
  end
876 877

  def test_marshaling_with_frozen_utc_instance
878
    t = Time.utc(2000).freeze
879
    unmarshaled = Marshal.load(Marshal.dump(t))
880
    assert_equal "UTC", unmarshaled.zone
881
    assert_equal t, unmarshaled
882
  end
883 884

  def test_marshaling_with_frozen_local_instance
885
    t = Time.local(2000).freeze
886
    unmarshaled = Marshal.load(Marshal.dump(t))
887
    assert_equal t.zone, unmarshaled.zone
888
    assert_equal t, unmarshaled
889
  end
890 891 892 893 894 895 896

  def test_marshalling_preserves_fractional_seconds
    t = Time.parse('00:00:00.500')
    unmarshaled = Marshal.load(Marshal.dump(t))
    assert_equal t.to_f, unmarshaled.to_f
    assert_equal t, unmarshaled
  end
897 898 899 900

  def test_last_quarter_on_31st
    assert_equal Time.local(2004, 2, 29), Time.local(2004, 5, 31).last_quarter
  end
901
end