mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Update DateTime#change
to support usec and nsec
Adding support for these options now allows us to update the `DateTime#end_of` methods to match the equivalent `Time#end_of` methods, e.g: datetime = DateTime.now.end_of_day datetime.nsec == 999999999 # => true Fixes #21424.
This commit is contained in:
parent
b61a56541a
commit
b5af751508
4 changed files with 46 additions and 17 deletions
|
@ -52,7 +52,7 @@ class DateTimeTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_assign_in_local_timezone
|
||||
now = DateTime.now
|
||||
now = DateTime.civil(2017, 3, 1, 12, 0, 0)
|
||||
with_timezone_config default: :local do
|
||||
task = Task.new starting: now
|
||||
assert_equal now, task.starting
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
* Update `DateTime#change` to support `:usec` and `:nsec` options.
|
||||
|
||||
Adding support for these options now allows us to update the `DateTime#end_of`
|
||||
methods to match the equivalent `Time#end_of` methods, e.g:
|
||||
|
||||
datetime = DateTime.now.end_of_day
|
||||
datetime.nsec == 999999999 # => true
|
||||
|
||||
Fixes #21424.
|
||||
|
||||
*Dan Moore*, *Andrew White*
|
||||
|
||||
* Add `ActiveSupport::Duration#before` and `#after` as aliases for `#until` and `#since`
|
||||
|
||||
These read more like English and require less mental gymnastics to read and write.
|
||||
|
@ -20,7 +32,7 @@
|
|||
*Robin Dupret* (#28157)
|
||||
|
||||
* In Core Extensions, make `MarshalWithAutoloading#load` pass through the second, optional
|
||||
argument for `Marshal#load( source [, proc] )`. This way we don't have to do
|
||||
argument for `Marshal#load( source [, proc] )`. This way we don't have to do
|
||||
`Marshal.method(:load).super_method.call(source, proc)` just to be able to pass a proc.
|
||||
|
||||
*Jeff Latz*
|
||||
|
|
|
@ -47,13 +47,23 @@ class DateTime
|
|||
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
|
||||
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
|
||||
def change(options)
|
||||
if new_nsec = options[:nsec]
|
||||
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
||||
new_fraction = Rational(new_nsec, 1000000000)
|
||||
else
|
||||
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
||||
new_fraction = Rational(new_usec, 1000000)
|
||||
end
|
||||
|
||||
raise ArgumentError, "argument out of range" if new_fraction >= 1
|
||||
|
||||
::DateTime.civil(
|
||||
options.fetch(:year, year),
|
||||
options.fetch(:month, month),
|
||||
options.fetch(:day, day),
|
||||
options.fetch(:hour, hour),
|
||||
options.fetch(:min, options[:hour] ? 0 : min),
|
||||
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
|
||||
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction,
|
||||
options.fetch(:offset, offset),
|
||||
options.fetch(:start, start)
|
||||
)
|
||||
|
@ -122,7 +132,7 @@ class DateTime
|
|||
|
||||
# Returns a new DateTime representing the end of the day (23:59:59).
|
||||
def end_of_day
|
||||
change(hour: 23, min: 59, sec: 59)
|
||||
change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
|
||||
end
|
||||
alias :at_end_of_day :end_of_day
|
||||
|
||||
|
@ -134,7 +144,7 @@ class DateTime
|
|||
|
||||
# Returns a new DateTime representing the end of the hour (hh:59:59).
|
||||
def end_of_hour
|
||||
change(min: 59, sec: 59)
|
||||
change(min: 59, sec: 59, usec: Rational(999999999, 1000))
|
||||
end
|
||||
alias :at_end_of_hour :end_of_hour
|
||||
|
||||
|
@ -146,7 +156,7 @@ class DateTime
|
|||
|
||||
# Returns a new DateTime representing the end of the minute (hh:mm:59).
|
||||
def end_of_minute
|
||||
change(sec: 59)
|
||||
change(sec: 59, usec: Rational(999999999, 1000))
|
||||
end
|
||||
alias :at_end_of_minute :end_of_minute
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ require "core_ext/date_and_time_behavior"
|
|||
require "time_zone_test_helpers"
|
||||
|
||||
class DateTimeExtCalculationsTest < ActiveSupport::TestCase
|
||||
def date_time_init(year, month, day, hour, minute, second, *args)
|
||||
DateTime.civil(year, month, day, hour, minute, second)
|
||||
def date_time_init(year, month, day, hour, minute, second, usec = 0)
|
||||
DateTime.civil(year, month, day, hour, minute, second + (usec / 1000000))
|
||||
end
|
||||
|
||||
include DateAndTimeBehavior
|
||||
|
@ -113,7 +113,7 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
def test_end_of_day
|
||||
assert_equal DateTime.civil(2005, 2, 4, 23, 59, 59), DateTime.civil(2005, 2, 4, 10, 10, 10).end_of_day
|
||||
assert_equal DateTime.civil(2005, 2, 4, 23, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 2, 4, 10, 10, 10).end_of_day
|
||||
end
|
||||
|
||||
def test_beginning_of_hour
|
||||
|
@ -121,7 +121,7 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
def test_end_of_hour
|
||||
assert_equal DateTime.civil(2005, 2, 4, 19, 59, 59), DateTime.civil(2005, 2, 4, 19, 30, 10).end_of_hour
|
||||
assert_equal DateTime.civil(2005, 2, 4, 19, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 2, 4, 19, 30, 10).end_of_hour
|
||||
end
|
||||
|
||||
def test_beginning_of_minute
|
||||
|
@ -129,13 +129,13 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
def test_end_of_minute
|
||||
assert_equal DateTime.civil(2005, 2, 4, 19, 30, 59), DateTime.civil(2005, 2, 4, 19, 30, 10).end_of_minute
|
||||
assert_equal DateTime.civil(2005, 2, 4, 19, 30, Rational(59999999999, 1000000000)), DateTime.civil(2005, 2, 4, 19, 30, 10).end_of_minute
|
||||
end
|
||||
|
||||
def test_end_of_month
|
||||
assert_equal DateTime.civil(2005, 3, 31, 23, 59, 59), DateTime.civil(2005, 3, 20, 10, 10, 10).end_of_month
|
||||
assert_equal DateTime.civil(2005, 2, 28, 23, 59, 59), DateTime.civil(2005, 2, 20, 10, 10, 10).end_of_month
|
||||
assert_equal DateTime.civil(2005, 4, 30, 23, 59, 59), DateTime.civil(2005, 4, 20, 10, 10, 10).end_of_month
|
||||
assert_equal DateTime.civil(2005, 3, 31, 23, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 3, 20, 10, 10, 10).end_of_month
|
||||
assert_equal DateTime.civil(2005, 2, 28, 23, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 2, 20, 10, 10, 10).end_of_month
|
||||
assert_equal DateTime.civil(2005, 4, 30, 23, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 4, 20, 10, 10, 10).end_of_month
|
||||
end
|
||||
|
||||
def test_last_year
|
||||
|
@ -162,12 +162,19 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
assert_equal DateTime.civil(2006, 2, 22, 15, 15, 10), DateTime.civil(2005, 2, 22, 15, 15, 10).change(year: 2006)
|
||||
assert_equal DateTime.civil(2005, 6, 22, 15, 15, 10), DateTime.civil(2005, 2, 22, 15, 15, 10).change(month: 6)
|
||||
assert_equal DateTime.civil(2012, 9, 22, 15, 15, 10), DateTime.civil(2005, 2, 22, 15, 15, 10).change(year: 2012, month: 9)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 16), DateTime.civil(2005, 2, 22, 15, 15, 10).change(hour: 16)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 16, 45), DateTime.civil(2005, 2, 22, 15, 15, 10).change(hour: 16, min: 45)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 15, 45), DateTime.civil(2005, 2, 22, 15, 15, 10).change(min: 45)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 16), DateTime.civil(2005, 2, 22, 15, 15, 10).change(hour: 16)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 16, 45), DateTime.civil(2005, 2, 22, 15, 15, 10).change(hour: 16, min: 45)
|
||||
assert_equal DateTime.civil(2005, 2, 22, 15, 45), DateTime.civil(2005, 2, 22, 15, 15, 10).change(min: 45)
|
||||
|
||||
# datetime with fractions of a second
|
||||
assert_equal DateTime.civil(2005, 2, 1, 15, 15, 10.7), DateTime.civil(2005, 2, 22, 15, 15, 10.7).change(day: 1)
|
||||
assert_equal DateTime.civil(2005, 1, 2, 11, 22, Rational(33000008, 1000000)), DateTime.civil(2005, 1, 2, 11, 22, 33).change(usec: 8)
|
||||
assert_equal DateTime.civil(2005, 1, 2, 11, 22, Rational(33000008, 1000000)), DateTime.civil(2005, 1, 2, 11, 22, 33).change(nsec: 8000)
|
||||
assert_raise(ArgumentError) { DateTime.civil(2005, 1, 2, 11, 22, 0).change(usec: 1, nsec: 1) }
|
||||
assert_raise(ArgumentError) { DateTime.civil(2005, 1, 2, 11, 22, 0).change(usec: 1000000) }
|
||||
assert_raise(ArgumentError) { DateTime.civil(2005, 1, 2, 11, 22, 0).change(nsec: 1000000000) }
|
||||
assert_nothing_raised { DateTime.civil(2005, 1, 2, 11, 22, 0).change(usec: 999999) }
|
||||
assert_nothing_raised { DateTime.civil(2005, 1, 2, 11, 22, 0).change(nsec: 999999999) }
|
||||
end
|
||||
|
||||
def test_advance
|
||||
|
|
Loading…
Reference in a new issue