activesupport 4.2.11.1 → 6.1.7.3

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.

Files changed (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -391
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -7
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +34 -6
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +61 -55
  12. data/lib/active_support/cache/mem_cache_store.rb +115 -100
  13. data/lib/active_support/cache/memory_store.rb +81 -58
  14. data/lib/active_support/cache/null_store.rb +11 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +90 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +386 -225
  19. data/lib/active_support/callbacks.rb +661 -594
  20. data/lib/active_support/concern.rb +80 -7
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +226 -0
  23. data/lib/active_support/configurable.rb +16 -17
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +41 -1
  26. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  32. data/lib/active_support/core_ext/array.rb +9 -6
  33. data/lib/active_support/core_ext/benchmark.rb +5 -3
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +52 -48
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -25
  39. data/lib/active_support/core_ext/class.rb +4 -3
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +14 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  43. data/lib/active_support/core_ext/date/conversions.rb +27 -24
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +6 -4
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +167 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +19 -3
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  50. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  53. data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
  54. data/lib/active_support/core_ext/date_time.rb +7 -5
  55. data/lib/active_support/core_ext/digest/uuid.rb +8 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +186 -22
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +13 -10
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +20 -43
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +10 -9
  69. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +11 -18
  72. data/lib/active_support/core_ext/integer.rb +5 -3
  73. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +5 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +10 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +63 -69
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +148 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +19 -14
  85. data/lib/active_support/core_ext/module/delegation.rb +164 -51
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +23 -22
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  90. data/lib/active_support/core_ext/module.rb +13 -11
  91. data/lib/active_support/core_ext/name_error.rb +51 -4
  92. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +133 -136
  94. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  95. data/lib/active_support/core_ext/numeric.rb +5 -3
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +27 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  99. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  100. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  101. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  102. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  103. data/lib/active_support/core_ext/object/json.rb +63 -21
  104. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  105. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  106. data/lib/active_support/core_ext/object/try.rb +81 -23
  107. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  108. data/lib/active_support/core_ext/object.rb +14 -13
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  111. data/lib/active_support/core_ext/range/each.rb +18 -17
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +7 -4
  115. data/lib/active_support/core_ext/regexp.rb +10 -1
  116. data/lib/active_support/core_ext/securerandom.rb +45 -0
  117. data/lib/active_support/core_ext/string/access.rb +9 -18
  118. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  119. data/lib/active_support/core_ext/string/conversions.rb +8 -4
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +48 -6
  122. data/lib/active_support/core_ext/string/indent.rb +6 -4
  123. data/lib/active_support/core_ext/string/inflections.rb +102 -26
  124. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  125. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  126. data/lib/active_support/core_ext/string/output_safety.rb +125 -40
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +6 -5
  129. data/lib/active_support/core_ext/string/zones.rb +4 -2
  130. data/lib/active_support/core_ext/string.rb +15 -13
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  134. data/lib/active_support/core_ext/time/calculations.rb +137 -53
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +22 -13
  137. data/lib/active_support/core_ext/time/zones.rb +41 -7
  138. data/lib/active_support/core_ext/time.rb +7 -6
  139. data/lib/active_support/core_ext/uri.rb +11 -8
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +241 -175
  147. data/lib/active_support/deprecation/behaviors.rb +58 -12
  148. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  151. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  153. data/lib/active_support/deprecation/reporting.rb +81 -18
  154. data/lib/active_support/deprecation.rb +17 -9
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  158. data/lib/active_support/duration/iso8601_serializer.rb +59 -0
  159. data/lib/active_support/duration.rb +364 -39
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +170 -0
  164. data/lib/active_support/execution_wrapper.rb +132 -0
  165. data/lib/active_support/executor.rb +8 -0
  166. data/lib/active_support/file_update_checker.rb +62 -37
  167. data/lib/active_support/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +7 -5
  169. data/lib/active_support/gzip.rb +7 -5
  170. data/lib/active_support/hash_with_indifferent_access.rb +171 -48
  171. data/lib/active_support/i18n.rb +9 -6
  172. data/lib/active_support/i18n_railtie.rb +47 -16
  173. data/lib/active_support/inflections.rb +13 -11
  174. data/lib/active_support/inflector/inflections.rb +58 -14
  175. data/lib/active_support/inflector/methods.rb +186 -169
  176. data/lib/active_support/inflector/transliterate.rb +83 -33
  177. data/lib/active_support/inflector.rb +7 -5
  178. data/lib/active_support/json/decoding.rb +32 -30
  179. data/lib/active_support/json/encoding.rb +22 -61
  180. data/lib/active_support/json.rb +4 -2
  181. data/lib/active_support/key_generator.rb +11 -43
  182. data/lib/active_support/lazy_load_hooks.rb +53 -20
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +9 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  186. data/lib/active_support/log_subscriber.rb +52 -19
  187. data/lib/active_support/logger.rb +10 -24
  188. data/lib/active_support/logger_silence.rb +14 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -10
  190. data/lib/active_support/message_encryptor.rb +167 -57
  191. data/lib/active_support/message_verifier.rb +151 -18
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +35 -80
  196. data/lib/active_support/multibyte/unicode.rb +22 -330
  197. data/lib/active_support/multibyte.rb +4 -2
  198. data/lib/active_support/notifications/fanout.rb +125 -23
  199. data/lib/active_support/notifications/instrumenter.rb +98 -16
  200. data/lib/active_support/notifications.rb +82 -14
  201. data/lib/active_support/number_helper/number_converter.rb +17 -16
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -14
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +14 -11
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +12 -10
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +29 -57
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +123 -71
  211. data/lib/active_support/option_merger.rb +25 -4
  212. data/lib/active_support/ordered_hash.rb +7 -5
  213. data/lib/active_support/ordered_options.rb +35 -7
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +10 -4
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +10 -11
  218. data/lib/active_support/railtie.rb +66 -10
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +112 -57
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +13 -4
  224. data/lib/active_support/subscriber.rb +80 -31
  225. data/lib/active_support/tagged_logging.rb +54 -17
  226. data/lib/active_support/test_case.rb +107 -44
  227. data/lib/active_support/testing/assertions.rb +158 -20
  228. data/lib/active_support/testing/autorun.rb +4 -2
  229. data/lib/active_support/testing/constant_lookup.rb +2 -1
  230. data/lib/active_support/testing/declarative.rb +3 -1
  231. data/lib/active_support/testing/deprecation.rb +13 -10
  232. data/lib/active_support/testing/file_fixtures.rb +38 -0
  233. data/lib/active_support/testing/isolation.rb +35 -26
  234. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  239. data/lib/active_support/testing/stream.rb +43 -0
  240. data/lib/active_support/testing/tagged_logging.rb +3 -1
  241. data/lib/active_support/testing/time_helpers.rb +121 -20
  242. data/lib/active_support/time.rb +14 -12
  243. data/lib/active_support/time_with_zone.rb +215 -51
  244. data/lib/active_support/values/time_zone.rb +223 -71
  245. data/lib/active_support/version.rb +3 -1
  246. data/lib/active_support/xml_mini/jdom.rb +116 -115
  247. data/lib/active_support/xml_mini/libxml.rb +16 -13
  248. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  249. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  250. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  251. data/lib/active_support/xml_mini/rexml.rb +18 -9
  252. data/lib/active_support/xml_mini.rb +38 -46
  253. data/lib/active_support.rb +25 -11
  254. metadata +100 -43
  255. data/lib/active_support/concurrency/latch.rb +0 -27
  256. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  257. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  258. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  259. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  260. data/lib/active_support/core_ext/hash/compact.rb +0 -24
  261. data/lib/active_support/core_ext/hash/transform_values.rb +0 -23
  262. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  263. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  264. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  265. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  266. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  267. data/lib/active_support/core_ext/object/itself.rb +0 -15
  268. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  269. data/lib/active_support/core_ext/struct.rb +0 -6
  270. data/lib/active_support/core_ext/thread.rb +0 -86
  271. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  272. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Symbol
4
+ def start_with?(*prefixes)
5
+ to_s.start_with?(*prefixes)
6
+ end unless method_defined?(:start_with?)
7
+
8
+ def end_with?(*suffixes)
9
+ to_s.end_with?(*suffixes)
10
+ end unless method_defined?(:end_with?)
11
+
12
+ alias :starts_with? :start_with?
13
+ alias :ends_with? :end_with?
14
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/symbol/starts_ends_with"
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Time
4
6
  # Duck-types as a Time-like class. See Object#acts_like?.
@@ -1,9 +1,12 @@
1
- require 'active_support/duration'
2
- require 'active_support/core_ext/time/conversions'
3
- require 'active_support/time_with_zone'
4
- require 'active_support/core_ext/time/zones'
5
- require 'active_support/core_ext/date_and_time/calculations'
6
- require 'active_support/core_ext/date/calculations'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/duration"
4
+ require "active_support/core_ext/time/conversions"
5
+ require "active_support/time_with_zone"
6
+ require "active_support/core_ext/time/zones"
7
+ require "active_support/core_ext/date_and_time/calculations"
8
+ require "active_support/core_ext/date/calculations"
9
+ require "active_support/core_ext/module/remove_method"
7
10
 
8
11
  class Time
9
12
  include DateAndTime::Calculations
@@ -16,9 +19,9 @@ class Time
16
19
  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
17
20
  end
18
21
 
19
- # Return the number of days in the given month.
22
+ # Returns the number of days in the given month.
20
23
  # If no year is specified, it will use the current year.
21
- def days_in_month(month, year = now.year)
24
+ def days_in_month(month, year = current.year)
22
25
  if month == 2 && ::Date.gregorian_leap?(year)
23
26
  29
24
27
  else
@@ -26,6 +29,12 @@ class Time
26
29
  end
27
30
  end
28
31
 
32
+ # Returns the number of days in the given year.
33
+ # If no year is specified, it will use the current year.
34
+ def days_in_year(year = current.year)
35
+ days_in_month(2, year) + 337
36
+ end
37
+
29
38
  # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
30
39
  def current
31
40
  ::Time.zone ? ::Time.zone.now : ::Time.now
@@ -39,19 +48,49 @@ class Time
39
48
  # Time.at can be called with a time or numerical value
40
49
  time_or_number = args.first
41
50
 
42
- if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime)
51
+ if time_or_number.is_a?(ActiveSupport::TimeWithZone)
52
+ at_without_coercion(time_or_number.to_r).getlocal
53
+ elsif time_or_number.is_a?(DateTime)
43
54
  at_without_coercion(time_or_number.to_f).getlocal
44
55
  else
45
56
  at_without_coercion(time_or_number)
46
57
  end
47
58
  end
59
+ ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
48
60
  alias_method :at_without_coercion, :at
49
61
  alias_method :at, :at_with_coercion
62
+
63
+ # Creates a +Time+ instance from an RFC 3339 string.
64
+ #
65
+ # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
66
+ #
67
+ # If the time or offset components are missing then an +ArgumentError+ will be raised.
68
+ #
69
+ # Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
70
+ def rfc3339(str)
71
+ parts = Date._rfc3339(str)
72
+
73
+ raise ArgumentError, "invalid date" if parts.empty?
74
+
75
+ Time.new(
76
+ parts.fetch(:year),
77
+ parts.fetch(:mon),
78
+ parts.fetch(:mday),
79
+ parts.fetch(:hour),
80
+ parts.fetch(:min),
81
+ parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
82
+ parts.fetch(:offset)
83
+ )
84
+ end
50
85
  end
51
86
 
52
- # Seconds since midnight: Time.now.seconds_since_midnight
87
+ # Returns the number of seconds since 00:00:00.
88
+ #
89
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
90
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
91
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
53
92
  def seconds_since_midnight
54
- to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
93
+ to_i - change(hour: 0).to_i + (usec / 1.0e+6)
55
94
  end
56
95
 
57
96
  # Returns the number of seconds until 23:59:59.
@@ -70,40 +109,63 @@ class Time
70
109
  subsec
71
110
  end
72
111
 
112
+ unless Time.method_defined?(:floor)
113
+ def floor(precision = 0)
114
+ change(nsec: 0) + subsec.floor(precision)
115
+ end
116
+ end
117
+
118
+ # Restricted Ruby version due to a bug in `Time#ceil`
119
+ # See https://bugs.ruby-lang.org/issues/17025 for more details
120
+ if RUBY_VERSION <= "2.8"
121
+ remove_possible_method :ceil
122
+ def ceil(precision = 0)
123
+ change(nsec: 0) + subsec.ceil(precision)
124
+ end
125
+ end
126
+
73
127
  # Returns a new Time where one or more of the elements have been changed according
74
128
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
75
129
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
76
130
  # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
77
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
78
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
79
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
80
- # <tt>:nsec</tt>. Path either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
131
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
132
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
133
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
134
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
81
135
  #
82
136
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
83
137
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
84
138
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
85
139
  def change(options)
86
- new_year = options.fetch(:year, year)
87
- new_month = options.fetch(:month, month)
88
- new_day = options.fetch(:day, day)
89
- new_hour = options.fetch(:hour, hour)
90
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
91
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
140
+ new_year = options.fetch(:year, year)
141
+ new_month = options.fetch(:month, month)
142
+ new_day = options.fetch(:day, day)
143
+ new_hour = options.fetch(:hour, hour)
144
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
145
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
146
+ new_offset = options.fetch(:offset, nil)
92
147
 
93
148
  if new_nsec = options[:nsec]
94
149
  raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
95
150
  new_usec = Rational(new_nsec, 1000)
96
151
  else
97
- new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
152
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
98
153
  end
99
154
 
100
- if utc?
101
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
155
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
156
+
157
+ new_sec += Rational(new_usec, 1000000)
158
+
159
+ if new_offset
160
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
161
+ elsif utc?
162
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
163
+ elsif zone&.respond_to?(:utc_to_local)
164
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
102
165
  elsif zone
103
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
166
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
104
167
  else
105
- raise ArgumentError, 'argument out of range' if new_usec >= 1000000
106
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
168
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
107
169
  end
108
170
  end
109
171
 
@@ -129,9 +191,8 @@ class Time
129
191
  options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
130
192
  end
131
193
 
132
- d = to_date.advance(options)
133
- d = d.gregorian if d.julian?
134
- time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
194
+ d = to_date.gregorian.advance(options)
195
+ time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
135
196
  seconds_to_advance = \
136
197
  options.fetch(:seconds, 0) +
137
198
  options.fetch(:minutes, 0) * 60 +
@@ -159,8 +220,7 @@ class Time
159
220
 
160
221
  # Returns a new Time representing the start of the day (0:00)
161
222
  def beginning_of_day
162
- #(self - seconds_since_midnight).change(usec: 0)
163
- change(:hour => 0)
223
+ change(hour: 0)
164
224
  end
165
225
  alias :midnight :beginning_of_day
166
226
  alias :at_midnight :beginning_of_day
@@ -168,7 +228,7 @@ class Time
168
228
 
169
229
  # Returns a new Time representing the middle of the day (12:00)
170
230
  def middle_of_day
171
- change(:hour => 12)
231
+ change(hour: 12)
172
232
  end
173
233
  alias :midday :middle_of_day
174
234
  alias :noon :middle_of_day
@@ -176,53 +236,48 @@ class Time
176
236
  alias :at_noon :middle_of_day
177
237
  alias :at_middle_of_day :middle_of_day
178
238
 
179
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
239
+ # Returns a new Time representing the end of the day, 23:59:59.999999
180
240
  def end_of_day
181
241
  change(
182
- :hour => 23,
183
- :min => 59,
184
- :sec => 59,
185
- :usec => Rational(999999999, 1000)
242
+ hour: 23,
243
+ min: 59,
244
+ sec: 59,
245
+ usec: Rational(999999999, 1000)
186
246
  )
187
247
  end
188
248
  alias :at_end_of_day :end_of_day
189
249
 
190
250
  # Returns a new Time representing the start of the hour (x:00)
191
251
  def beginning_of_hour
192
- change(:min => 0)
252
+ change(min: 0)
193
253
  end
194
254
  alias :at_beginning_of_hour :beginning_of_hour
195
255
 
196
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
256
+ # Returns a new Time representing the end of the hour, x:59:59.999999
197
257
  def end_of_hour
198
258
  change(
199
- :min => 59,
200
- :sec => 59,
201
- :usec => Rational(999999999, 1000)
259
+ min: 59,
260
+ sec: 59,
261
+ usec: Rational(999999999, 1000)
202
262
  )
203
263
  end
204
264
  alias :at_end_of_hour :end_of_hour
205
265
 
206
266
  # Returns a new Time representing the start of the minute (x:xx:00)
207
267
  def beginning_of_minute
208
- change(:sec => 0)
268
+ change(sec: 0)
209
269
  end
210
270
  alias :at_beginning_of_minute :beginning_of_minute
211
271
 
212
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
272
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
213
273
  def end_of_minute
214
274
  change(
215
- :sec => 59,
216
- :usec => Rational(999999999, 1000)
275
+ sec: 59,
276
+ usec: Rational(999999999, 1000)
217
277
  )
218
278
  end
219
279
  alias :at_end_of_minute :end_of_minute
220
280
 
221
- # Returns a Range representing the whole day of the current time.
222
- def all_day
223
- beginning_of_day..end_of_day
224
- end
225
-
226
281
  def plus_with_duration(other) #:nodoc:
227
282
  if ActiveSupport::Duration === other
228
283
  other.since(self)
@@ -256,7 +311,7 @@ class Time
256
311
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
257
312
  # can be chronologically compared with a Time
258
313
  def compare_with_coercion(other)
259
- # we're avoiding Time#to_datetime cause it's expensive
314
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
260
315
  if other.class == Time
261
316
  compare_without_coercion(other)
262
317
  elsif other.is_a?(Time)
@@ -278,4 +333,33 @@ class Time
278
333
  alias_method :eql_without_coercion, :eql?
279
334
  alias_method :eql?, :eql_with_coercion
280
335
 
336
+ # Returns a new time the specified number of days ago.
337
+ def prev_day(days = 1)
338
+ advance(days: -days)
339
+ end
340
+
341
+ # Returns a new time the specified number of days in the future.
342
+ def next_day(days = 1)
343
+ advance(days: days)
344
+ end
345
+
346
+ # Returns a new time the specified number of months ago.
347
+ def prev_month(months = 1)
348
+ advance(months: -months)
349
+ end
350
+
351
+ # Returns a new time the specified number of months in the future.
352
+ def next_month(months = 1)
353
+ advance(months: months)
354
+ end
355
+
356
+ # Returns a new time the specified number of years ago.
357
+ def prev_year(years = 1)
358
+ advance(years: -years)
359
+ end
360
+
361
+ # Returns a new time the specified number of years in the future.
362
+ def next_year(years = 1)
363
+ advance(years: years)
364
+ end
281
365
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date_and_time/compatibility"
2
- require "active_support/core_ext/module/remove_method"
4
+ require "active_support/core_ext/module/redefine_method"
3
5
 
4
6
  class Time
5
7
  include DateAndTime::Compatibility
6
8
 
7
- remove_possible_method :to_time
9
+ silence_redefinition_of_method :to_time
8
10
 
9
11
  # Either return +self+ or the time in the local system timezone depending
10
12
  # on the setting of +ActiveSupport.to_time_preserves_timezone+.
@@ -1,30 +1,35 @@
1
- require 'active_support/inflector/methods'
2
- require 'active_support/values/time_zone'
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+ require "active_support/inflector/methods"
5
+ require "active_support/values/time_zone"
3
6
 
4
7
  class Time
5
8
  DATE_FORMATS = {
6
- :db => '%Y-%m-%d %H:%M:%S',
7
- :number => '%Y%m%d%H%M%S',
8
- :nsec => '%Y%m%d%H%M%S%9N',
9
- :time => '%H:%M',
10
- :short => '%d %b %H:%M',
11
- :long => '%B %d, %Y %H:%M',
12
- :long_ordinal => lambda { |time|
9
+ db: "%Y-%m-%d %H:%M:%S",
10
+ inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
11
+ number: "%Y%m%d%H%M%S",
12
+ nsec: "%Y%m%d%H%M%S%9N",
13
+ usec: "%Y%m%d%H%M%S%6N",
14
+ time: "%H:%M",
15
+ short: "%d %b %H:%M",
16
+ long: "%B %d, %Y %H:%M",
17
+ long_ordinal: lambda { |time|
13
18
  day_format = ActiveSupport::Inflector.ordinalize(time.day)
14
19
  time.strftime("%B #{day_format}, %Y %H:%M")
15
20
  },
16
- :rfc822 => lambda { |time|
21
+ rfc822: lambda { |time|
17
22
  offset_format = time.formatted_offset(false)
18
23
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
19
24
  },
20
- :iso8601 => lambda { |time| time.iso8601 }
25
+ iso8601: lambda { |time| time.iso8601 }
21
26
  }
22
27
 
23
28
  # Converts to a formatted string. See DATE_FORMATS for built-in formats.
24
29
  #
25
30
  # This method is aliased to <tt>to_s</tt>.
26
31
  #
27
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
32
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
28
33
  #
29
34
  # time.to_formatted_s(:time) # => "06:10"
30
35
  # time.to_s(:time) # => "06:10"
@@ -55,11 +60,15 @@ class Time
55
60
  alias_method :to_default_s, :to_s
56
61
  alias_method :to_s, :to_formatted_s
57
62
 
58
- # Returns the UTC offset as an +HH:MM formatted string.
63
+ # Returns a formatted string of the offset from UTC, or an alternative
64
+ # string if the time zone is already UTC.
59
65
  #
60
66
  # Time.local(2000).formatted_offset # => "-06:00"
61
67
  # Time.local(2000).formatted_offset(false) # => "-0600"
62
68
  def formatted_offset(colon = true, alternate_utc_string = nil)
63
69
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
64
70
  end
71
+
72
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
73
+ alias_method :rfc3339, :xmlschema
65
74
  end
@@ -1,6 +1,8 @@
1
- require 'active_support/time_with_zone'
2
- require 'active_support/core_ext/time/acts_like'
3
- require 'active_support/core_ext/date_and_time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/time_with_zone"
4
+ require "active_support/core_ext/time/acts_like"
5
+ require "active_support/core_ext/date_and_time/zones"
4
6
 
5
7
  class Time
6
8
  include DateAndTime::Zones
@@ -26,7 +28,7 @@ class Time
26
28
  # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
27
29
  #
28
30
  # class ApplicationController < ActionController::Base
29
- # around_filter :set_time_zone
31
+ # around_action :set_time_zone
30
32
  #
31
33
  # def set_time_zone
32
34
  # if logged_in?
@@ -40,7 +42,23 @@ class Time
40
42
  Thread.current[:time_zone] = find_zone!(time_zone)
41
43
  end
42
44
 
43
- # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
45
+ # Allows override of <tt>Time.zone</tt> locally inside supplied block;
46
+ # resets <tt>Time.zone</tt> to existing value when done.
47
+ #
48
+ # class ApplicationController < ActionController::Base
49
+ # around_action :set_time_zone
50
+ #
51
+ # private
52
+ #
53
+ # def set_time_zone
54
+ # Time.use_zone(current_user.timezone) { yield }
55
+ # end
56
+ # end
57
+ #
58
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
59
+ # objects that have already been created, e.g. any model timestamp
60
+ # attributes that have been read before the block will remain in
61
+ # the application's default timezone.
44
62
  def use_zone(time_zone)
45
63
  new_zone = find_zone!(time_zone)
46
64
  begin
@@ -51,12 +69,22 @@ class Time
51
69
  end
52
70
  end
53
71
 
54
- # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
72
+ # Returns a TimeZone instance matching the time zone provided.
73
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
74
+ # Raises an +ArgumentError+ for invalid time zones.
75
+ #
76
+ # Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
77
+ # Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
78
+ # Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
79
+ # Time.find_zone! nil # => nil
80
+ # Time.find_zone! false # => false
81
+ # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
55
82
  def find_zone!(time_zone)
56
83
  if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
57
84
  time_zone
58
85
  else
59
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
86
+ # Look up the timezone based on the identifier (unless we've been
87
+ # passed a TZInfo::Timezone)
60
88
  unless time_zone.respond_to?(:period_for_local)
61
89
  time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
62
90
  end
@@ -72,6 +100,12 @@ class Time
72
100
  raise ArgumentError, "Invalid Timezone: #{time_zone}"
73
101
  end
74
102
 
103
+ # Returns a TimeZone instance matching the time zone provided.
104
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
105
+ # Returns +nil+ for invalid time zones.
106
+ #
107
+ # Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
108
+ # Time.find_zone "NOT-A-TIMEZONE" # => nil
75
109
  def find_zone(time_zone)
76
110
  find_zone!(time_zone) rescue nil
77
111
  end
@@ -1,6 +1,7 @@
1
- require 'active_support/core_ext/time/acts_like'
2
- require 'active_support/core_ext/time/calculations'
3
- require 'active_support/core_ext/time/compatibility'
4
- require 'active_support/core_ext/time/conversions'
5
- require 'active_support/core_ext/time/marshal'
6
- require 'active_support/core_ext/time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/time/acts_like"
4
+ require "active_support/core_ext/time/calculations"
5
+ require "active_support/core_ext/time/compatibility"
6
+ require "active_support/core_ext/time/conversions"
7
+ require "active_support/core_ext/time/zones"
@@ -1,18 +1,17 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'uri'
4
- str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
5
- parser = URI::Parser.new
3
+ require "uri"
6
4
 
7
- unless str == parser.unescape(parser.escape(str))
5
+ if RUBY_VERSION < "2.6.0"
6
+ require "active_support/core_ext/module/redefine_method"
8
7
  URI::Parser.class_eval do
9
- remove_method :unescape
8
+ silence_redefinition_of_method :unescape
10
9
  def unescape(str, escaped = /%[a-fA-F\d]{2}/)
11
10
  # TODO: Are we actually sure that ASCII == UTF-8?
12
11
  # YK: My initial experiments say yes, but let's be sure please
13
12
  enc = str.encoding
14
13
  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
15
- str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
14
+ str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
16
15
  end
17
16
  end
18
17
  end
@@ -20,7 +19,11 @@ end
20
19
  module URI
21
20
  class << self
22
21
  def parser
23
- @parser ||= URI::Parser.new
22
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
23
+ URI.parser is deprecated and will be removed in Rails 7.0.
24
+ Use `URI::DEFAULT_PARSER` instead.
25
+ MSG
26
+ URI::DEFAULT_PARSER
24
27
  end
25
28
  end
26
29
  end
@@ -1,3 +1,5 @@
1
- Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).sort.each do |path|
2
4
  require path
3
5
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
4
+ def before_setup
5
+ ActiveSupport::CurrentAttributes.reset_all
6
+ super
7
+ end
8
+
9
+ def after_teardown
10
+ super
11
+ ActiveSupport::CurrentAttributes.reset_all
12
+ end
13
+ end