activesupport 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +572 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support.rb +96 -0
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/all.rb +5 -0
  8. data/lib/active_support/array_inquirer.rb +48 -0
  9. data/lib/active_support/backtrace_cleaner.rb +132 -0
  10. data/lib/active_support/benchmarkable.rb +51 -0
  11. data/lib/active_support/builder.rb +8 -0
  12. data/lib/active_support/cache.rb +830 -0
  13. data/lib/active_support/cache/file_store.rb +196 -0
  14. data/lib/active_support/cache/mem_cache_store.rb +212 -0
  15. data/lib/active_support/cache/memory_store.rb +174 -0
  16. data/lib/active_support/cache/null_store.rb +48 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +488 -0
  18. data/lib/active_support/cache/strategy/local_cache.rb +194 -0
  19. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  20. data/lib/active_support/callbacks.rb +856 -0
  21. data/lib/active_support/concern.rb +171 -0
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  23. data/lib/active_support/concurrency/share_lock.rb +227 -0
  24. data/lib/active_support/configurable.rb +146 -0
  25. data/lib/active_support/core_ext.rb +5 -0
  26. data/lib/active_support/core_ext/array.rb +9 -0
  27. data/lib/active_support/core_ext/array/access.rb +104 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +213 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
  34. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  35. data/lib/active_support/core_ext/benchmark.rb +16 -0
  36. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  37. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  38. data/lib/active_support/core_ext/class.rb +4 -0
  39. data/lib/active_support/core_ext/class/attribute.rb +141 -0
  40. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  41. data/lib/active_support/core_ext/class/subclasses.rb +54 -0
  42. data/lib/active_support/core_ext/date.rb +7 -0
  43. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  44. data/lib/active_support/core_ext/date/blank.rb +14 -0
  45. data/lib/active_support/core_ext/date/calculations.rb +146 -0
  46. data/lib/active_support/core_ext/date/conversions.rb +96 -0
  47. data/lib/active_support/core_ext/date/zones.rb +8 -0
  48. data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
  49. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  50. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  51. data/lib/active_support/core_ext/date_time.rb +7 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  57. data/lib/active_support/core_ext/digest.rb +3 -0
  58. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  59. data/lib/active_support/core_ext/enumerable.rb +188 -0
  60. data/lib/active_support/core_ext/file.rb +3 -0
  61. data/lib/active_support/core_ext/file/atomic.rb +70 -0
  62. data/lib/active_support/core_ext/hash.rb +10 -0
  63. data/lib/active_support/core_ext/hash/compact.rb +5 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +263 -0
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +24 -0
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
  69. data/lib/active_support/core_ext/hash/keys.rb +143 -0
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  71. data/lib/active_support/core_ext/hash/slice.rb +26 -0
  72. data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
  73. data/lib/active_support/core_ext/integer.rb +5 -0
  74. data/lib/active_support/core_ext/integer/inflections.rb +31 -0
  75. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  76. data/lib/active_support/core_ext/integer/time.rb +22 -0
  77. data/lib/active_support/core_ext/kernel.rb +5 -0
  78. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  79. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  80. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  81. data/lib/active_support/core_ext/load_error.rb +9 -0
  82. data/lib/active_support/core_ext/marshal.rb +24 -0
  83. data/lib/active_support/core_ext/module.rb +13 -0
  84. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  85. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  86. data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
  87. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  88. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  89. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  90. data/lib/active_support/core_ext/module/delegation.rb +313 -0
  91. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  92. data/lib/active_support/core_ext/module/introspection.rb +86 -0
  93. data/lib/active_support/core_ext/module/reachable.rb +6 -0
  94. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  95. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  96. data/lib/active_support/core_ext/name_error.rb +38 -0
  97. data/lib/active_support/core_ext/numeric.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
  99. data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
  100. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  101. data/lib/active_support/core_ext/numeric/time.rb +66 -0
  102. data/lib/active_support/core_ext/object.rb +16 -0
  103. data/lib/active_support/core_ext/object/acts_like.rb +21 -0
  104. data/lib/active_support/core_ext/object/blank.rb +155 -0
  105. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  106. data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
  107. data/lib/active_support/core_ext/object/duplicable.rb +49 -0
  108. data/lib/active_support/core_ext/object/inclusion.rb +29 -0
  109. data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
  110. data/lib/active_support/core_ext/object/json.rb +228 -0
  111. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  112. data/lib/active_support/core_ext/object/to_query.rb +89 -0
  113. data/lib/active_support/core_ext/object/try.rb +156 -0
  114. data/lib/active_support/core_ext/object/with_options.rb +82 -0
  115. data/lib/active_support/core_ext/range.rb +7 -0
  116. data/lib/active_support/core_ext/range/compare_range.rb +70 -0
  117. data/lib/active_support/core_ext/range/conversions.rb +41 -0
  118. data/lib/active_support/core_ext/range/each.rb +25 -0
  119. data/lib/active_support/core_ext/range/include_range.rb +9 -0
  120. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  121. data/lib/active_support/core_ext/range/overlaps.rb +10 -0
  122. data/lib/active_support/core_ext/regexp.rb +7 -0
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string.rb +15 -0
  125. data/lib/active_support/core_ext/string/access.rb +114 -0
  126. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  127. data/lib/active_support/core_ext/string/conversions.rb +59 -0
  128. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  129. data/lib/active_support/core_ext/string/filters.rb +145 -0
  130. data/lib/active_support/core_ext/string/indent.rb +45 -0
  131. data/lib/active_support/core_ext/string/inflections.rb +259 -0
  132. data/lib/active_support/core_ext/string/inquiry.rb +15 -0
  133. data/lib/active_support/core_ext/string/multibyte.rb +58 -0
  134. data/lib/active_support/core_ext/string/output_safety.rb +314 -0
  135. data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
  136. data/lib/active_support/core_ext/string/strip.rb +27 -0
  137. data/lib/active_support/core_ext/string/zones.rb +16 -0
  138. data/lib/active_support/core_ext/time.rb +7 -0
  139. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  140. data/lib/active_support/core_ext/time/calculations.rb +344 -0
  141. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  142. data/lib/active_support/core_ext/time/conversions.rb +72 -0
  143. data/lib/active_support/core_ext/time/zones.rb +113 -0
  144. data/lib/active_support/core_ext/uri.rb +25 -0
  145. data/lib/active_support/current_attributes.rb +203 -0
  146. data/lib/active_support/dependencies.rb +806 -0
  147. data/lib/active_support/dependencies/autoload.rb +79 -0
  148. data/lib/active_support/dependencies/interlock.rb +57 -0
  149. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  150. data/lib/active_support/deprecation.rb +46 -0
  151. data/lib/active_support/deprecation/behaviors.rb +109 -0
  152. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  153. data/lib/active_support/deprecation/instance_delegator.rb +39 -0
  154. data/lib/active_support/deprecation/method_wrappers.rb +78 -0
  155. data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
  156. data/lib/active_support/deprecation/reporting.rb +114 -0
  157. data/lib/active_support/descendants_tracker.rb +109 -0
  158. data/lib/active_support/digest.rb +20 -0
  159. data/lib/active_support/duration.rb +433 -0
  160. data/lib/active_support/duration/iso8601_parser.rb +124 -0
  161. data/lib/active_support/duration/iso8601_serializer.rb +54 -0
  162. data/lib/active_support/encrypted_configuration.rb +45 -0
  163. data/lib/active_support/encrypted_file.rb +100 -0
  164. data/lib/active_support/evented_file_update_checker.rb +235 -0
  165. data/lib/active_support/execution_wrapper.rb +129 -0
  166. data/lib/active_support/executor.rb +8 -0
  167. data/lib/active_support/file_update_checker.rb +163 -0
  168. data/lib/active_support/gem_version.rb +17 -0
  169. data/lib/active_support/gzip.rb +38 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +399 -0
  171. data/lib/active_support/i18n.rb +16 -0
  172. data/lib/active_support/i18n_railtie.rb +126 -0
  173. data/lib/active_support/inflections.rb +72 -0
  174. data/lib/active_support/inflector.rb +9 -0
  175. data/lib/active_support/inflector/inflections.rb +257 -0
  176. data/lib/active_support/inflector/methods.rb +398 -0
  177. data/lib/active_support/inflector/transliterate.rb +147 -0
  178. data/lib/active_support/json.rb +4 -0
  179. data/lib/active_support/json/decoding.rb +76 -0
  180. data/lib/active_support/json/encoding.rb +134 -0
  181. data/lib/active_support/key_generator.rb +41 -0
  182. data/lib/active_support/lazy_load_hooks.rb +82 -0
  183. data/lib/active_support/locale/en.rb +31 -0
  184. data/lib/active_support/locale/en.yml +135 -0
  185. data/lib/active_support/log_subscriber.rb +135 -0
  186. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  187. data/lib/active_support/logger.rb +93 -0
  188. data/lib/active_support/logger_silence.rb +45 -0
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -0
  190. data/lib/active_support/message_encryptor.rb +227 -0
  191. data/lib/active_support/message_verifier.rb +205 -0
  192. data/lib/active_support/messages/metadata.rb +71 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  194. data/lib/active_support/messages/rotator.rb +56 -0
  195. data/lib/active_support/multibyte.rb +23 -0
  196. data/lib/active_support/multibyte/chars.rb +216 -0
  197. data/lib/active_support/multibyte/unicode.rb +157 -0
  198. data/lib/active_support/notifications.rb +253 -0
  199. data/lib/active_support/notifications/fanout.rb +244 -0
  200. data/lib/active_support/notifications/instrumenter.rb +164 -0
  201. data/lib/active_support/number_helper.rb +378 -0
  202. data/lib/active_support/number_helper/number_converter.rb +184 -0
  203. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  204. data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
  205. data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
  206. data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
  207. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  208. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  209. data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
  210. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  211. data/lib/active_support/option_merger.rb +27 -0
  212. data/lib/active_support/ordered_hash.rb +50 -0
  213. data/lib/active_support/ordered_options.rb +85 -0
  214. data/lib/active_support/parameter_filter.rb +129 -0
  215. data/lib/active_support/per_thread_registry.rb +60 -0
  216. data/lib/active_support/proxy_object.rb +15 -0
  217. data/lib/active_support/rails.rb +29 -0
  218. data/lib/active_support/railtie.rb +80 -0
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +174 -0
  221. data/lib/active_support/security_utils.rb +31 -0
  222. data/lib/active_support/string_inquirer.rb +34 -0
  223. data/lib/active_support/subscriber.rb +169 -0
  224. data/lib/active_support/tagged_logging.rb +88 -0
  225. data/lib/active_support/test_case.rb +163 -0
  226. data/lib/active_support/testing/assertions.rb +228 -0
  227. data/lib/active_support/testing/autorun.rb +7 -0
  228. data/lib/active_support/testing/constant_lookup.rb +51 -0
  229. data/lib/active_support/testing/declarative.rb +28 -0
  230. data/lib/active_support/testing/deprecation.rb +38 -0
  231. data/lib/active_support/testing/file_fixtures.rb +38 -0
  232. data/lib/active_support/testing/isolation.rb +110 -0
  233. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  234. data/lib/active_support/testing/parallelization.rb +128 -0
  235. data/lib/active_support/testing/setup_and_teardown.rb +55 -0
  236. data/lib/active_support/testing/stream.rb +44 -0
  237. data/lib/active_support/testing/tagged_logging.rb +27 -0
  238. data/lib/active_support/testing/time_helpers.rb +200 -0
  239. data/lib/active_support/time.rb +20 -0
  240. data/lib/active_support/time_with_zone.rb +561 -0
  241. data/lib/active_support/values/time_zone.rb +570 -0
  242. data/lib/active_support/version.rb +10 -0
  243. data/lib/active_support/xml_mini.rb +202 -0
  244. data/lib/active_support/xml_mini/jdom.rb +183 -0
  245. data/lib/active_support/xml_mini/libxml.rb +80 -0
  246. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  247. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  248. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  249. data/lib/active_support/xml_mini/rexml.rb +130 -0
  250. metadata +385 -0
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+
5
+ module DateAndTime
6
+ module Compatibility
7
+ # If true, +to_time+ preserves the timezone offset of receiver.
8
+ #
9
+ # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
10
+ # converting to the local system time, to preserving the offset
11
+ # of the receiver. For backwards compatibility we're overriding
12
+ # this behavior, but new apps will have an initializer that sets
13
+ # this to true, because the new behavior is preferred.
14
+ mattr_accessor :preserve_timezone, instance_writer: false, default: false
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DateAndTime
4
+ module Zones
5
+ # Returns the simultaneous time in <tt>Time.zone</tt> if a zone is given or
6
+ # if Time.zone_default is set. Otherwise, it returns the current time.
7
+ #
8
+ # Time.zone = 'Hawaii' # => 'Hawaii'
9
+ # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
10
+ # Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
11
+ #
12
+ # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
13
+ # instead of the operating system's time zone.
14
+ #
15
+ # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
16
+ # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
17
+ #
18
+ # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
19
+ # Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
20
+ def in_time_zone(zone = ::Time.zone)
21
+ time_zone = ::Time.find_zone! zone
22
+ time = acts_like?(:time) ? self : nil
23
+
24
+ if time_zone
25
+ time_with_zone(time, time_zone)
26
+ else
27
+ time || to_time
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def time_with_zone(time, zone)
34
+ if time
35
+ ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone)
36
+ else
37
+ ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc))
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
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"
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "active_support/core_ext/object/acts_like"
5
+
6
+ class DateTime
7
+ # Duck-types as a Date-like class. See Object#acts_like?.
8
+ def acts_like_date?
9
+ true
10
+ end
11
+
12
+ # Duck-types as a Time-like class. See Object#acts_like?.
13
+ def acts_like_time?
14
+ true
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class DateTime #:nodoc:
6
+ # No DateTime is ever blank:
7
+ #
8
+ # DateTime.now.blank? # => false
9
+ #
10
+ # @return [false]
11
+ def blank?
12
+ false
13
+ end
14
+ end
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class DateTime
6
+ class << self
7
+ # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
8
+ # <tt>config.time_zone</tt> are set, otherwise returns
9
+ # <tt>Time.now.to_datetime</tt>.
10
+ def current
11
+ ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
12
+ end
13
+ end
14
+
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
20
+ def seconds_since_midnight
21
+ sec + (min * 60) + (hour * 3600)
22
+ end
23
+
24
+ # Returns the number of seconds until 23:59:59.
25
+ #
26
+ # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
27
+ # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
28
+ # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
29
+ def seconds_until_end_of_day
30
+ end_of_day.to_i - to_i
31
+ end
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
+
40
+ # Returns a new DateTime where one or more of the elements have been changed
41
+ # according to the +options+ parameter. The time options (<tt>:hour</tt>,
42
+ # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
43
+ # passed, then minute and sec is set to 0. If the hour and minute is passed,
44
+ # then sec is set to 0. The +options+ parameter takes a hash with any of these
45
+ # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
46
+ # <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
47
+ #
48
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)
49
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
50
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
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
+
62
+ ::DateTime.civil(
63
+ options.fetch(:year, year),
64
+ options.fetch(:month, month),
65
+ options.fetch(:day, day),
66
+ options.fetch(:hour, hour),
67
+ options.fetch(:min, options[:hour] ? 0 : min),
68
+ options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction,
69
+ options.fetch(:offset, offset),
70
+ options.fetch(:start, start)
71
+ )
72
+ end
73
+
74
+ # Uses Date to provide precise Time calculations for years, months, and days.
75
+ # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
76
+ # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
77
+ # <tt>:minutes</tt>, <tt>:seconds</tt>.
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
+
89
+ d = to_date.advance(options)
90
+ datetime_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
91
+ seconds_to_advance = \
92
+ options.fetch(:seconds, 0) +
93
+ options.fetch(:minutes, 0) * 60 +
94
+ options.fetch(:hours, 0) * 3600
95
+
96
+ if seconds_to_advance.zero?
97
+ datetime_advanced_by_date
98
+ else
99
+ datetime_advanced_by_date.since(seconds_to_advance)
100
+ end
101
+ end
102
+
103
+ # Returns a new DateTime representing the time a number of seconds ago.
104
+ # Do not use this method in combination with x.months, use months_ago instead!
105
+ def ago(seconds)
106
+ since(-seconds)
107
+ end
108
+
109
+ # Returns a new DateTime representing the time a number of seconds since the
110
+ # instance time. Do not use this method in combination with x.months, use
111
+ # months_since instead!
112
+ def since(seconds)
113
+ self + Rational(seconds, 86400)
114
+ end
115
+ alias :in :since
116
+
117
+ # Returns a new DateTime representing the start of the day (0:00).
118
+ def beginning_of_day
119
+ change(hour: 0)
120
+ end
121
+ alias :midnight :beginning_of_day
122
+ alias :at_midnight :beginning_of_day
123
+ alias :at_beginning_of_day :beginning_of_day
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
+
135
+ # Returns a new DateTime representing the end of the day (23:59:59).
136
+ def end_of_day
137
+ change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
138
+ end
139
+ alias :at_end_of_day :end_of_day
140
+
141
+ # Returns a new DateTime representing the start of the hour (hh:00:00).
142
+ def beginning_of_hour
143
+ change(min: 0)
144
+ end
145
+ alias :at_beginning_of_hour :beginning_of_hour
146
+
147
+ # Returns a new DateTime representing the end of the hour (hh:59:59).
148
+ def end_of_hour
149
+ change(min: 59, sec: 59, usec: Rational(999999999, 1000))
150
+ end
151
+ alias :at_end_of_hour :end_of_hour
152
+
153
+ # Returns a new DateTime representing the start of the minute (hh:mm:00).
154
+ def beginning_of_minute
155
+ change(sec: 0)
156
+ end
157
+ alias :at_beginning_of_minute :beginning_of_minute
158
+
159
+ # Returns a new DateTime representing the end of the minute (hh:mm:59).
160
+ def end_of_minute
161
+ change(sec: 59, usec: Rational(999999999, 1000))
162
+ end
163
+ alias :at_end_of_minute :end_of_minute
164
+
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.
177
+ #
178
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
179
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
180
+ def utc
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
+ )
187
+ end
188
+ alias_method :getgm, :utc
189
+ alias_method :getutc, :utc
190
+ alias_method :gmtime, :utc
191
+
192
+ # Returns +true+ if <tt>offset == 0</tt>.
193
+ def utc?
194
+ offset == 0
195
+ end
196
+
197
+ # Returns the offset value in seconds.
198
+ def utc_offset
199
+ (offset * 86400).to_i
200
+ end
201
+
202
+ # Layers additional behavior on DateTime#<=> so that Time and
203
+ # ActiveSupport::TimeWithZone instances can be compared with a DateTime.
204
+ def <=>(other)
205
+ if other.respond_to? :to_datetime
206
+ super other.to_datetime rescue nil
207
+ else
208
+ super
209
+ end
210
+ end
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
@@ -0,0 +1,107 @@
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"
8
+
9
+ class DateTime
10
+ # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
11
+ #
12
+ # This method is aliased to <tt>to_s</tt>.
13
+ #
14
+ # === Examples
15
+ # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
16
+ #
17
+ # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
18
+ # datetime.to_s(:db) # => "2007-12-04 00:00:00"
19
+ # datetime.to_s(:number) # => "20071204000000"
20
+ # datetime.to_formatted_s(:short) # => "04 Dec 00:00"
21
+ # datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
22
+ # datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
23
+ # datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
24
+ # datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
25
+ #
26
+ # == Adding your own datetime formats to to_formatted_s
27
+ # DateTime formats are shared with Time. You can add your own to the
28
+ # Time::DATE_FORMATS hash. Use the format name as the hash key and
29
+ # either a strftime string or Proc instance that takes a time or
30
+ # datetime argument as the value.
31
+ #
32
+ # # config/initializers/time_formats.rb
33
+ # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
34
+ # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
35
+ def to_formatted_s(format = :default)
36
+ if formatter = ::Time::DATE_FORMATS[format]
37
+ formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
38
+ else
39
+ to_default_s
40
+ end
41
+ end
42
+ alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
43
+ alias_method :to_s, :to_formatted_s
44
+
45
+ # Returns a formatted string of the offset from UTC, or an alternative
46
+ # string if the time zone is already UTC.
47
+ #
48
+ # datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
49
+ # datetime.formatted_offset # => "-06:00"
50
+ # datetime.formatted_offset(false) # => "-0600"
51
+ def formatted_offset(colon = true, alternate_utc_string = nil)
52
+ utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
53
+ end
54
+
55
+ # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
56
+ def readable_inspect
57
+ to_s(:rfc822)
58
+ end
59
+ alias_method :default_inspect, :inspect
60
+ alias_method :inspect, :readable_inspect
61
+
62
+ # Returns DateTime with local offset for given year if format is local else
63
+ # offset is zero.
64
+ #
65
+ # DateTime.civil_from_format :local, 2012
66
+ # # => Sun, 01 Jan 2012 00:00:00 +0300
67
+ # DateTime.civil_from_format :local, 2012, 12, 17
68
+ # # => Mon, 17 Dec 2012 00:00:00 +0000
69
+ def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0)
70
+ if utc_or_local.to_sym == :local
71
+ offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
72
+ else
73
+ offset = 0
74
+ end
75
+ civil(year, month, day, hour, min, sec, offset)
76
+ end
77
+
78
+ # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
79
+ def to_f
80
+ seconds_since_unix_epoch.to_f + sec_fraction
81
+ end
82
+
83
+ # Converts +self+ to an integer number of seconds since the Unix epoch.
84
+ def to_i
85
+ seconds_since_unix_epoch.to_i
86
+ end
87
+
88
+ # Returns the fraction of a second as microseconds
89
+ def usec
90
+ (sec_fraction * 1_000_000).to_i
91
+ end
92
+
93
+ # Returns the fraction of a second as nanoseconds
94
+ def nsec
95
+ (sec_fraction * 1_000_000_000).to_i
96
+ end
97
+
98
+ private
99
+
100
+ def offset_in_seconds
101
+ (offset * 86400).to_i
102
+ end
103
+
104
+ def seconds_since_unix_epoch
105
+ (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
106
+ end
107
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/digest/uuid"
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Digest
6
+ module UUID
7
+ DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
8
+ URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
9
+ OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
10
+ X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
11
+
12
+ # Generates a v5 non-random UUID (Universally Unique IDentifier).
13
+ #
14
+ # Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
15
+ # uuid_from_hash always generates the same UUID for a given name and namespace combination.
16
+ #
17
+ # See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
18
+ def self.uuid_from_hash(hash_class, uuid_namespace, name)
19
+ if hash_class == Digest::MD5
20
+ version = 3
21
+ elsif hash_class == Digest::SHA1
22
+ version = 5
23
+ else
24
+ raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
25
+ end
26
+
27
+ hash = hash_class.new
28
+ hash.update(uuid_namespace)
29
+ hash.update(name)
30
+
31
+ ary = hash.digest.unpack("NnnnnN")
32
+ ary[2] = (ary[2] & 0x0FFF) | (version << 12)
33
+ ary[3] = (ary[3] & 0x3FFF) | 0x8000
34
+
35
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
36
+ end
37
+
38
+ # Convenience method for uuid_from_hash using Digest::MD5.
39
+ def self.uuid_v3(uuid_namespace, name)
40
+ uuid_from_hash(Digest::MD5, uuid_namespace, name)
41
+ end
42
+
43
+ # Convenience method for uuid_from_hash using Digest::SHA1.
44
+ def self.uuid_v5(uuid_namespace, name)
45
+ uuid_from_hash(Digest::SHA1, uuid_namespace, name)
46
+ end
47
+
48
+ # Convenience method for SecureRandom.uuid.
49
+ def self.uuid_v4
50
+ SecureRandom.uuid
51
+ end
52
+ end
53
+ end