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

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

  include DateAndTimeBehavior
12
  include TimeZoneTestHelpers
13

14
  def test_seconds_since_midnight
15 16 17 18 19
    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
20 21
  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
      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"
27 28
    end

29
    with_env_tz "NZ" do
30
      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
31 32
      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 41
      assert_equal 1 * 3600 - 1, Time.local(2005, 10, 30, 0, 59, 59).seconds_since_midnight, "just before DST end"
      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
      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"
47 48
    end

49
    with_env_tz "NZ" do
50 51
      # 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
52 53
      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"
54 55 56

      # 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 )
57 58
      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
  def test_seconds_until_end_of_day
63 64 65 66 67
    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
68 69 70
  end

  def test_seconds_until_end_of_day_at_daylight_savings_time_start
71
    with_env_tz "US/Eastern" do
72
      # dt: US: 2005 April 3rd 2:00am ST => April 3rd 3:00am DT
73 74
      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"
75 76
    end

77
    with_env_tz "NZ" do
78
      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
79 80
      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"
81 82 83 84
    end
  end

  def test_seconds_until_end_of_day_at_daylight_savings_time_end
85
    with_env_tz "US/Eastern" do
86 87
      # 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
88 89
      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"
90 91 92

      # 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 )
93 94
      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"
95 96
    end

97
    with_env_tz "NZ" do
98 99
      # 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
100 101
      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"
102 103 104

      # 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 )
105 106
      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"
107 108 109
    end
  end

110
  def test_sec_fraction
111 112
    time = Time.utc(2016, 4, 23, 0, 0, Rational(1, 10000000000))
    assert_equal Rational(1, 10000000000), time.sec_fraction
113 114 115 116

    time = Time.utc(2016, 4, 23, 0, 0, 0.0000000001)
    assert_equal 0.0000000001.to_r, time.sec_fraction

117 118
    time = Time.utc(2016, 4, 23, 0, 0, 0, Rational(1, 10000))
    assert_equal Rational(1, 10000000000), time.sec_fraction
119 120 121 122 123

    time = Time.utc(2016, 4, 23, 0, 0, 0, 0.0001)
    assert_equal 0.0001.to_r / 1000000, time.sec_fraction
  end

124
  def test_beginning_of_day
125
    assert_equal Time.local(2005, 2, 4, 0, 0, 0), Time.local(2005, 2, 4, 10, 10, 10).beginning_of_day
126
    with_env_tz "US/Eastern" do
127 128
      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"
129
    end
130
    with_env_tz "NZ" do
131 132
      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"
133
    end
134
  end
135

A
Anatoli Makarevich 已提交
136
  def test_middle_of_day
137
    assert_equal Time.local(2005, 2, 4, 12, 0, 0), Time.local(2005, 2, 4, 10, 10, 10).middle_of_day
138
    with_env_tz "US/Eastern" do
139 140
      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"
A
Anatoli Makarevich 已提交
141
    end
142
    with_env_tz "NZ" do
143 144
      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"
A
Anatoli Makarevich 已提交
145 146 147
    end
  end

148
  def test_beginning_of_hour
149
    assert_equal Time.local(2005, 2, 4, 19, 0, 0), Time.local(2005, 2, 4, 19, 30, 10).beginning_of_hour
150 151
  end

152
  def test_beginning_of_minute
153
    assert_equal Time.local(2005, 2, 4, 19, 30, 0), Time.local(2005, 2, 4, 19, 30, 10).beginning_of_minute
154 155
  end

156
  def test_end_of_day
157
    assert_equal Time.local(2007, 8, 12, 23, 59, 59, Rational(999999999, 1000)), Time.local(2007, 8, 12, 10, 10, 10).end_of_day
158
    with_env_tz "US/Eastern" do
159 160
      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"
161
    end
162
    with_env_tz "NZ" do
163 164
      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"
165
    end
166 167
    with_env_tz "Asia/Yekaterinburg" do
      assert_equal Time.local(2015, 2, 8, 23, 59, 59, Rational(999999999, 1000)), Time.new(2015, 2, 8, 8, 0, 0, "+05:00").end_of_day
168
    end
169 170
  end

171
  def test_end_of_hour
172
    assert_equal Time.local(2005, 2, 4, 19, 59, 59, Rational(999999999, 1000)), Time.local(2005, 2, 4, 19, 30, 10).end_of_hour
173 174
  end

175
  def test_end_of_minute
176
    assert_equal Time.local(2005, 2, 4, 19, 30, 59, Rational(999999999, 1000)), Time.local(2005, 2, 4, 19, 30, 10).end_of_minute
177 178
  end

179
  def test_last_year
180
    assert_equal Time.local(2004, 6, 5, 10),  Time.local(2005, 6, 5, 10, 0, 0).last_year
181 182
  end

183
  def test_ago
184 185 186 187
    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)
188 189
  end

190
  def test_daylight_savings_time_crossings_backward_start
191
    with_env_tz "US/Eastern" do
192
      # dt: US: 2005 April 3rd 4:18am
193 194 195
      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"
196

197 198 199
      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"
200
    end
201
    with_env_tz "NZ" do
202
      # dt: New Zealand: 2006 October 1st 4:18am
203 204 205
      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"
      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"
206

207 208 209
      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"
      assert_equal Time.local(2006, 9, 29, 4, 18, 0), Time.local(2006, 9, 30, 4, 18, 0).ago(86400), "st-86400=>st"
      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"
210
    end
211 212 213
  end

  def test_daylight_savings_time_crossings_backward_end
214
    with_env_tz "US/Eastern" do
215
      # st: US: 2005 October 30th 4:03am
216 217 218
      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"
219

220 221 222
      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"
223
    end
224
    with_env_tz "NZ" do
225
      # st: New Zealand: 2006 March 19th 4:03am
226 227 228
      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"
229

230 231 232
      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"
233
    end
234 235
  end

236
  def test_daylight_savings_time_crossings_backward_start_1day
237
    with_env_tz "US/Eastern" do
238
      # dt: US: 2005 April 3rd 4:18am
239 240
      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"
241
    end
242
    with_env_tz "NZ" do
243
      # dt: New Zealand: 2006 October 1st 4:18am
244 245
      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"
246 247 248 249
    end
  end

  def test_daylight_savings_time_crossings_backward_end_1day
250
    with_env_tz "US/Eastern" do
251
      # st: US: 2005 October 30th 4:03am
252 253
      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"
254
    end
255
    with_env_tz "NZ" do
256
      # st: New Zealand: 2006 March 19th 4:03am
257 258
      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"
259 260
    end
  end
261

262
  def test_since
263 264 265 266
    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)
267
    # when out of range of Time, returns a DateTime
268
    assert_equal DateTime.civil(2038, 1, 20, 11, 59, 59), Time.utc(2038, 1, 18, 11, 59, 59).since(86400 * 2)
269 270
  end

271
  def test_daylight_savings_time_crossings_forward_start
272
    with_env_tz "US/Eastern" do
273
      # st: US: 2005 April 2nd 7:27pm
274 275 276
      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"
277

278 279 280
      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"
      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"
281
    end
282
    with_env_tz "NZ" do
283
      # st: New Zealand: 2006 September 30th 7:27pm
284 285 286
      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"
287

288 289 290
      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"
291
    end
292 293
  end

294
  def test_daylight_savings_time_crossings_forward_start_1day
295
    with_env_tz "US/Eastern" do
296
      # st: US: 2005 April 2nd 7:27pm
297 298
      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"
299
    end
300
    with_env_tz "NZ" do
301
      # st: New Zealand: 2006 September 30th 7:27pm
302 303
      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"
304 305 306
    end
  end

307
  def test_daylight_savings_time_crossings_forward_start_tomorrow
308
    with_env_tz "US/Eastern" do
309
      # st: US: 2005 April 2nd 7:27pm
310 311
      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"
312
    end
313
    with_env_tz "NZ" do
314
      # st: New Zealand: 2006 September 30th 7:27pm
315 316
      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"
317 318 319
    end
  end

320
  def test_daylight_savings_time_crossings_backward_start_yesterday
321
    with_env_tz "US/Eastern" do
322
      # st: US: 2005 April 2nd 7:27pm
323 324
      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"
325
    end
326
    with_env_tz "NZ" do
327
      # st: New Zealand: 2006 September 30th 7:27pm
328 329
      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"
330 331 332
    end
  end

333
  def test_daylight_savings_time_crossings_forward_end
334
    with_env_tz "US/Eastern" do
335
      # dt: US: 2005 October 30th 12:45am
336 337 338
      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"
339

340 341 342
      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"
343
    end
344
    with_env_tz "NZ" do
345
      # dt: New Zealand: 2006 March 19th 1:45am
346 347 348
      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"
349

350 351 352
      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"
353
    end
354 355
  end

356
  def test_daylight_savings_time_crossings_forward_end_1day
357
    with_env_tz "US/Eastern" do
358
      # dt: US: 2005 October 30th 12:45am
359 360
      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"
361
    end
362
    with_env_tz "NZ" do
363
      # dt: New Zealand: 2006 March 19th 1:45am
364 365
      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"
366 367 368
    end
  end

369
  def test_daylight_savings_time_crossings_forward_end_tomorrow
370
    with_env_tz "US/Eastern" do
371
      # dt: US: 2005 October 30th 12:45am
372 373
      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"
374
    end
375
    with_env_tz "NZ" do
376
      # dt: New Zealand: 2006 March 19th 1:45am
377 378
      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"
379 380 381
    end
  end

382
  def test_daylight_savings_time_crossings_backward_end_yesterday
383
    with_env_tz "US/Eastern" do
384
      # dt: US: 2005 October 30th 12:45am
385 386
      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"
387
    end
388
    with_env_tz "NZ" do
389
      # dt: New Zealand: 2006 March 19th 1:45am
390 391
      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"
392 393 394
    end
  end

395
  def test_change
396 397 398 399 400 401 402 403 404 405 406 407 408
    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)
    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)

    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)
    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) }
409
    assert_nothing_raised { Time.new(2015, 5, 9, 10, 00, 00, "+03:00").change(nsec: 999999999) }
D
David Heinemeier Hansson 已提交
410
  end
411

D
David Heinemeier Hansson 已提交
412
  def test_utc_change
413 414 415 416 417 418 419
    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)
    assert_equal Time.utc(2005, 1, 2, 11, 22, 33, 8), Time.utc(2005, 1, 2, 11, 22, 33, 2).change(nsec: 8000)
420
  end
421

422
  def test_offset_change
423 424 425 426 427 428 429 430 431
    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)
    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
432 433
    assert_raise(ArgumentError) { Time.new(2005, 2, 22, 15, 15, 45, "-08:00").change(usec: 1000000) }
    assert_raise(ArgumentError) { Time.new(2005, 2, 22, 15, 15, 45, "-08:00").change(nsec: 1000000000) }
434 435
  end

436
  def test_advance
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
    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)
    assert_equal Time.local(2005, 3, 21, 15, 15, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(weeks: 3)
    assert_equal Time.local(2005, 3, 25, 3, 15, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(weeks: 3.5)
    assert_in_delta Time.local(2005, 3, 26, 12, 51, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(weeks: 3.7), 1
    assert_equal Time.local(2005, 3, 5, 15, 15, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(days: 5)
    assert_equal Time.local(2005, 3, 6, 3, 15, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(days: 5.5)
    assert_in_delta Time.local(2005, 3, 6, 8, 3, 10), Time.local(2005, 2, 28, 15, 15, 10).advance(days: 5.7), 1
    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)
    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)
    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)
    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
    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)
    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)
456
  end
457

458
  def test_utc_advance
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
    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)
    assert_equal Time.utc(2005, 3, 21, 15, 15, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(weeks: 3)
    assert_equal Time.utc(2005, 3, 25, 3, 15, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(weeks: 3.5)
    assert_in_delta Time.utc(2005, 3, 26, 12, 51, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(weeks: 3.7), 1
    assert_equal Time.utc(2005, 3, 5, 15, 15, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(days: 5)
    assert_equal Time.utc(2005, 3, 6, 3, 15, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(days: 5.5)
    assert_in_delta Time.utc(2005, 3, 6, 8, 3, 10), Time.utc(2005, 2, 28, 15, 15, 10).advance(days: 5.7), 1
    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)
    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)
    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)
    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
    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)
    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)
478 479
  end

480
  def test_offset_advance
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
    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)
500 501
  end

502 503
  def test_advance_with_nsec
    t = Time.at(0, Rational(108635108, 1000))
504
    assert_equal t, t.advance(months: 0)
505 506
  end

507
  def test_advance_gregorian_proleptic
508 509 510 511
    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)
512 513
  end

514
  def test_last_week
515
    with_env_tz "US/Eastern" do
516 517 518 519 520
      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)
521 522
    end
  end
523

524
  def test_next_week_near_daylight_start
525
    with_env_tz "US/Eastern" do
526
      assert_equal Time.local(2006, 4, 3), Time.local(2006, 4, 2, 23, 1, 0).next_week, "just crossed standard => daylight"
527
    end
528
    with_env_tz "NZ" do
529
      assert_equal Time.local(2006, 10, 2), Time.local(2006, 10, 1, 23, 1, 0).next_week, "just crossed standard => daylight"
530
    end
531 532 533
  end

  def test_next_week_near_daylight_end
534
    with_env_tz "US/Eastern" do
535
      assert_equal Time.local(2006, 10, 30), Time.local(2006, 10, 29, 23, 1, 0).next_week, "just crossed daylight => standard"
536
    end
537
    with_env_tz "NZ" do
538
      assert_equal Time.local(2006, 3, 20), Time.local(2006, 3, 19, 23, 1, 0).next_week, "just crossed daylight => standard"
539
    end
540 541
  end

542
  def test_to_s
543
    time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901)
544 545
    assert_equal time.to_default_s,                 time.to_s
    assert_equal time.to_default_s,                 time.to_s(:doesnt_exist)
546 547 548
    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)
549 550
    assert_equal "20050221174430",                  time.to_s(:number)
    assert_equal "20050221174430123456789",         time.to_s(:nsec)
M
Maarten Jacobs 已提交
551
    assert_equal "20050221174430123456",            time.to_s(:usec)
552 553
    assert_equal "February 21, 2005 17:44",         time.to_s(:long)
    assert_equal "February 21st, 2005 17:44",       time.to_s(:long_ordinal)
554
    with_env_tz "UTC" do
555 556
      assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_s(:rfc822)
    end
557 558 559
    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)
560 561 562
      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)
563
    end
564
  end
565

566
  def test_custom_date_format
567 568
    Time::DATE_FORMATS[:custom] = "%Y%m%d%H%M%S"
    assert_equal "20050221143000", Time.local(2005, 2, 21, 14, 30, 0).to_s(:custom)
569
    Time::DATE_FORMATS.delete(:custom)
570
  end
571

572 573 574 575 576
  def test_rfc3339_with_fractional_seconds
    time = Time.new(1999, 12, 31, 19, 0, Rational(1, 8), -18000)
    assert_equal "1999-12-31T19:00:00.125-05:00", time.rfc3339(3)
  end

577 578 579 580 581
  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
582
    assert_equal Time.utc(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, 0)
583
    with_env_tz "US/Eastern" do
584
      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))
585
    end
586
    with_env_tz "NZ" do
587
      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))
588 589
    end
    assert_equal ::Date::ITALY, Time.utc(2005, 2, 21, 17, 44, 30).to_datetime.start # use Ruby's default start value
590 591
  end

592
  def test_to_time
593
    with_env_tz "US/Eastern" do
594 595 596 597
      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
598
  end
599 600 601 602 603 604 605

  # 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
606

607
  def test_days_in_month_with_year
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    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
626

627
  def test_days_in_month_feb_in_common_year_without_year_arg
628 629 630
    Time.stub(:now, Time.utc(2007)) do
      assert_equal 28, Time.days_in_month(2)
    end
631
  end
632

633
  def test_days_in_month_feb_in_leap_year_without_year_arg
634 635 636
    Time.stub(:now, Time.utc(2008)) do
      assert_equal 29, Time.days_in_month(2)
    end
637
  end
638

J
Jon Pascoe 已提交
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
  def test_days_in_year_with_year
    assert_equal 365, Time.days_in_year(2005)
    assert_equal 366, Time.days_in_year(2004)
    assert_equal 366, Time.days_in_year(2000)
    assert_equal 365, Time.days_in_year(1900)
  end

  def test_days_in_year_in_common_year_without_year_arg
    Time.stub(:now, Time.utc(2007)) do
      assert_equal 365, Time.days_in_year
    end
  end

  def test_days_in_year_in_leap_year_without_year_arg
    Time.stub(:now, Time.utc(2008)) do
      assert_equal 366, Time.days_in_year
    end
  end

658 659 660 661
  def test_last_month_on_31st
    assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).last_month
  end

662 663 664
  def test_xmlschema_is_available
    assert_nothing_raised { Time.now.xmlschema }
  end
665

666
  def test_today_with_time_local
667
    Date.stub(:current, Date.new(2000, 1, 1)) do
668 669 670 671
      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?
672
    end
673 674 675
  end

  def test_today_with_time_utc
676
    Date.stub(:current, Date.new(2000, 1, 1)) do
677 678 679 680
      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?
681
    end
682 683 684
  end

  def test_past_with_time_current_as_time_local
685
    with_env_tz "US/Eastern" do
686 687 688 689 690 691 692
      Time.stub(:current, Time.local(2005, 2, 10, 15, 30, 45)) do
        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?
693
      end
694 695 696 697
    end
  end

  def test_past_with_time_current_as_time_with_zone
698
    with_env_tz "US/Eastern" do
699
      twz = Time.utc(2005, 2, 10, 15, 30, 45).in_time_zone("Central Time (US & Canada)")
700
      Time.stub(:current, twz) do
701 702 703 704 705 706
        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?
707
      end
708 709 710 711
    end
  end

  def test_future_with_time_current_as_time_local
712
    with_env_tz "US/Eastern" do
713 714 715 716 717 718 719
      Time.stub(:current, Time.local(2005, 2, 10, 15, 30, 45)) do
        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?
720
      end
721 722 723 724
    end
  end

  def test_future_with_time_current_as_time_with_zone
725
    with_env_tz "US/Eastern" do
726
      twz = Time.utc(2005, 2, 10, 15, 30, 45).in_time_zone("Central Time (US & Canada)")
727
      Time.stub(:current, twz) do
728 729 730 731 732 733
        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?
734
      end
735 736 737
    end
  end

738 739
  def test_acts_like_time
    assert Time.new.acts_like_time?
740
  end
741

742
  def test_formatted_offset_with_utc
743 744 745
    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")
746
  end
747

748
  def test_formatted_offset_with_local
749 750 751 752 753
    with_env_tz "US/Eastern" do
      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)
754 755
    end
  end
756

757 758 759 760 761
  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
762

763 764 765 766 767
  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
768

769
  def test_compare_with_time_with_zone
770 771 772
    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"]))
773
  end
774

775 776 777
  def test_compare_with_string
    assert_equal   1, Time.utc(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59, 999).to_s
    assert_equal   0, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0).to_s
778
    assert_equal(-1, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 1, 0).to_s)
779
    assert_nil Time.utc(2000) <=> "Invalid as Time"
780 781
  end

782 783 784 785 786 787 788 789 790 791 792
  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

793
  def test_at_with_datetime_returns_local_time
794 795
    with_env_tz "US/Eastern" do
      dt = DateTime.civil(2000, 1, 1, 0, 0, 0, "+0")
796
      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(dt)
797
      assert_equal "EST", Time.at(dt).zone
798 799 800
      assert_equal(-18000, Time.at(dt).utc_offset)

      # Daylight savings
801
      dt = DateTime.civil(2000, 7, 1, 1, 0, 0, "+1")
802
      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(dt)
803
      assert_equal "EDT", Time.at(dt).zone
804
      assert_equal(-14400, Time.at(dt).utc_offset)
805 806 807
    end
  end

808
  def test_at_with_time_with_zone
809
    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"]))
810 811 812 813 814

    # Only test this if the underlying Time.at raises a TypeError
    begin
      Time.at_without_coercion(Time.now, 0)
    rescue TypeError
815
      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)) }
816 817 818
    end
  end

819
  def test_at_with_time_with_zone_returns_local_time
820 821
    with_env_tz "US/Eastern" do
      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone["London"])
822
      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(twz)
823
      assert_equal "EST", Time.at(twz).zone
824 825 826
      assert_equal(-18000, Time.at(twz).utc_offset)

      # Daylight savings
827
      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 7, 1, 0, 0, 0), ActiveSupport::TimeZone["London"])
828
      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(twz)
829
      assert_equal "EDT", Time.at(twz).zone
830
      assert_equal(-14400, Time.at(twz).utc_offset)
831 832 833
    end
  end

834 835 836 837
  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

838
  def test_at_with_utc_time
839
    with_env_tz "US/Eastern" do
840
      assert_equal Time.utc(2000), Time.at(Time.utc(2000))
841
      assert_equal "UTC", Time.at(Time.utc(2000)).zone
842
      assert_equal(0, Time.at(Time.utc(2000)).utc_offset)
843 844 845 846
    end
  end

  def test_at_with_local_time
847
    with_env_tz "US/Eastern" do
848
      assert_equal Time.local(2000), Time.at(Time.local(2000))
849
      assert_equal "EST", Time.at(Time.local(2000)).zone
850
      assert_equal(-18000, Time.at(Time.local(2000)).utc_offset)
851 852

      assert_equal Time.local(2000, 7, 1), Time.at(Time.local(2000, 7, 1))
853
      assert_equal "EDT", Time.at(Time.local(2000, 7, 1)).zone
854
      assert_equal(-14400, Time.at(Time.local(2000, 7, 1)).utc_offset)
855 856 857
    end
  end

858
  def test_eql?
859 860 861
    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"]))
862 863
  end

864
  def test_minus_with_time_with_zone
865
    assert_equal  86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone["UTC"])
866
  end
867

868 869 870
  def test_minus_with_datetime
    assert_equal  86_400.0, Time.utc(2000, 1, 2) - DateTime.civil(2000, 1, 1)
  end
871

872
  def test_time_created_with_local_constructor_cannot_represent_times_during_hour_skipped_by_dst
873
    with_env_tz "US/Eastern" do
874 875 876 877 878 879 880
      # 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

881 882
  def test_case_equality
    assert Time === Time.utc(2000)
883
    assert Time === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["UTC"])
J
Jeremy Evans 已提交
884
    assert Time === Class.new(Time).utc(2000)
885
    assert_equal false, Time === DateTime.civil(2000)
J
Jeremy Evans 已提交
886
    assert_equal false, Class.new(Time) === Time.utc(2000)
887
    assert_equal false, Class.new(Time) === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["UTC"])
888 889
  end

890
  def test_all_day
891
    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
892 893
  end

894
  def test_all_day_with_timezone
895 896
    beginning_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011, 6, 7, 0, 0, 0))
    end_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011, 6, 7, 23, 59, 59, Rational(999999999, 1000)))
897

898 899
    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
900 901
  end

902
  def test_all_week
903 904
    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)
905 906
  end

907
  def test_all_month
908
    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
909 910
  end

911
  def test_all_quarter
912
    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
913 914
  end

915
  def test_all_year
916
    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
917
  end
A
Andrew White 已提交
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948

  def test_rfc3339_parse
    time = Time.rfc3339("1999-12-31T19:00:00.125-05:00")

    assert_equal 1999, time.year
    assert_equal 12, time.month
    assert_equal 31, time.day
    assert_equal 19, time.hour
    assert_equal 0, time.min
    assert_equal 0, time.sec
    assert_equal 125000, time.usec
    assert_equal(-18000, time.utc_offset)

    exception = assert_raises(ArgumentError) do
      Time.rfc3339("1999-12-31")
    end

    assert_equal "invalid date", exception.message

    exception = assert_raises(ArgumentError) do
      Time.rfc3339("1999-12-31T19:00:00")
    end

    assert_equal "invalid date", exception.message

    exception = assert_raises(ArgumentError) do
      Time.rfc3339("foobar")
    end

    assert_equal "invalid date", exception.message
  end
949
end
950

951
class TimeExtMarshalingTest < ActiveSupport::TestCase
952 953
  def test_marshaling_with_utc_instance
    t = Time.utc(2000)
954
    unmarshaled = Marshal.load(Marshal.dump(t))
955
    assert_equal "UTC", unmarshaled.zone
956
    assert_equal t, unmarshaled
957
  end
958 959

  def test_marshaling_with_local_instance
960
    t = Time.local(2000)
961
    unmarshaled = Marshal.load(Marshal.dump(t))
962
    assert_equal t.zone, unmarshaled.zone
963
    assert_equal t, unmarshaled
964
  end
965 966

  def test_marshaling_with_frozen_utc_instance
967
    t = Time.utc(2000).freeze
968
    unmarshaled = Marshal.load(Marshal.dump(t))
969
    assert_equal "UTC", unmarshaled.zone
970
    assert_equal t, unmarshaled
971
  end
972 973

  def test_marshaling_with_frozen_local_instance
974
    t = Time.local(2000).freeze
975
    unmarshaled = Marshal.load(Marshal.dump(t))
976
    assert_equal t.zone, unmarshaled.zone
977
    assert_equal t, unmarshaled
978
  end
979 980

  def test_marshalling_preserves_fractional_seconds
981
    t = Time.parse("00:00:00.500")
982 983 984 985
    unmarshaled = Marshal.load(Marshal.dump(t))
    assert_equal t.to_f, unmarshaled.to_f
    assert_equal t, unmarshaled
  end
986 987 988 989

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