activesupport 1.2.4 → 8.1.2

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 (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -1,174 +1,379 @@
1
- module ActiveSupport #:nodoc:
2
- module CoreExtensions #:nodoc:
3
- module Time #:nodoc:
4
- # Enables the use of time calculations within Time itself
5
- module Calculations
6
- def self.append_features(base) #:nodoc:
7
- super
8
- base.extend(ClassMethods)
9
- end
1
+ # frozen_string_literal: true
10
2
 
11
- module ClassMethods
12
- # Return the number of days in the given month. If a year is given,
13
- # February will return the correct number of days for leap years.
14
- # Otherwise, this method will always report February as having 28
15
- # days.
16
- def days_in_month(month, year=nil)
17
- if month == 2
18
- !year.nil? && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) ? 29 : 28
19
- elsif month <= 7
20
- month % 2 == 0 ? 30 : 31
21
- else
22
- month % 2 == 0 ? 31 : 30
23
- end
24
- end
25
- end
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"
26
10
 
27
- # Seconds since midnight: Time.now.seconds_since_midnight
28
- def seconds_since_midnight
29
- self.hour.hours + self.min.minutes + self.sec + (self.usec/1.0e+6)
30
- end
31
-
32
- # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
33
- # (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
34
- # minute is passed, then sec and usec is set to 0.
35
- def change(options)
36
- ::Time.send(
37
- self.utc? ? :utc : :local,
38
- options[:year] || self.year,
39
- options[:month] || self.month,
40
- options[:mday] || self.mday,
41
- options[:hour] || self.hour,
42
- options[:min] || (options[:hour] ? 0 : self.min),
43
- options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
44
- options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
45
- )
46
- end
11
+ class Time
12
+ include DateAndTime::Calculations
47
13
 
48
- # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
49
- # Do not use this method in combination with x.months, use months_ago instead!
50
- def ago(seconds)
51
- seconds.until(self)
52
- end
14
+ COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
53
15
 
54
- # Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around
55
- #the Numeric extension. Do not use this method in combination with x.months, use months_since instead!
56
- def since(seconds)
57
- seconds.since(self)
58
- end
59
- alias :in :since
16
+ class << self
17
+ # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
18
+ def ===(other)
19
+ super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
20
+ end
21
+
22
+ # Returns the number of days in the given month.
23
+ # If no year is specified, it will use the current year.
24
+ def days_in_month(month, year = current.year)
25
+ if month == 2 && ::Date.gregorian_leap?(year)
26
+ 29
27
+ else
28
+ COMMON_YEAR_DAYS_IN_MONTH[month]
29
+ end
30
+ end
31
+
32
+ # Returns the number of days in the given year.
33
+ # If no year is specified, it will use the current year.
34
+ def days_in_year(year = current.year)
35
+ days_in_month(2, year) + 337
36
+ end
60
37
 
61
- # Returns a new Time representing the time a number of specified months ago
62
- def months_ago(months)
63
- months_since(-months)
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>.
39
+ def current
40
+ ::Time.zone ? ::Time.zone.now : ::Time.now
41
+ end
42
+
43
+ # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
44
+ # instances can be used when called with a single argument
45
+ def at_with_coercion(time_or_number, *args)
46
+ if args.empty?
47
+ if time_or_number.is_a?(ActiveSupport::TimeWithZone)
48
+ at_without_coercion(time_or_number.to_r).getlocal
49
+ elsif time_or_number.is_a?(DateTime)
50
+ at_without_coercion(time_or_number.to_f).getlocal
51
+ else
52
+ at_without_coercion(time_or_number)
64
53
  end
54
+ else
55
+ at_without_coercion(time_or_number, *args)
56
+ end
57
+ end
58
+ ruby2_keywords :at_with_coercion
59
+ alias_method :at_without_coercion, :at
60
+ alias_method :at, :at_with_coercion
65
61
 
66
- def months_since(months)
67
- year, month, mday = self.year, self.month, self.mday
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)
68
71
 
69
- month += months
72
+ raise ArgumentError, "invalid date" if parts.empty?
70
73
 
71
- # in case months is negative
72
- while month < 1
73
- month += 12
74
- year -= 1
75
- end
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
84
+ end
76
85
 
77
- # in case months is positive
78
- while month > 12
79
- month -= 12
80
- year += 1
81
- end
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
91
+ def seconds_since_midnight
92
+ to_i - change(hour: 0).to_i + (usec / 1.0e+6)
93
+ end
82
94
 
83
- max = ::Time.days_in_month(month, year)
84
- mday = max if mday > max
95
+ # Returns the number of seconds until 23:59:59.
96
+ #
97
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
98
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
99
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
100
+ def seconds_until_end_of_day
101
+ end_of_day.to_i - to_i
102
+ end
85
103
 
86
- change(:year => year, :month => month, :mday => mday)
87
- end
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
88
110
 
89
- # Returns a new Time representing the time a number of specified years ago
90
- def years_ago(years)
91
- change(:year => self.year - years)
92
- end
93
-
94
- def years_since(years)
95
- change(:year => self.year + years)
96
- end
111
+ # Returns a new Time where one or more of the elements have been changed according
112
+ # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
113
+ # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
114
+ # the hour is passed, then minute, sec, usec, and nsec is set to 0. If the hour
115
+ # and minute is passed, then sec, usec, and nsec is set to 0. The +options+ parameter
116
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
117
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
118
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
119
+ #
120
+ # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
121
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
122
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
123
+ def change(options)
124
+ new_year = options.fetch(:year, year)
125
+ new_month = options.fetch(:month, month)
126
+ new_day = options.fetch(:day, day)
127
+ new_hour = options.fetch(:hour, hour)
128
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
129
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
130
+ new_offset = options.fetch(:offset, nil)
97
131
 
98
- # Short-hand for years_ago(1)
99
- def last_year
100
- years_ago(1)
101
- end
102
-
103
- # Short-hand for years_since(1)
104
- def next_year
105
- years_since(1)
106
- end
132
+ if new_nsec = options[:nsec]
133
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
134
+ new_usec = Rational(new_nsec, 1000)
135
+ else
136
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
137
+ end
107
138
 
139
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
108
140
 
109
- # Short-hand for months_ago(1)
110
- def last_month
111
- months_ago(1)
112
- end
141
+ new_sec += Rational(new_usec, 1000000)
113
142
 
114
- # Short-hand for months_since(1)
115
- def next_month
116
- months_since(1)
117
- end
118
-
119
- # Returns a new Time representing the "start" of this week (Monday, 0:00)
120
- def beginning_of_week
121
- days_to_monday = self.wday!=0 ? self.wday-1 : 6
122
- (self - days_to_monday.days).midnight
123
- end
124
- alias :monday :beginning_of_week
125
- alias :at_beginning_of_week :beginning_of_week
126
-
127
- # Returns a new Time representing the start of the given day in next week (default is Monday).
128
- def next_week(day = :monday)
129
- days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
130
- since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
131
- end
132
-
133
- # Returns a new Time representing the start of the day (0:00)
134
- def beginning_of_day
135
- (self - self.seconds_since_midnight).change(:usec => 0)
136
- end
137
- alias :midnight :beginning_of_day
138
- alias :at_midnight :beginning_of_day
139
- alias :at_beginning_of_day :beginning_of_day
140
-
141
- # Returns a new Time representing the start of the month (1st of the month, 0:00)
142
- def beginning_of_month
143
- #self - ((self.mday-1).days + self.seconds_since_midnight)
144
- change(:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
145
- end
146
- alias :at_beginning_of_month :beginning_of_month
147
-
148
- # Returns a new Time representing the end of the month (last day of the month, 0:00)
149
- def end_of_month
150
- #self - ((self.mday-1).days + self.seconds_since_midnight)
151
- last_day = ::Time.days_in_month( self.month, self.year )
152
- change(:mday => last_day,:hour => 0, :min => 0, :sec => 0, :usec => 0)
153
- end
154
- alias :at_end_of_month :end_of_month
155
-
156
- # Returns a new Time representing the start of the year (1st of january, 0:00)
157
- def beginning_of_year
158
- change(:month => 1,:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
159
- end
160
- alias :at_beginning_of_year :beginning_of_year
161
-
162
- # Convenience method which returns a new Time representing the time 1 day ago
163
- def yesterday
164
- self.ago(1.day)
165
- end
166
-
167
- # Convenience method which returns a new Time representing the time 1 day since the instance time
168
- def tomorrow
169
- self.since(1.day)
170
- end
143
+ if new_offset
144
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
145
+ elsif utc?
146
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
147
+ elsif zone.respond_to?(:utc_to_local)
148
+ new_time = ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
149
+
150
+ # Some versions of Ruby have a bug where Time.new with a zone object and
151
+ # fractional seconds will end up with a broken utc_offset.
152
+ # This is fixed in Ruby 3.3.1 and 3.2.4
153
+ unless new_time.utc_offset.integer?
154
+ new_time += 0
155
+ end
156
+
157
+ # When there are two occurrences of a nominal time due to DST ending,
158
+ # `Time.new` chooses the first chronological occurrence (the one with a
159
+ # larger UTC offset). However, for `change`, we want to choose the
160
+ # occurrence that matches this time's UTC offset.
161
+ #
162
+ # If the new time's UTC offset is larger than this time's UTC offset, the
163
+ # new time might be a first chronological occurrence. So we add the offset
164
+ # difference to fast-forward the new time, and check if the result has the
165
+ # desired UTC offset (i.e. is the second chronological occurrence).
166
+ offset_difference = new_time.utc_offset - utc_offset
167
+ if offset_difference > 0 && (new_time_2 = new_time + offset_difference).utc_offset == utc_offset
168
+ new_time_2
169
+ else
170
+ new_time
171
+ end
172
+ elsif zone
173
+ ::Time.local(new_sec, new_min, new_hour, new_day, new_month, new_year, nil, nil, isdst, nil)
174
+ else
175
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
176
+ end
177
+ end
178
+
179
+ # Uses Date to provide precise Time calculations for years, months, and days
180
+ # according to the proleptic Gregorian calendar. The +options+ parameter
181
+ # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
182
+ # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
183
+ # <tt>:seconds</tt>.
184
+ #
185
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
186
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
187
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
188
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
189
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
190
+ #
191
+ # Just like Date#advance, increments are applied in order of time units from
192
+ # largest to smallest. This order can affect the result around the end of a
193
+ # month.
194
+ def advance(options)
195
+ unless options[:weeks].nil?
196
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
197
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
198
+ end
199
+
200
+ unless options[:days].nil?
201
+ options[:days], partial_days = options[:days].divmod(1)
202
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
203
+ end
204
+
205
+ d = to_date.gregorian.advance(options)
206
+ time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
207
+ seconds_to_advance = \
208
+ options.fetch(:seconds, 0) +
209
+ options.fetch(:minutes, 0) * 60 +
210
+ options.fetch(:hours, 0) * 3600
211
+
212
+ if seconds_to_advance.zero?
213
+ time_advanced_by_date
214
+ else
215
+ time_advanced_by_date.since(seconds_to_advance)
216
+ end
217
+ end
218
+
219
+ # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
220
+ def ago(seconds)
221
+ since(-seconds)
222
+ end
223
+
224
+ # Returns a new Time representing the time a number of seconds since the instance time
225
+ def since(seconds)
226
+ self + seconds
227
+ end
228
+ alias :in :since
229
+
230
+ # Returns a new Time representing the start of the day (0:00)
231
+ def beginning_of_day
232
+ change(hour: 0)
233
+ end
234
+ alias :midnight :beginning_of_day
235
+ alias :at_midnight :beginning_of_day
236
+ alias :at_beginning_of_day :beginning_of_day
237
+
238
+ # Returns a new Time representing the middle of the day (12:00)
239
+ def middle_of_day
240
+ change(hour: 12)
241
+ end
242
+ alias :midday :middle_of_day
243
+ alias :noon :middle_of_day
244
+ alias :at_midday :middle_of_day
245
+ alias :at_noon :middle_of_day
246
+ alias :at_middle_of_day :middle_of_day
247
+
248
+ # Returns a new Time representing the end of the day, 23:59:59.999999
249
+ def end_of_day
250
+ change(
251
+ hour: 23,
252
+ min: 59,
253
+ sec: 59,
254
+ usec: Rational(999999999, 1000)
255
+ )
256
+ end
257
+ alias :at_end_of_day :end_of_day
258
+
259
+ # Returns a new Time representing the start of the hour (x:00)
260
+ def beginning_of_hour
261
+ change(min: 0)
262
+ end
263
+ alias :at_beginning_of_hour :beginning_of_hour
264
+
265
+ # Returns a new Time representing the end of the hour, x:59:59.999999
266
+ def end_of_hour
267
+ change(
268
+ min: 59,
269
+ sec: 59,
270
+ usec: Rational(999999999, 1000)
271
+ )
272
+ end
273
+ alias :at_end_of_hour :end_of_hour
274
+
275
+ # Returns a new Time representing the start of the minute (x:xx:00)
276
+ def beginning_of_minute
277
+ change(sec: 0)
278
+ end
279
+ alias :at_beginning_of_minute :beginning_of_minute
280
+
281
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
282
+ def end_of_minute
283
+ change(
284
+ sec: 59,
285
+ usec: Rational(999999999, 1000)
286
+ )
287
+ end
288
+ alias :at_end_of_minute :end_of_minute
289
+
290
+ def plus_with_duration(other) # :nodoc:
291
+ if ActiveSupport::Duration === other
292
+ other.since(self)
293
+ else
294
+ plus_without_duration(other)
295
+ end
296
+ end
297
+ alias_method :plus_without_duration, :+
298
+ alias_method :+, :plus_with_duration
299
+
300
+ def minus_with_duration(other) # :nodoc:
301
+ if ActiveSupport::Duration === other
302
+ other.until(self)
303
+ else
304
+ minus_without_duration(other)
305
+ end
306
+ end
307
+ alias_method :minus_without_duration, :-
308
+ alias_method :-, :minus_with_duration
309
+
310
+ # Time#- can also be used to determine the number of seconds between two Time instances.
311
+ # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
312
+ # are coerced into values that Time#- will recognize
313
+ def minus_with_coercion(other)
314
+ other = other.comparable_time if other.respond_to?(:comparable_time)
315
+ other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
316
+ end
317
+ alias_method :minus_without_coercion, :-
318
+ alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
319
+
320
+ # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
321
+ # can be chronologically compared with a Time
322
+ def compare_with_coercion(other)
323
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
324
+ if other.class == Time
325
+ compare_without_coercion(other)
326
+ elsif other.is_a?(Time)
327
+ # also avoid ActiveSupport::TimeWithZone#to_time before Rails 8.0
328
+ if other.respond_to?(:comparable_time)
329
+ compare_without_coercion(other.comparable_time)
330
+ else
331
+ compare_without_coercion(other.to_time)
171
332
  end
333
+ else
334
+ to_datetime <=> other
172
335
  end
173
336
  end
337
+ alias_method :compare_without_coercion, :<=>
338
+ alias_method :<=>, :compare_with_coercion
339
+
340
+ # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
341
+ # can be eql? to an equivalent Time
342
+ def eql_with_coercion(other)
343
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
344
+ other = other.comparable_time if other.respond_to?(:comparable_time)
345
+ eql_without_coercion(other)
346
+ end
347
+ alias_method :eql_without_coercion, :eql?
348
+ alias_method :eql?, :eql_with_coercion
349
+
350
+ # Returns a new time the specified number of days ago.
351
+ def prev_day(days = 1)
352
+ advance(days: -days)
353
+ end
354
+
355
+ # Returns a new time the specified number of days in the future.
356
+ def next_day(days = 1)
357
+ advance(days: days)
358
+ end
359
+
360
+ # Returns a new time the specified number of months ago.
361
+ def prev_month(months = 1)
362
+ advance(months: -months)
363
+ end
364
+
365
+ # Returns a new time the specified number of months in the future.
366
+ def next_month(months = 1)
367
+ advance(months: months)
368
+ end
369
+
370
+ # Returns a new time the specified number of years ago.
371
+ def prev_year(years = 1)
372
+ advance(years: -years)
373
+ end
374
+
375
+ # Returns a new time the specified number of years in the future.
376
+ def next_year(years = 1)
377
+ advance(years: years)
378
+ end
174
379
  end
@@ -0,0 +1,15 @@
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
+ # Return +self+.
12
+ def to_time
13
+ self
14
+ end
15
+ end
@@ -1,36 +1,75 @@
1
- require 'date'
1
+ # frozen_string_literal: true
2
2
 
3
- module ActiveSupport #:nodoc:
4
- module CoreExtensions #:nodoc:
5
- module Time #:nodoc:
6
- # Getting times in different convenient string representations and other objects
7
- module Conversions
8
- DATE_FORMATS = {
9
- :db => "%Y-%m-%d %H:%M:%S",
10
- :short => "%d %b %H:%M",
11
- :long => "%B %d, %Y %H:%M",
12
- :rfc822 => "%a, %d %b %Y %H:%M:%S %z"
13
- }
3
+ require "time"
4
+ require "active_support/inflector/methods"
5
+ require "active_support/values/time_zone"
14
6
 
15
- def self.append_features(klass)
16
- super
17
- klass.send(:alias_method, :to_default_s, :to_s)
18
- klass.send(:alias_method, :to_s, :to_formatted_s)
19
- end
20
-
21
- def to_formatted_s(format = :default)
22
- DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s
23
- end
7
+ class Time
8
+ DATE_FORMATS = {
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|
18
+ day_format = ActiveSupport::Inflector.ordinalize(time.day)
19
+ time.strftime("%B #{day_format}, %Y %H:%M")
20
+ },
21
+ rfc822: lambda { |time|
22
+ offset_format = time.formatted_offset(false)
23
+ time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
24
+ },
25
+ rfc2822: lambda { |time| time.rfc2822 },
26
+ iso8601: lambda { |time| time.iso8601 }
27
+ }
24
28
 
25
- def to_date
26
- ::Date.new(year, month, day)
27
- end
28
-
29
- # To be able to keep Dates and Times interchangeable on conversions
30
- def to_time
31
- self
32
- end
33
- end
29
+ # Converts to a formatted string. See DATE_FORMATS for built-in formats.
30
+ #
31
+ # This method is aliased to <tt>to_formatted_s</tt>.
32
+ #
33
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
34
+ #
35
+ # time.to_fs(:time) # => "06:10"
36
+ # time.to_formatted_s(:time) # => "06:10"
37
+ #
38
+ # time.to_fs(:db) # => "2007-01-18 06:10:17"
39
+ # time.to_fs(:number) # => "20070118061017"
40
+ # time.to_fs(:short) # => "18 Jan 06:10"
41
+ # time.to_fs(:long) # => "January 18, 2007 06:10"
42
+ # time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
43
+ # time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
44
+ # time.to_fs(:rfc2822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
45
+ # time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
46
+ #
47
+ # == Adding your own time formats to +to_fs+
48
+ # You can add your own formats to the Time::DATE_FORMATS hash.
49
+ # Use the format name as the hash key and either a strftime string
50
+ # or Proc instance that takes a time argument as the value.
51
+ #
52
+ # # config/initializers/time_formats.rb
53
+ # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
54
+ # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
55
+ def to_fs(format = :default)
56
+ if formatter = DATE_FORMATS[format]
57
+ formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
58
+ else
59
+ to_s
34
60
  end
35
61
  end
62
+ alias_method :to_formatted_s, :to_fs
63
+
64
+ # Returns a formatted string of the offset from UTC, or an alternative
65
+ # string if the time zone is already UTC.
66
+ #
67
+ # Time.local(2000).formatted_offset # => "-06:00"
68
+ # Time.local(2000).formatted_offset(false) # => "-0600"
69
+ def formatted_offset(colon = true, alternate_utc_string = nil)
70
+ utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
71
+ end
72
+
73
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
74
+ alias_method :rfc3339, :xmlschema
36
75
  end