activesupport 4.0.12 → 7.0.2.4

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 (295) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +249 -501
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -5
  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 +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +41 -13
  9. data/lib/active_support/benchmarkable.rb +7 -15
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +96 -74
  12. data/lib/active_support/cache/mem_cache_store.rb +211 -103
  13. data/lib/active_support/cache/memory_store.rb +90 -58
  14. data/lib/active_support/cache/null_store.rb +19 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +468 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +86 -83
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  18. data/lib/active_support/cache.rb +580 -241
  19. data/lib/active_support/callbacks.rb +812 -425
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +103 -14
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
  23. data/lib/active_support/concurrency/share_lock.rb +226 -0
  24. data/lib/active_support/configurable.rb +21 -19
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +47 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +35 -44
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +26 -16
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  34. data/lib/active_support/core_ext/array.rb +10 -7
  35. data/lib/active_support/core_ext/benchmark.rb +5 -3
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  37. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  38. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  40. data/lib/active_support/core_ext/class/subclasses.rb +25 -26
  41. data/lib/active_support/core_ext/class.rb +4 -4
  42. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  43. data/lib/active_support/core_ext/date/blank.rb +14 -0
  44. data/lib/active_support/core_ext/date/calculations.rb +31 -18
  45. data/lib/active_support/core_ext/date/conversions.rb +43 -32
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +5 -34
  48. data/lib/active_support/core_ext/date.rb +7 -4
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +8 -4
  59. data/lib/active_support/core_ext/digest/uuid.rb +79 -0
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +249 -17
  62. data/lib/active_support/core_ext/file/atomic.rb +41 -32
  63. data/lib/active_support/core_ext/file.rb +3 -1
  64. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +14 -5
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +39 -56
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -23
  72. data/lib/active_support/core_ext/hash.rb +10 -8
  73. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +11 -33
  76. data/lib/active_support/core_ext/integer.rb +5 -3
  77. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  80. data/lib/active_support/core_ext/kernel.rb +5 -4
  81. data/lib/active_support/core_ext/load_error.rb +5 -21
  82. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  83. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  84. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
  87. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  88. data/lib/active_support/core_ext/module/delegation.rb +172 -45
  89. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  90. data/lib/active_support/core_ext/module/introspection.rb +23 -38
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -10
  94. data/lib/active_support/core_ext/name_error.rb +45 -4
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  99. data/lib/active_support/core_ext/numeric.rb +6 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +70 -20
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  104. data/lib/active_support/core_ext/object/duplicable.rb +17 -47
  105. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +244 -0
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  110. data/lib/active_support/core_ext/object/try.rb +106 -26
  111. data/lib/active_support/core_ext/object/with_options.rb +64 -5
  112. data/lib/active_support/core_ext/object.rb +14 -12
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +18 -17
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  121. data/lib/active_support/core_ext/range.rb +7 -4
  122. data/lib/active_support/core_ext/regexp.rb +10 -1
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string/access.rb +42 -51
  125. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  126. data/lib/active_support/core_ext/string/conversions.rb +18 -13
  127. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  128. data/lib/active_support/core_ext/string/filters.rb +97 -7
  129. data/lib/active_support/core_ext/string/indent.rb +6 -4
  130. data/lib/active_support/core_ext/string/inflections.rb +106 -25
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  133. data/lib/active_support/core_ext/string/output_safety.rb +227 -54
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +6 -5
  136. data/lib/active_support/core_ext/string/zones.rb +4 -1
  137. data/lib/active_support/core_ext/string.rb +15 -13
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  141. data/lib/active_support/core_ext/time/calculations.rb +178 -116
  142. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  143. data/lib/active_support/core_ext/time/conversions.rb +37 -25
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +44 -42
  146. data/lib/active_support/core_ext/time.rb +8 -5
  147. data/lib/active_support/core_ext/uri.rb +4 -25
  148. data/lib/active_support/core_ext.rb +4 -2
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +3 -1
  152. data/lib/active_support/dependencies/interlock.rb +49 -0
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +71 -696
  155. data/lib/active_support/deprecation/behaviors.rb +65 -16
  156. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  159. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
  161. data/lib/active_support/deprecation/reporting.rb +81 -18
  162. data/lib/active_support/deprecation.rb +19 -11
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  166. data/lib/active_support/duration/iso8601_serializer.rb +67 -0
  167. data/lib/active_support/duration.rb +437 -39
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +117 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +170 -0
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +151 -0
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +8 -0
  178. data/lib/active_support/file_update_checker.rb +62 -37
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +17 -0
  181. data/lib/active_support/gzip.rb +7 -5
  182. data/lib/active_support/hash_with_indifferent_access.rb +207 -54
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +10 -6
  185. data/lib/active_support/i18n_railtie.rb +48 -19
  186. data/lib/active_support/inflections.rb +19 -12
  187. data/lib/active_support/inflector/inflections.rb +97 -37
  188. data/lib/active_support/inflector/methods.rb +192 -157
  189. data/lib/active_support/inflector/transliterate.rb +83 -33
  190. data/lib/active_support/inflector.rb +7 -5
  191. data/lib/active_support/isolated_execution_state.rb +64 -0
  192. data/lib/active_support/json/decoding.rb +37 -42
  193. data/lib/active_support/json/encoding.rb +93 -293
  194. data/lib/active_support/json.rb +4 -2
  195. data/lib/active_support/key_generator.rb +30 -47
  196. data/lib/active_support/lazy_load_hooks.rb +54 -21
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +10 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  200. data/lib/active_support/log_subscriber.rb +61 -18
  201. data/lib/active_support/logger.rb +40 -4
  202. data/lib/active_support/logger_silence.rb +17 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +69 -0
  204. data/lib/active_support/message_encryptor.rb +178 -55
  205. data/lib/active_support/message_verifier.rb +195 -26
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +45 -92
  210. data/lib/active_support/multibyte/unicode.rb +44 -377
  211. data/lib/active_support/multibyte.rb +5 -3
  212. data/lib/active_support/notifications/fanout.rb +177 -44
  213. data/lib/active_support/notifications/instrumenter.rb +117 -17
  214. data/lib/active_support/notifications.rb +106 -39
  215. data/lib/active_support/number_helper/number_converter.rb +181 -0
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  223. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  224. data/lib/active_support/number_helper.rb +152 -394
  225. data/lib/active_support/option_merger.rb +18 -5
  226. data/lib/active_support/ordered_hash.rb +8 -6
  227. data/lib/active_support/ordered_options.rb +43 -7
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +24 -11
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +10 -11
  232. data/lib/active_support/railtie.rb +118 -12
  233. data/lib/active_support/reloader.rb +130 -0
  234. data/lib/active_support/rescuable.rb +112 -57
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +38 -0
  238. data/lib/active_support/string_inquirer.rb +11 -4
  239. data/lib/active_support/subscriber.rb +109 -39
  240. data/lib/active_support/tagged_logging.rb +54 -17
  241. data/lib/active_support/test_case.rb +121 -37
  242. data/lib/active_support/testing/assertions.rb +177 -39
  243. data/lib/active_support/testing/autorun.rb +5 -3
  244. data/lib/active_support/testing/constant_lookup.rb +3 -6
  245. data/lib/active_support/testing/declarative.rb +10 -22
  246. data/lib/active_support/testing/deprecation.rb +65 -11
  247. data/lib/active_support/testing/file_fixtures.rb +38 -0
  248. data/lib/active_support/testing/isolation.rb +56 -87
  249. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  255. data/lib/active_support/testing/stream.rb +41 -0
  256. data/lib/active_support/testing/tagged_logging.rb +6 -4
  257. data/lib/active_support/testing/time_helpers.rb +246 -0
  258. data/lib/active_support/time.rb +13 -13
  259. data/lib/active_support/time_with_zone.rb +315 -90
  260. data/lib/active_support/values/time_zone.rb +306 -135
  261. data/lib/active_support/version.rb +6 -7
  262. data/lib/active_support/xml_mini/jdom.rb +117 -115
  263. data/lib/active_support/xml_mini/libxml.rb +22 -21
  264. data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
  265. data/lib/active_support/xml_mini/nokogiri.rb +19 -19
  266. data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
  267. data/lib/active_support/xml_mini/rexml.rb +25 -17
  268. data/lib/active_support/xml_mini.rb +67 -56
  269. data/lib/active_support.rb +58 -3
  270. metadata +125 -66
  271. data/lib/active_support/basic_object.rb +0 -11
  272. data/lib/active_support/buffered_logger.rb +0 -21
  273. data/lib/active_support/concurrency/latch.rb +0 -27
  274. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  275. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  276. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  277. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  278. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  279. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  280. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  281. data/lib/active_support/core_ext/logger.rb +0 -67
  282. data/lib/active_support/core_ext/marshal.rb +0 -21
  283. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  284. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  285. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  286. data/lib/active_support/core_ext/proc.rb +0 -17
  287. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  288. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  289. data/lib/active_support/core_ext/struct.rb +0 -6
  290. data/lib/active_support/core_ext/thread.rb +0 -79
  291. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  292. data/lib/active_support/file_watcher.rb +0 -36
  293. data/lib/active_support/json/variable.rb +0 -18
  294. data/lib/active_support/testing/pending.rb +0 -14
  295. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -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/deprecation'
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,39 +29,10 @@ class Time
26
29
  end
27
30
  end
28
31
 
29
- # *DEPRECATED*: Use +Time#utc+ or +Time#local+ instead.
30
- #
31
- # Returns a new Time if requested year can be accommodated by Ruby's Time class
32
- # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
33
- # otherwise returns a DateTime.
34
- def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
35
- ActiveSupport::Deprecation.warn 'time_with_datetime_fallback is deprecated. Use Time#utc or Time#local instead', caller
36
- time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
37
-
38
- # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
39
- if time.year == year
40
- time
41
- else
42
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
43
- end
44
- rescue
45
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
46
- end
47
-
48
- # *DEPRECATED*: Use +Time#utc+ instead.
49
- #
50
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
51
- def utc_time(*args)
52
- ActiveSupport::Deprecation.warn 'utc_time is deprecated. Use Time#utc instead', caller
53
- time_with_datetime_fallback(:utc, *args)
54
- end
55
-
56
- # *DEPRECATED*: Use +Time#local+ instead.
57
- #
58
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
59
- def local_time(*args)
60
- ActiveSupport::Deprecation.warn 'local_time is deprecated. Use Time#local instead', caller
61
- time_with_datetime_fallback(:local, *args)
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
62
36
  end
63
37
 
64
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>.
@@ -68,13 +42,15 @@ class Time
68
42
 
69
43
  # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
70
44
  # instances can be used when called with a single argument
71
- def at_with_coercion(*args)
72
- return at_without_coercion(*args) if args.size != 1
45
+ def at_with_coercion(*args, **kwargs)
46
+ return at_without_coercion(*args, **kwargs) if args.size != 1 || !kwargs.empty?
73
47
 
74
48
  # Time.at can be called with a time or numerical value
75
49
  time_or_number = args.first
76
50
 
77
- 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)
78
54
  at_without_coercion(time_or_number.to_f).getlocal
79
55
  else
80
56
  at_without_coercion(time_or_number)
@@ -82,11 +58,38 @@ class Time
82
58
  end
83
59
  alias_method :at_without_coercion, :at
84
60
  alias_method :at, :at_with_coercion
61
+
62
+ # Creates a +Time+ instance from an RFC 3339 string.
63
+ #
64
+ # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
65
+ #
66
+ # If the time or offset components are missing then an +ArgumentError+ will be raised.
67
+ #
68
+ # Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
69
+ def rfc3339(str)
70
+ parts = Date._rfc3339(str)
71
+
72
+ raise ArgumentError, "invalid date" if parts.empty?
73
+
74
+ Time.new(
75
+ parts.fetch(:year),
76
+ parts.fetch(:mon),
77
+ parts.fetch(:mday),
78
+ parts.fetch(:hour),
79
+ parts.fetch(:min),
80
+ parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
81
+ parts.fetch(:offset)
82
+ )
83
+ end
85
84
  end
86
85
 
87
- # Seconds since midnight: Time.now.seconds_since_midnight
86
+ # Returns the number of seconds since 00:00:00.
87
+ #
88
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
89
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
90
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
88
91
  def seconds_since_midnight
89
- to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
92
+ to_i - change(hour: 0).to_i + (usec / 1.0e+6)
90
93
  end
91
94
 
92
95
  # Returns the number of seconds until 23:59:59.
@@ -98,39 +101,84 @@ class Time
98
101
  end_of_day.to_i - to_i
99
102
  end
100
103
 
104
+ # Returns the fraction of a second as a +Rational+
105
+ #
106
+ # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
107
+ def sec_fraction
108
+ subsec
109
+ end
110
+
111
+ unless Time.method_defined?(:floor)
112
+ def floor(precision = 0)
113
+ change(nsec: 0) + subsec.floor(precision)
114
+ end
115
+ end
116
+
117
+ # Restricted Ruby version due to a bug in `Time#ceil`
118
+ # See https://bugs.ruby-lang.org/issues/17025 for more details
119
+ if RUBY_VERSION <= "2.8"
120
+ remove_possible_method :ceil
121
+ def ceil(precision = 0)
122
+ change(nsec: 0) + subsec.ceil(precision)
123
+ end
124
+ end
125
+
101
126
  # Returns a new Time where one or more of the elements have been changed according
102
127
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
103
- # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
104
- # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
105
- # sec and usec is set to 0. The +options+ parameter takes a hash with any of these
106
- # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
107
- # <tt>:sec</tt>, <tt>:usec</tt>.
128
+ # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
129
+ # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
130
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
131
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
132
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
133
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
108
134
  #
109
135
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
110
136
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
111
137
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
112
138
  def change(options)
113
- new_year = options.fetch(:year, year)
114
- new_month = options.fetch(:month, month)
115
- new_day = options.fetch(:day, day)
116
- new_hour = options.fetch(:hour, hour)
117
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
118
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
119
- new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
120
-
121
- if utc?
122
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
139
+ new_year = options.fetch(:year, year)
140
+ new_month = options.fetch(:month, month)
141
+ new_day = options.fetch(:day, day)
142
+ new_hour = options.fetch(:hour, hour)
143
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
144
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
145
+ new_offset = options.fetch(:offset, nil)
146
+
147
+ if new_nsec = options[:nsec]
148
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
149
+ new_usec = Rational(new_nsec, 1000)
150
+ else
151
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
152
+ end
153
+
154
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
155
+
156
+ new_sec += Rational(new_usec, 1000000)
157
+
158
+ if new_offset
159
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
160
+ elsif utc?
161
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
162
+ elsif zone&.respond_to?(:utc_to_local)
163
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
123
164
  elsif zone
124
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
165
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
125
166
  else
126
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
167
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
127
168
  end
128
169
  end
129
170
 
130
- # Uses Date to provide precise Time calculations for years, months, and days.
131
- # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
132
- # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
133
- # <tt>:minutes</tt>, <tt>:seconds</tt>.
171
+ # Uses Date to provide precise Time calculations for years, months, and days
172
+ # according to the proleptic Gregorian calendar. The +options+ parameter
173
+ # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
174
+ # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
175
+ # <tt>:seconds</tt>.
176
+ #
177
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
178
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
179
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
180
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
181
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
134
182
  def advance(options)
135
183
  unless options[:weeks].nil?
136
184
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -142,8 +190,8 @@ class Time
142
190
  options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
143
191
  end
144
192
 
145
- d = to_date.advance(options)
146
- time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
193
+ d = to_date.gregorian.advance(options)
194
+ time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
147
195
  seconds_to_advance = \
148
196
  options.fetch(:seconds, 0) +
149
197
  options.fetch(:minutes, 0) * 60 +
@@ -171,82 +219,65 @@ class Time
171
219
 
172
220
  # Returns a new Time representing the start of the day (0:00)
173
221
  def beginning_of_day
174
- #(self - seconds_since_midnight).change(usec: 0)
175
- change(:hour => 0)
222
+ change(hour: 0)
176
223
  end
177
224
  alias :midnight :beginning_of_day
178
225
  alias :at_midnight :beginning_of_day
179
226
  alias :at_beginning_of_day :beginning_of_day
180
227
 
181
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
228
+ # Returns a new Time representing the middle of the day (12:00)
229
+ def middle_of_day
230
+ change(hour: 12)
231
+ end
232
+ alias :midday :middle_of_day
233
+ alias :noon :middle_of_day
234
+ alias :at_midday :middle_of_day
235
+ alias :at_noon :middle_of_day
236
+ alias :at_middle_of_day :middle_of_day
237
+
238
+ # Returns a new Time representing the end of the day, 23:59:59.999999
182
239
  def end_of_day
183
240
  change(
184
- :hour => 23,
185
- :min => 59,
186
- :sec => 59,
187
- :usec => Rational(999999999, 1000)
241
+ hour: 23,
242
+ min: 59,
243
+ sec: 59,
244
+ usec: Rational(999999999, 1000)
188
245
  )
189
246
  end
190
247
  alias :at_end_of_day :end_of_day
191
248
 
192
249
  # Returns a new Time representing the start of the hour (x:00)
193
250
  def beginning_of_hour
194
- change(:min => 0)
251
+ change(min: 0)
195
252
  end
196
253
  alias :at_beginning_of_hour :beginning_of_hour
197
254
 
198
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
255
+ # Returns a new Time representing the end of the hour, x:59:59.999999
199
256
  def end_of_hour
200
257
  change(
201
- :min => 59,
202
- :sec => 59,
203
- :usec => Rational(999999999, 1000)
258
+ min: 59,
259
+ sec: 59,
260
+ usec: Rational(999999999, 1000)
204
261
  )
205
262
  end
206
263
  alias :at_end_of_hour :end_of_hour
207
264
 
208
265
  # Returns a new Time representing the start of the minute (x:xx:00)
209
266
  def beginning_of_minute
210
- change(:sec => 0)
267
+ change(sec: 0)
211
268
  end
212
269
  alias :at_beginning_of_minute :beginning_of_minute
213
270
 
214
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
271
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
215
272
  def end_of_minute
216
273
  change(
217
- :sec => 59,
218
- :usec => Rational(999999999, 1000)
274
+ sec: 59,
275
+ usec: Rational(999999999, 1000)
219
276
  )
220
277
  end
221
278
  alias :at_end_of_minute :end_of_minute
222
279
 
223
- # Returns a Range representing the whole day of the current time.
224
- def all_day
225
- beginning_of_day..end_of_day
226
- end
227
-
228
- # Returns a Range representing the whole week of the current time.
229
- # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
230
- def all_week(start_day = Date.beginning_of_week)
231
- beginning_of_week(start_day)..end_of_week(start_day)
232
- end
233
-
234
- # Returns a Range representing the whole month of the current time.
235
- def all_month
236
- beginning_of_month..end_of_month
237
- end
238
-
239
- # Returns a Range representing the whole quarter of the current time.
240
- def all_quarter
241
- beginning_of_quarter..end_of_quarter
242
- end
243
-
244
- # Returns a Range representing the whole year of the current time.
245
- def all_year
246
- beginning_of_year..end_of_year
247
- end
248
-
249
- def plus_with_duration(other) #:nodoc:
280
+ def plus_with_duration(other) # :nodoc:
250
281
  if ActiveSupport::Duration === other
251
282
  other.since(self)
252
283
  else
@@ -256,7 +287,7 @@ class Time
256
287
  alias_method :plus_without_duration, :+
257
288
  alias_method :+, :plus_with_duration
258
289
 
259
- def minus_with_duration(other) #:nodoc:
290
+ def minus_with_duration(other) # :nodoc:
260
291
  if ActiveSupport::Duration === other
261
292
  other.until(self)
262
293
  else
@@ -274,13 +305,15 @@ class Time
274
305
  other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
275
306
  end
276
307
  alias_method :minus_without_coercion, :-
277
- alias_method :-, :minus_with_coercion
308
+ alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
278
309
 
279
310
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
280
311
  # can be chronologically compared with a Time
281
312
  def compare_with_coercion(other)
282
- # we're avoiding Time#to_datetime cause it's expensive
283
- if other.is_a?(Time)
313
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
314
+ if other.class == Time
315
+ compare_without_coercion(other)
316
+ elsif other.is_a?(Time)
284
317
  compare_without_coercion(other.to_time)
285
318
  else
286
319
  to_datetime <=> other
@@ -299,4 +332,33 @@ class Time
299
332
  alias_method :eql_without_coercion, :eql?
300
333
  alias_method :eql?, :eql_with_coercion
301
334
 
335
+ # Returns a new time the specified number of days ago.
336
+ def prev_day(days = 1)
337
+ advance(days: -days)
338
+ end
339
+
340
+ # Returns a new time the specified number of days in the future.
341
+ def next_day(days = 1)
342
+ advance(days: days)
343
+ end
344
+
345
+ # Returns a new time the specified number of months ago.
346
+ def prev_month(months = 1)
347
+ advance(months: -months)
348
+ end
349
+
350
+ # Returns a new time the specified number of months in the future.
351
+ def next_month(months = 1)
352
+ advance(months: months)
353
+ end
354
+
355
+ # Returns a new time the specified number of years ago.
356
+ def prev_year(years = 1)
357
+ advance(years: -years)
358
+ end
359
+
360
+ # Returns a new time the specified number of years in the future.
361
+ def next_year(years = 1)
362
+ advance(years: years)
363
+ end
302
364
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/date_and_time/compatibility"
4
+ require "active_support/core_ext/module/redefine_method"
5
+
6
+ class Time
7
+ include DateAndTime::Compatibility
8
+
9
+ silence_redefinition_of_method :to_time
10
+
11
+ # Either return +self+ or the time in the local system timezone depending
12
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
13
+ def to_time
14
+ preserve_timezone ? self : getlocal
15
+ end
16
+ end
@@ -1,41 +1,48 @@
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
+ },
25
+ iso8601: lambda { |time| time.iso8601 }
20
26
  }
21
27
 
22
- # Converts to a formatted string. See DATE_FORMATS for builtin formats.
28
+ # Converts to a formatted string. See DATE_FORMATS for built-in formats.
23
29
  #
24
- # This method is aliased to <tt>to_s</tt>.
30
+ # This method is aliased to <tt>to_formatted_s</tt>.
25
31
  #
26
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
32
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
27
33
  #
34
+ # time.to_fs(:time) # => "06:10"
28
35
  # time.to_formatted_s(:time) # => "06:10"
29
- # time.to_s(:time) # => "06:10"
30
36
  #
31
- # time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
32
- # time.to_formatted_s(:number) # => "20070118061017"
33
- # time.to_formatted_s(:short) # => "18 Jan 06:10"
34
- # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
35
- # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
36
- # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
37
+ # time.to_fs(:db) # => "2007-01-18 06:10:17"
38
+ # time.to_fs(:number) # => "20070118061017"
39
+ # time.to_fs(:short) # => "18 Jan 06:10"
40
+ # time.to_fs(:long) # => "January 18, 2007 06:10"
41
+ # time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
42
+ # time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
43
+ # time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
37
44
  #
38
- # == Adding your own time formats to +to_formatted_s+
45
+ # == Adding your own time formats to +to_fs+
39
46
  # You can add your own formats to the Time::DATE_FORMATS hash.
40
47
  # Use the format name as the hash key and either a strftime string
41
48
  # or Proc instance that takes a time argument as the value.
@@ -43,21 +50,26 @@ class Time
43
50
  # # config/initializers/time_formats.rb
44
51
  # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
45
52
  # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
46
- def to_formatted_s(format = :default)
53
+ def to_fs(format = :default)
47
54
  if formatter = DATE_FORMATS[format]
48
55
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
49
56
  else
57
+ # Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
50
58
  to_default_s
51
59
  end
52
60
  end
61
+ alias_method :to_formatted_s, :to_fs
53
62
  alias_method :to_default_s, :to_s
54
- alias_method :to_s, :to_formatted_s
55
63
 
56
- # Returns the UTC offset as an +HH:MM formatted string.
64
+ # Returns a formatted string of the offset from UTC, or an alternative
65
+ # string if the time zone is already UTC.
57
66
  #
58
67
  # Time.local(2000).formatted_offset # => "-06:00"
59
68
  # Time.local(2000).formatted_offset(false) # => "-0600"
60
69
  def formatted_offset(colon = true, alternate_utc_string = nil)
61
70
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
62
71
  end
72
+
73
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
74
+ alias_method :rfc3339, :xmlschema
63
75
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ class Time
6
+ NOT_SET = Object.new # :nodoc:
7
+ def to_s(format = NOT_SET) # :nodoc:
8
+ if formatter = DATE_FORMATS[format]
9
+ ActiveSupport::Deprecation.warn(
10
+ "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
11
+ )
12
+ formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
13
+ elsif format == NOT_SET
14
+ to_default_s
15
+ else
16
+ ActiveSupport::Deprecation.warn(
17
+ "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
18
+ )
19
+ to_default_s
20
+ end
21
+ end
22
+ end