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,14 +1,9 @@
1
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
2
4
 
3
5
  class DateTime
4
6
  class << self
5
- # *DEPRECATED*: Use +DateTime.civil_from_format+ directly.
6
- def local_offset
7
- ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.'
8
-
9
- ::Time.local(2012).utc_offset.to_r / 86400
10
- end
11
-
12
7
  # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
13
8
  # <tt>config.time_zone</tt> are set, otherwise returns
14
9
  # <tt>Time.now.to_datetime</tt>.
@@ -17,17 +12,11 @@ class DateTime
17
12
  end
18
13
  end
19
14
 
20
- # Tells whether the DateTime object's datetime lies in the past.
21
- def past?
22
- self < ::DateTime.current
23
- end
24
-
25
- # Tells whether the DateTime object's datetime lies in the future.
26
- def future?
27
- self > ::DateTime.current
28
- end
29
-
30
- # Seconds since midnight: DateTime.now.seconds_since_midnight.
15
+ # Returns the number of seconds since 00:00:00.
16
+ #
17
+ # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0
18
+ # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296
19
+ # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399
31
20
  def seconds_since_midnight
32
21
  sec + (min * 60) + (hour * 3600)
33
22
  end
@@ -41,6 +30,13 @@ class DateTime
41
30
  end_of_day.to_i - to_i
42
31
  end
43
32
 
33
+ # Returns the fraction of a second as a +Rational+
34
+ #
35
+ # DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
36
+ def subsec
37
+ sec_fraction
38
+ end
39
+
44
40
  # Returns a new DateTime where one or more of the elements have been changed
45
41
  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
46
42
  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
@@ -53,13 +49,23 @@ class DateTime
53
49
  # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
54
50
  # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
55
51
  def change(options)
52
+ if new_nsec = options[:nsec]
53
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
54
+ new_fraction = Rational(new_nsec, 1000000000)
55
+ else
56
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
57
+ new_fraction = Rational(new_usec, 1000000)
58
+ end
59
+
60
+ raise ArgumentError, "argument out of range" if new_fraction >= 1
61
+
56
62
  ::DateTime.civil(
57
63
  options.fetch(:year, year),
58
64
  options.fetch(:month, month),
59
65
  options.fetch(:day, day),
60
66
  options.fetch(:hour, hour),
61
67
  options.fetch(:min, options[:hour] ? 0 : min),
62
- options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
68
+ options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction,
63
69
  options.fetch(:offset, offset),
64
70
  options.fetch(:start, start)
65
71
  )
@@ -70,8 +76,18 @@ class DateTime
70
76
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
71
77
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
72
78
  def advance(options)
79
+ unless options[:weeks].nil?
80
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
81
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
82
+ end
83
+
84
+ unless options[:days].nil?
85
+ options[:days], partial_days = options[:days].divmod(1)
86
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
87
+ end
88
+
73
89
  d = to_date.advance(options)
74
- datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
90
+ datetime_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
75
91
  seconds_to_advance = \
76
92
  options.fetch(:seconds, 0) +
77
93
  options.fetch(:minutes, 0) * 60 +
@@ -80,7 +96,7 @@ class DateTime
80
96
  if seconds_to_advance.zero?
81
97
  datetime_advanced_by_date
82
98
  else
83
- datetime_advanced_by_date.since seconds_to_advance
99
+ datetime_advanced_by_date.since(seconds_to_advance)
84
100
  end
85
101
  end
86
102
 
@@ -94,56 +110,84 @@ class DateTime
94
110
  # instance time. Do not use this method in combination with x.months, use
95
111
  # months_since instead!
96
112
  def since(seconds)
97
- self + Rational(seconds.round, 86400)
113
+ self + Rational(seconds, 86400)
98
114
  end
99
115
  alias :in :since
100
116
 
101
117
  # Returns a new DateTime representing the start of the day (0:00).
102
118
  def beginning_of_day
103
- change(:hour => 0)
119
+ change(hour: 0)
104
120
  end
105
121
  alias :midnight :beginning_of_day
106
122
  alias :at_midnight :beginning_of_day
107
123
  alias :at_beginning_of_day :beginning_of_day
108
124
 
125
+ # Returns a new DateTime representing the middle of the day (12:00)
126
+ def middle_of_day
127
+ change(hour: 12)
128
+ end
129
+ alias :midday :middle_of_day
130
+ alias :noon :middle_of_day
131
+ alias :at_midday :middle_of_day
132
+ alias :at_noon :middle_of_day
133
+ alias :at_middle_of_day :middle_of_day
134
+
109
135
  # Returns a new DateTime representing the end of the day (23:59:59).
110
136
  def end_of_day
111
- change(:hour => 23, :min => 59, :sec => 59)
137
+ change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
112
138
  end
113
139
  alias :at_end_of_day :end_of_day
114
140
 
115
141
  # Returns a new DateTime representing the start of the hour (hh:00:00).
116
142
  def beginning_of_hour
117
- change(:min => 0)
143
+ change(min: 0)
118
144
  end
119
145
  alias :at_beginning_of_hour :beginning_of_hour
120
146
 
121
147
  # Returns a new DateTime representing the end of the hour (hh:59:59).
122
148
  def end_of_hour
123
- change(:min => 59, :sec => 59)
149
+ change(min: 59, sec: 59, usec: Rational(999999999, 1000))
124
150
  end
125
151
  alias :at_end_of_hour :end_of_hour
126
152
 
127
153
  # Returns a new DateTime representing the start of the minute (hh:mm:00).
128
154
  def beginning_of_minute
129
- change(:sec => 0)
155
+ change(sec: 0)
130
156
  end
131
157
  alias :at_beginning_of_minute :beginning_of_minute
132
158
 
133
159
  # Returns a new DateTime representing the end of the minute (hh:mm:59).
134
160
  def end_of_minute
135
- change(:sec => 59)
161
+ change(sec: 59, usec: Rational(999999999, 1000))
136
162
  end
137
163
  alias :at_end_of_minute :end_of_minute
138
164
 
139
- # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
165
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
166
+ def localtime(utc_offset = nil)
167
+ utc = new_offset(0)
168
+
169
+ Time.utc(
170
+ utc.year, utc.month, utc.day,
171
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
172
+ ).getlocal(utc_offset)
173
+ end
174
+ alias_method :getlocal, :localtime
175
+
176
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
140
177
  #
141
178
  # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
142
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
179
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
143
180
  def utc
144
- new_offset(0)
181
+ utc = new_offset(0)
182
+
183
+ Time.utc(
184
+ utc.year, utc.month, utc.day,
185
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
186
+ )
145
187
  end
188
+ alias_method :getgm, :utc
146
189
  alias_method :getutc, :utc
190
+ alias_method :gmtime, :utc
147
191
 
148
192
  # Returns +true+ if <tt>offset == 0</tt>.
149
193
  def utc?
@@ -158,13 +202,10 @@ class DateTime
158
202
  # Layers additional behavior on DateTime#<=> so that Time and
159
203
  # ActiveSupport::TimeWithZone instances can be compared with a DateTime.
160
204
  def <=>(other)
161
- if other.kind_of?(Infinity)
162
- super
163
- elsif other.respond_to? :to_datetime
164
- super other.to_datetime
205
+ if other.respond_to? :to_datetime
206
+ super other.to_datetime rescue nil
165
207
  else
166
- nil
208
+ super
167
209
  end
168
210
  end
169
-
170
211
  end
@@ -0,0 +1,18 @@
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 DateTime
7
+ include DateAndTime::Compatibility
8
+
9
+ silence_redefinition_of_method :to_time
10
+
11
+ # Either return an instance of +Time+ with the same UTC offset
12
+ # as +self+ or an instance of +Time+ representing the same time
13
+ # in the local system timezone depending on the setting of
14
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
15
+ def to_time
16
+ preserve_timezone ? getlocal(utc_offset) : getlocal
17
+ end
18
+ end
@@ -1,25 +1,29 @@
1
- require 'active_support/inflector/methods'
2
- require 'active_support/core_ext/time/conversions'
3
- require 'active_support/core_ext/date_time/calculations'
4
- require 'active_support/values/time_zone'
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "active_support/inflector/methods"
5
+ require "active_support/core_ext/time/conversions"
6
+ require "active_support/core_ext/date_time/calculations"
7
+ require "active_support/values/time_zone"
5
8
 
6
9
  class DateTime
7
10
  # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
8
11
  #
9
- # This method is aliased to <tt>to_s</tt>.
12
+ # This method is aliased to <tt>to_formatted_s</tt>.
10
13
  #
11
14
  # === Examples
12
15
  # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
13
16
  #
14
- # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
15
- # datetime.to_s(:db) # => "2007-12-04 00:00:00"
16
- # datetime.to_s(:number) # => "20071204000000"
17
- # datetime.to_formatted_s(:short) # => "04 Dec 00:00"
18
- # datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
19
- # datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
20
- # datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
17
+ # datetime.to_fs(:db) # => "2007-12-04 00:00:00"
18
+ # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
19
+ # datetime.to_fs(:number) # => "20071204000000"
20
+ # datetime.to_fs(:short) # => "04 Dec 00:00"
21
+ # datetime.to_fs(:long) # => "December 04, 2007 00:00"
22
+ # datetime.to_fs(:long_ordinal) # => "December 4th, 2007 00:00"
23
+ # datetime.to_fs(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
24
+ # datetime.to_fs(:iso8601) # => "2007-12-04T00:00:00+00:00"
21
25
  #
22
- # == Adding your own datetime formats to to_formatted_s
26
+ # == Adding your own datetime formats to to_fs
23
27
  # DateTime formats are shared with Time. You can add your own to the
24
28
  # Time::DATE_FORMATS hash. Use the format name as the hash key and
25
29
  # either a strftime string or Proc instance that takes a time or
@@ -28,16 +32,18 @@ class DateTime
28
32
  # # config/initializers/time_formats.rb
29
33
  # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
30
34
  # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
31
- def to_formatted_s(format = :default)
35
+ def to_fs(format = :default)
32
36
  if formatter = ::Time::DATE_FORMATS[format]
33
37
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
34
38
  else
35
39
  to_default_s
36
40
  end
37
41
  end
42
+ alias_method :to_formatted_s, :to_fs
38
43
  alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
39
- alias_method :to_s, :to_formatted_s
40
44
 
45
+ # Returns a formatted string of the offset from UTC, or an alternative
46
+ # string if the time zone is already UTC.
41
47
  #
42
48
  # datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
43
49
  # datetime.formatted_offset # => "-06:00"
@@ -48,7 +54,7 @@ class DateTime
48
54
 
49
55
  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
50
56
  def readable_inspect
51
- to_s(:rfc822)
57
+ to_fs(:rfc822)
52
58
  end
53
59
  alias_method :default_inspect, :inspect
54
60
  alias_method :inspect, :readable_inspect
@@ -60,7 +66,7 @@ class DateTime
60
66
  # # => Sun, 01 Jan 2012 00:00:00 +0300
61
67
  # DateTime.civil_from_format :local, 2012, 12, 17
62
68
  # # => Mon, 17 Dec 2012 00:00:00 +0000
63
- def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
69
+ def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0)
64
70
  if utc_or_local.to_sym == :local
65
71
  offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
66
72
  else
@@ -69,9 +75,9 @@ class DateTime
69
75
  civil(year, month, day, hour, min, sec, offset)
70
76
  end
71
77
 
72
- # Converts +self+ to a floating-point number of seconds since the Unix epoch.
78
+ # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
73
79
  def to_f
74
- seconds_since_unix_epoch.to_f
80
+ seconds_since_unix_epoch.to_f + sec_fraction
75
81
  end
76
82
 
77
83
  # Converts +self+ to an integer number of seconds since the Unix epoch.
@@ -90,12 +96,11 @@ class DateTime
90
96
  end
91
97
 
92
98
  private
99
+ def offset_in_seconds
100
+ (offset * 86400).to_i
101
+ end
93
102
 
94
- def offset_in_seconds
95
- (offset * 86400).to_i
96
- end
97
-
98
- def seconds_since_unix_epoch
99
- (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
100
- end
103
+ def seconds_since_unix_epoch
104
+ (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
105
+ end
101
106
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class DateTime
6
+ NOT_SET = Object.new # :nodoc:
7
+ def to_s(format = NOT_SET) # :nodoc:
8
+ if formatter = ::Time::DATE_FORMATS[format]
9
+ ActiveSupport::Deprecation.warn(
10
+ "DateTime#to_s(#{format.inspect}) is deprecated. Please use DateTime#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
+ "DateTime#to_s(#{format.inspect}) is deprecated. Please use DateTime#to_fs(#{format.inspect}) instead."
18
+ )
19
+ to_default_s
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,8 @@
1
- require 'active_support/core_ext/date_time/acts_like'
2
- require 'active_support/core_ext/date_time/calculations'
3
- require 'active_support/core_ext/date_time/conversions'
4
- require 'active_support/core_ext/date_time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/date_time/acts_like"
4
+ require "active_support/core_ext/date_time/blank"
5
+ require "active_support/core_ext/date_time/calculations"
6
+ require "active_support/core_ext/date_time/compatibility"
7
+ require "active_support/core_ext/date_time/conversions"
8
+ require "active_support/core_ext/date_time/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require "openssl"
5
+
6
+ module Digest
7
+ module UUID
8
+ DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
9
+ URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
10
+ OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
11
+ X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
12
+
13
+ mattr_accessor :use_rfc4122_namespaced_uuids, instance_accessor: false, default: false
14
+
15
+ # Generates a v5 non-random UUID (Universally Unique IDentifier).
16
+ #
17
+ # Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs.
18
+ # uuid_from_hash always generates the same UUID for a given name and namespace combination.
19
+ #
20
+ # See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
21
+ def self.uuid_from_hash(hash_class, namespace, name)
22
+ if hash_class == Digest::MD5 || hash_class == OpenSSL::Digest::MD5
23
+ version = 3
24
+ elsif hash_class == Digest::SHA1 || hash_class == OpenSSL::Digest::SHA1
25
+ version = 5
26
+ else
27
+ raise ArgumentError, "Expected OpenSSL::Digest::SHA1 or OpenSSL::Digest::MD5, got #{hash_class.name}."
28
+ end
29
+
30
+ uuid_namespace = pack_uuid_namespace(namespace)
31
+
32
+ hash = hash_class.new
33
+ hash.update(uuid_namespace)
34
+ hash.update(name)
35
+
36
+ ary = hash.digest.unpack("NnnnnN")
37
+ ary[2] = (ary[2] & 0x0FFF) | (version << 12)
38
+ ary[3] = (ary[3] & 0x3FFF) | 0x8000
39
+
40
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
41
+ end
42
+
43
+ # Convenience method for uuid_from_hash using OpenSSL::Digest::MD5.
44
+ def self.uuid_v3(uuid_namespace, name)
45
+ uuid_from_hash(OpenSSL::Digest::MD5, uuid_namespace, name)
46
+ end
47
+
48
+ # Convenience method for uuid_from_hash using OpenSSL::Digest::SHA1.
49
+ def self.uuid_v5(uuid_namespace, name)
50
+ uuid_from_hash(OpenSSL::Digest::SHA1, uuid_namespace, name)
51
+ end
52
+
53
+ # Convenience method for SecureRandom.uuid.
54
+ def self.uuid_v4
55
+ SecureRandom.uuid
56
+ end
57
+
58
+ def self.pack_uuid_namespace(namespace)
59
+ if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace)
60
+ namespace
61
+ elsif use_rfc4122_namespaced_uuids == true
62
+ match_data = namespace.match(/\A(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})\z/)
63
+
64
+ raise ArgumentError, "Only UUIDs are valid namespace identifiers" unless match_data.present?
65
+
66
+ match_data.captures.map { |s| s.to_i(16) }.pack("NnnnnN")
67
+ else
68
+ ActiveSupport::Deprecation.warn <<~WARNING.squish
69
+ Providing a namespace ID that is not one of the constants defined on Digest::UUID generates an incorrect UUID value according to RFC 4122.
70
+ To enable the correct behavior, set the Rails.application.config.active_support.use_rfc4122_namespaced_uuids configuration option to true.
71
+ WARNING
72
+
73
+ namespace
74
+ end
75
+ end
76
+
77
+ private_class_method :pack_uuid_namespace
78
+ end
79
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/digest/uuid"