activesupport 4.2.11.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +309 -485
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/active_support.rb +8 -15
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/cache.rb +59 -72
- data/lib/active_support/cache/file_store.rb +27 -19
- data/lib/active_support/cache/mem_cache_store.rb +71 -60
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/callbacks.rb +107 -111
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +142 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +13 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +5 -2
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
- data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/enumerable.rb +27 -17
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/compact.rb +15 -19
- data/lib/active_support/core_ext/hash/conversions.rb +21 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +22 -18
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
- data/lib/active_support/core_ext/integer/time.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +8 -13
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +7 -14
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +20 -0
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +11 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +39 -70
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +9 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +67 -21
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- data/lib/active_support/core_ext/string/inflections.rb +23 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +8 -9
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time.rb +0 -2
- data/lib/active_support/core_ext/time/calculations.rb +18 -16
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +19 -3
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/dependencies.rb +79 -44
- data/lib/active_support/dependencies/interlock.rb +47 -0
- data/lib/active_support/deprecation/behaviors.rb +12 -0
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +13 -2
- data/lib/active_support/duration.rb +5 -8
- data/lib/active_support/evented_file_update_checker.rb +150 -0
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +15 -17
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +87 -89
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +2 -8
- data/lib/active_support/json/encoding.rb +0 -50
- data/lib/active_support/key_generator.rb +4 -4
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/logger.rb +4 -52
- data/lib/active_support/logger_silence.rb +3 -5
- data/lib/active_support/message_encryptor.rb +4 -11
- data/lib/active_support/message_verifier.rb +64 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +6 -8
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/notifications/fanout.rb +5 -5
- data/lib/active_support/notifications/instrumenter.rb +19 -2
- data/lib/active_support/number_helper.rb +21 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +3 -0
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/security_utils.rb +0 -7
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +13 -25
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/composite_filter.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +6 -6
- data/lib/active_support/time_with_zone.rb +135 -53
- data/lib/active_support/values/time_zone.rb +80 -46
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini.rb +15 -30
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- metadata +57 -21
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
- data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/compatibility.rb +0 -14
- data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Testing
|
3
|
+
# Adds simple access to sample files called file fixtures.
|
4
|
+
# File fixtures are normal files stored in
|
5
|
+
# <tt>ActiveSupport::TestCase.file_fixture_path</tt>.
|
6
|
+
#
|
7
|
+
# File fixtures are represented as +Pathname+ objects.
|
8
|
+
# This makes it easy to extract specific information:
|
9
|
+
#
|
10
|
+
# file_fixture("example.txt").read # get the file's content
|
11
|
+
# file_fixture("example.mp3").size # get the file size
|
12
|
+
module FileFixtures
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
class_attribute :file_fixture_path, instance_writer: false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a +Pathname+ to the fixture file named +fixture_name+.
|
20
|
+
#
|
21
|
+
# Raises +ArgumentError+ if +fixture_name+ can't be found.
|
22
|
+
def file_fixture(fixture_name)
|
23
|
+
path = Pathname.new(File.join(file_fixture_path, fixture_name))
|
24
|
+
|
25
|
+
if path.exist?
|
26
|
+
path
|
27
|
+
else
|
28
|
+
msg = "the directory '%s' does not contain a file named '%s'"
|
29
|
+
raise ArgumentError, msg % [file_fixture_path, fixture_name]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'rbconfig'
|
2
|
-
|
3
1
|
module ActiveSupport
|
4
2
|
module Testing
|
5
3
|
module Isolation
|
@@ -12,7 +10,7 @@ module ActiveSupport
|
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.forking_env?
|
15
|
-
!ENV["NO_FORK"] && (
|
13
|
+
!ENV["NO_FORK"] && Process.respond_to?(:fork)
|
16
14
|
end
|
17
15
|
|
18
16
|
@@class_setup_mutex = Mutex.new
|
@@ -43,7 +41,23 @@ module ActiveSupport
|
|
43
41
|
pid = fork do
|
44
42
|
read.close
|
45
43
|
yield
|
46
|
-
|
44
|
+
begin
|
45
|
+
if error?
|
46
|
+
failures.map! { |e|
|
47
|
+
begin
|
48
|
+
Marshal.dump e
|
49
|
+
e
|
50
|
+
rescue TypeError
|
51
|
+
ex = Exception.new e.message
|
52
|
+
ex.set_backtrace e.backtrace
|
53
|
+
Minitest::UnexpectedError.new ex
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
result = Marshal.dump(self.dup)
|
58
|
+
end
|
59
|
+
|
60
|
+
write.puts [result].pack("m")
|
47
61
|
exit!
|
48
62
|
end
|
49
63
|
|
@@ -71,17 +85,17 @@ module ActiveSupport
|
|
71
85
|
else
|
72
86
|
Tempfile.open("isolation") do |tmpfile|
|
73
87
|
env = {
|
74
|
-
ISOLATION_TEST
|
75
|
-
ISOLATION_OUTPUT
|
88
|
+
'ISOLATION_TEST' => self.class.name,
|
89
|
+
'ISOLATION_OUTPUT' => tmpfile.path
|
76
90
|
}
|
77
91
|
|
78
92
|
load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
|
79
93
|
orig_args = ORIG_ARGV.join(" ")
|
80
94
|
test_opts = "-n#{self.class.name}##{self.name}"
|
81
|
-
command = "#{Gem.ruby} #{load_paths} #{$0} #{orig_args} #{test_opts}"
|
95
|
+
command = "#{Gem.ruby} #{load_paths} #{$0} '#{orig_args}' #{test_opts}"
|
82
96
|
|
83
97
|
# IO.popen lets us pass env in a cross-platform way
|
84
|
-
child = IO.popen(
|
98
|
+
child = IO.popen(env, command)
|
85
99
|
|
86
100
|
begin
|
87
101
|
Process.wait(child.pid)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'minitest/mock'
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
module MethodCallAssertions # :nodoc:
|
6
|
+
private
|
7
|
+
def assert_called(object, method_name, message = nil, times: 1, returns: nil)
|
8
|
+
times_called = 0
|
9
|
+
|
10
|
+
object.stub(method_name, proc { times_called += 1; returns }) { yield }
|
11
|
+
|
12
|
+
error = "Expected #{method_name} to be called #{times} times, " \
|
13
|
+
"but was called #{times_called} times"
|
14
|
+
error = "#{message}.\n#{error}" if message
|
15
|
+
assert_equal times, times_called, error
|
16
|
+
end
|
17
|
+
|
18
|
+
def assert_called_with(object, method_name, args = [], returns: nil)
|
19
|
+
mock = Minitest::Mock.new
|
20
|
+
|
21
|
+
if args.all? { |arg| arg.is_a?(Array) }
|
22
|
+
args.each { |arg| mock.expect(:call, returns, arg) }
|
23
|
+
else
|
24
|
+
mock.expect(:call, returns, args)
|
25
|
+
end
|
26
|
+
|
27
|
+
object.stub(method_name, mock) { yield }
|
28
|
+
|
29
|
+
mock.verify
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_not_called(object, method_name, message = nil, &block)
|
33
|
+
assert_called(object, method_name, message, times: 0, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_any_instance(klass, instance: klass.new)
|
37
|
+
klass.stub(:new, instance) { yield instance }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Testing
|
3
|
+
module Stream #:nodoc:
|
4
|
+
private
|
5
|
+
|
6
|
+
def silence_stream(stream)
|
7
|
+
old_stream = stream.dup
|
8
|
+
stream.reopen(IO::NULL)
|
9
|
+
stream.sync = true
|
10
|
+
yield
|
11
|
+
ensure
|
12
|
+
stream.reopen(old_stream)
|
13
|
+
old_stream.close
|
14
|
+
end
|
15
|
+
|
16
|
+
def quietly
|
17
|
+
silence_stream(STDOUT) do
|
18
|
+
silence_stream(STDERR) do
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def capture(stream)
|
25
|
+
stream = stream.to_s
|
26
|
+
captured_stream = Tempfile.new(stream)
|
27
|
+
stream_io = eval("$#{stream}")
|
28
|
+
origin_stream = stream_io.dup
|
29
|
+
stream_io.reopen(captured_stream)
|
30
|
+
|
31
|
+
yield
|
32
|
+
|
33
|
+
stream_io.rewind
|
34
|
+
return captured_stream.read
|
35
|
+
ensure
|
36
|
+
captured_stream.close
|
37
|
+
captured_stream.unlink
|
38
|
+
stream_io.reopen(origin_stream)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -7,7 +7,7 @@ module ActiveSupport
|
|
7
7
|
@stubs = {}
|
8
8
|
end
|
9
9
|
|
10
|
-
def stub_object(object, method_name,
|
10
|
+
def stub_object(object, method_name, return_value)
|
11
11
|
key = [object.object_id, method_name]
|
12
12
|
|
13
13
|
if stub = @stubs[key]
|
@@ -19,7 +19,7 @@ module ActiveSupport
|
|
19
19
|
@stubs[key] = Stub.new(object, method_name, new_name)
|
20
20
|
|
21
21
|
object.singleton_class.send :alias_method, new_name, method_name
|
22
|
-
object.define_singleton_method(method_name
|
22
|
+
object.define_singleton_method(method_name) { return_value }
|
23
23
|
end
|
24
24
|
|
25
25
|
def unstub_all!
|
@@ -39,7 +39,7 @@ module ActiveSupport
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
#
|
42
|
+
# Contains helpers that help you test passage of time.
|
43
43
|
module TimeHelpers
|
44
44
|
# Changes current time to the time in the future or in the past by a given time difference by
|
45
45
|
# stubbing +Time.now+, +Date.today+, and +DateTime.now+.
|
@@ -99,9 +99,9 @@ module ActiveSupport
|
|
99
99
|
now = date_or_time.to_time.change(usec: 0)
|
100
100
|
end
|
101
101
|
|
102
|
-
simple_stubs.stub_object(Time, :now
|
103
|
-
simple_stubs.stub_object(Date, :today
|
104
|
-
simple_stubs.stub_object(DateTime, :now
|
102
|
+
simple_stubs.stub_object(Time, :now, now)
|
103
|
+
simple_stubs.stub_object(Date, :today, now.to_date)
|
104
|
+
simple_stubs.stub_object(DateTime, :now, now.to_datetime)
|
105
105
|
|
106
106
|
if block_given?
|
107
107
|
begin
|
@@ -1,6 +1,6 @@
|
|
1
|
+
require 'active_support/duration'
|
1
2
|
require 'active_support/values/time_zone'
|
2
3
|
require 'active_support/core_ext/object/acts_like'
|
3
|
-
require 'active_support/core_ext/date_and_time/compatibility'
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
# A Time-like class that can represent a time in any time zone. Necessary
|
@@ -14,7 +14,7 @@ module ActiveSupport
|
|
14
14
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
15
15
|
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
16
16
|
# Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
17
|
-
# Time.zone.at(
|
17
|
+
# Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
18
18
|
# Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00
|
19
19
|
# Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
20
20
|
#
|
@@ -41,21 +41,23 @@ module ActiveSupport
|
|
41
41
|
'Time'
|
42
42
|
end
|
43
43
|
|
44
|
-
|
44
|
+
PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N".freeze }
|
45
|
+
PRECISIONS[0] = '%FT%T'.freeze
|
46
|
+
|
47
|
+
include Comparable
|
45
48
|
attr_reader :time_zone
|
46
49
|
|
47
50
|
def initialize(utc_time, time_zone, local_time = nil, period = nil)
|
48
|
-
@utc
|
49
|
-
@time_zone, @time = time_zone, local_time
|
51
|
+
@utc, @time_zone, @time = utc_time, time_zone, local_time
|
50
52
|
@period = @utc ? period : get_period_and_ensure_valid_local_time(period)
|
51
53
|
end
|
52
54
|
|
53
|
-
# Returns a
|
55
|
+
# Returns a Time or DateTime instance that represents the time in +time_zone+.
|
54
56
|
def time
|
55
57
|
@time ||= period.to_local(@utc)
|
56
58
|
end
|
57
59
|
|
58
|
-
# Returns a
|
60
|
+
# Returns a Time or DateTime instance that represents the time in UTC.
|
59
61
|
def utc
|
60
62
|
@utc ||= period.to_utc(@time)
|
61
63
|
end
|
@@ -75,9 +77,10 @@ module ActiveSupport
|
|
75
77
|
utc.in_time_zone(new_zone)
|
76
78
|
end
|
77
79
|
|
78
|
-
# Returns a <tt>Time</tt> instance of the simultaneous time in
|
80
|
+
# Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
|
81
|
+
# system's <tt>ENV['TZ']</tt> zone.
|
79
82
|
def localtime(utc_offset = nil)
|
80
|
-
utc.getlocal(utc_offset)
|
83
|
+
utc.respond_to?(:getlocal) ? utc.getlocal(utc_offset) : utc.to_time.getlocal(utc_offset)
|
81
84
|
end
|
82
85
|
alias_method :getlocal, :localtime
|
83
86
|
|
@@ -99,7 +102,7 @@ module ActiveSupport
|
|
99
102
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
100
103
|
# Time.zone.now.utc? # => false
|
101
104
|
def utc?
|
102
|
-
|
105
|
+
period.offset.abbreviation == :UTC || period.offset.abbreviation == :UCT
|
103
106
|
end
|
104
107
|
alias_method :gmt?, :utc?
|
105
108
|
|
@@ -122,22 +125,27 @@ module ActiveSupport
|
|
122
125
|
utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
123
126
|
end
|
124
127
|
|
125
|
-
#
|
126
|
-
#
|
128
|
+
# Returns the time zone abbreviation.
|
129
|
+
#
|
130
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)"
|
131
|
+
# Time.zone.now.zone # => "EST"
|
127
132
|
def zone
|
128
133
|
period.zone_identifier.to_s
|
129
134
|
end
|
130
135
|
|
136
|
+
# Returns a string of the object's date, time, zone and offset from UTC.
|
137
|
+
#
|
138
|
+
# Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25 EST -05:00"
|
131
139
|
def inspect
|
132
140
|
"#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
|
133
141
|
end
|
134
142
|
|
143
|
+
# Returns a string of the object's date and time in the ISO 8601 standard
|
144
|
+
# format.
|
145
|
+
#
|
146
|
+
# Time.zone.now.xmlschema # => "2014-12-04T11:02:37-05:00"
|
135
147
|
def xmlschema(fraction_digits = 0)
|
136
|
-
|
137
|
-
(".%06i" % time.usec)[0, fraction_digits.to_i + 1]
|
138
|
-
end
|
139
|
-
|
140
|
-
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
|
148
|
+
"#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
|
141
149
|
end
|
142
150
|
alias_method :iso8601, :xmlschema
|
143
151
|
|
@@ -166,11 +174,8 @@ module ActiveSupport
|
|
166
174
|
end
|
167
175
|
|
168
176
|
def encode_with(coder) #:nodoc:
|
169
|
-
|
170
|
-
|
171
|
-
else
|
172
|
-
coder.represent_scalar(nil, utc.strftime("%Y-%m-%d %H:%M:%S.%9NZ"))
|
173
|
-
end
|
177
|
+
coder.tag = '!ruby/object:ActiveSupport::TimeWithZone'
|
178
|
+
coder.map = { 'utc' => utc, 'zone' => time_zone, 'time' => time }
|
174
179
|
end
|
175
180
|
|
176
181
|
# Returns a string of the object's date and time in the format used by
|
@@ -192,7 +197,7 @@ module ActiveSupport
|
|
192
197
|
|
193
198
|
# Returns a string of the object's date and time.
|
194
199
|
# Accepts an optional <tt>format</tt>:
|
195
|
-
# * <tt>:default</tt> - default value, mimics Ruby
|
200
|
+
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
|
196
201
|
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_formatted_s(:db).
|
197
202
|
# * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
|
198
203
|
def to_s(format = :default)
|
@@ -201,7 +206,7 @@ module ActiveSupport
|
|
201
206
|
elsif formatter = ::Time::DATE_FORMATS[format]
|
202
207
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
203
208
|
else
|
204
|
-
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby
|
209
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
|
205
210
|
end
|
206
211
|
end
|
207
212
|
alias_method :to_formatted_s, :to_s
|
@@ -240,6 +245,7 @@ module ActiveSupport
|
|
240
245
|
utc.future?
|
241
246
|
end
|
242
247
|
|
248
|
+
# Returns +true+ if +other+ is equal to current object.
|
243
249
|
def eql?(other)
|
244
250
|
other.eql?(utc)
|
245
251
|
end
|
@@ -248,9 +254,23 @@ module ActiveSupport
|
|
248
254
|
utc.hash
|
249
255
|
end
|
250
256
|
|
257
|
+
# Adds an interval of time to the current object's time and returns that
|
258
|
+
# value as a new TimeWithZone object.
|
259
|
+
#
|
260
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
261
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
262
|
+
# now + 1000 # => Sun, 02 Nov 2014 01:43:08 EDT -04:00
|
263
|
+
#
|
264
|
+
# If we're adding a Duration of variable length (i.e., years, months, days),
|
265
|
+
# move forward from #time, otherwise move forward from #utc, for accuracy
|
266
|
+
# when moving across DST boundaries.
|
267
|
+
#
|
268
|
+
# For instance, a time + 24.hours will advance exactly 24 hours, while a
|
269
|
+
# time + 1.day will advance 23-25 hours, depending on the day.
|
270
|
+
#
|
271
|
+
# now + 24.hours # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
272
|
+
# now + 1.day # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
251
273
|
def +(other)
|
252
|
-
# If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
|
253
|
-
# otherwise move forward from #utc, for accuracy when moving across DST boundaries
|
254
274
|
if duration_of_variable_length?(other)
|
255
275
|
method_missing(:+, other)
|
256
276
|
else
|
@@ -258,10 +278,25 @@ module ActiveSupport
|
|
258
278
|
result.in_time_zone(time_zone)
|
259
279
|
end
|
260
280
|
end
|
281
|
+
alias_method :since, :+
|
261
282
|
|
283
|
+
# Returns a new TimeWithZone object that represents the difference between
|
284
|
+
# the current object's time and the +other+ time.
|
285
|
+
#
|
286
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
287
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
288
|
+
# now - 1000 # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
289
|
+
#
|
290
|
+
# If subtracting a Duration of variable length (i.e., years, months, days),
|
291
|
+
# move backward from #time, otherwise move backward from #utc, for accuracy
|
292
|
+
# when moving across DST boundaries.
|
293
|
+
#
|
294
|
+
# For instance, a time - 24.hours will go subtract exactly 24 hours, while a
|
295
|
+
# time - 1.day will subtract 23-25 hours, depending on the day.
|
296
|
+
#
|
297
|
+
# now - 24.hours # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
298
|
+
# now - 1.day # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
262
299
|
def -(other)
|
263
|
-
# If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
|
264
|
-
# otherwise move backwards #utc, for accuracy when moving across DST boundaries
|
265
300
|
if other.acts_like?(:time)
|
266
301
|
to_time - other.to_time
|
267
302
|
elsif duration_of_variable_length?(other)
|
@@ -272,21 +307,48 @@ module ActiveSupport
|
|
272
307
|
end
|
273
308
|
end
|
274
309
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
310
|
+
# Subtracts an interval of time from the current object's time and returns
|
311
|
+
# the result as a new TimeWithZone object.
|
312
|
+
#
|
313
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
314
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
315
|
+
# now.ago(1000) # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
316
|
+
#
|
317
|
+
# If we're subtracting a Duration of variable length (i.e., years, months,
|
318
|
+
# days), move backward from #time, otherwise move backward from #utc, for
|
319
|
+
# accuracy when moving across DST boundaries.
|
320
|
+
#
|
321
|
+
# For instance, <tt>time.ago(24.hours)</tt> will move back exactly 24 hours,
|
322
|
+
# while <tt>time.ago(1.day)</tt> will move back 23-25 hours, depending on
|
323
|
+
# the day.
|
324
|
+
#
|
325
|
+
# now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
326
|
+
# now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
286
327
|
def ago(other)
|
287
328
|
since(-other)
|
288
329
|
end
|
289
330
|
|
331
|
+
# Uses Date to provide precise Time calculations for years, months, and days
|
332
|
+
# according to the proleptic Gregorian calendar. The result is returned as a
|
333
|
+
# new TimeWithZone object.
|
334
|
+
#
|
335
|
+
# The +options+ parameter takes a hash with any of these keys:
|
336
|
+
# <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>,
|
337
|
+
# <tt>:hours</tt>, <tt>:minutes</tt>, <tt>:seconds</tt>.
|
338
|
+
#
|
339
|
+
# If advancing by a value of variable length (i.e., years, weeks, months,
|
340
|
+
# days), move forward from #time, otherwise move forward from #utc, for
|
341
|
+
# accuracy when moving across DST boundaries.
|
342
|
+
#
|
343
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
344
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
345
|
+
# now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29 EDT -04:00
|
346
|
+
# now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28 EDT -04:00
|
347
|
+
# now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28 EST -05:00
|
348
|
+
# now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
349
|
+
# now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28 EST -05:00
|
350
|
+
# now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28 EST -05:00
|
351
|
+
# now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28 EST -05:00
|
290
352
|
def advance(options)
|
291
353
|
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
|
292
354
|
# otherwise advance from #utc, for accuracy when moving across DST boundaries
|
@@ -305,36 +367,51 @@ module ActiveSupport
|
|
305
367
|
EOV
|
306
368
|
end
|
307
369
|
|
370
|
+
# Returns Array of parts of Time in sequence of
|
371
|
+
# [seconds, minutes, hours, day, month, year, weekday, yearday, dst?, zone].
|
372
|
+
#
|
373
|
+
# now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27 UTC +00:00
|
374
|
+
# now.to_a # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
|
308
375
|
def to_a
|
309
376
|
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
310
377
|
end
|
311
378
|
|
379
|
+
# Returns the object's date and time as a floating point number of seconds
|
380
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
381
|
+
#
|
382
|
+
# Time.zone.now.to_f # => 1417709320.285418
|
312
383
|
def to_f
|
313
384
|
utc.to_f
|
314
385
|
end
|
315
386
|
|
387
|
+
# Returns the object's date and time as an integer number of seconds
|
388
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
389
|
+
#
|
390
|
+
# Time.zone.now.to_i # => 1417709320
|
316
391
|
def to_i
|
317
392
|
utc.to_i
|
318
393
|
end
|
319
394
|
alias_method :tv_sec, :to_i
|
320
395
|
|
396
|
+
# Returns the object's date and time as a rational number of seconds
|
397
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
398
|
+
#
|
399
|
+
# Time.zone.now.to_r # => (708854548642709/500000)
|
321
400
|
def to_r
|
322
401
|
utc.to_r
|
323
402
|
end
|
324
403
|
|
325
|
-
|
326
|
-
|
404
|
+
# Returns an instance of Time in the system timezone.
|
405
|
+
def to_time
|
406
|
+
utc.to_time
|
327
407
|
end
|
328
408
|
|
329
|
-
# Returns an instance of
|
330
|
-
#
|
331
|
-
#
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
else
|
336
|
-
@to_time_with_system_offset ||= getlocal
|
337
|
-
end
|
409
|
+
# Returns an instance of DateTime with the timezone's UTC offset
|
410
|
+
#
|
411
|
+
# Time.zone.now.to_datetime # => Tue, 18 Aug 2015 02:32:20 +0000
|
412
|
+
# Time.current.in_time_zone('Hawaii').to_datetime # => Mon, 17 Aug 2015 16:32:20 -1000
|
413
|
+
def to_datetime
|
414
|
+
utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
|
338
415
|
end
|
339
416
|
|
340
417
|
# So that +self+ <tt>acts_like?(:time)</tt>.
|
@@ -348,9 +425,13 @@ module ActiveSupport
|
|
348
425
|
end
|
349
426
|
alias_method :kind_of?, :is_a?
|
350
427
|
|
428
|
+
# An instance of ActiveSupport::TimeWithZone is never blank
|
429
|
+
def blank?
|
430
|
+
false
|
431
|
+
end
|
432
|
+
|
351
433
|
def freeze
|
352
|
-
# preload instance variables before freezing
|
353
|
-
period; utc; time; to_datetime; to_time
|
434
|
+
period; utc; time # preload instance variables before freezing
|
354
435
|
super
|
355
436
|
end
|
356
437
|
|
@@ -373,6 +454,7 @@ module ActiveSupport
|
|
373
454
|
# Ensure proxy class responds to all methods that underlying time instance
|
374
455
|
# responds to.
|
375
456
|
def respond_to_missing?(sym, include_priv)
|
457
|
+
# consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
|
376
458
|
return false if sym.to_sym == :acts_like_date?
|
377
459
|
time.respond_to?(sym, include_priv)
|
378
460
|
end
|
@@ -400,7 +482,7 @@ module ActiveSupport
|
|
400
482
|
end
|
401
483
|
|
402
484
|
def transfer_time_values_to_utc_constructor(time)
|
403
|
-
::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec
|
485
|
+
::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000))
|
404
486
|
end
|
405
487
|
|
406
488
|
def duration_of_variable_length?(obj)
|