activesupport 3.1.0 → 5.0.0

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 (276) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +798 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +13 -7
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +38 -34
  7. data/lib/active_support/benchmarkable.rb +17 -28
  8. data/lib/active_support/cache/file_store.rb +85 -70
  9. data/lib/active_support/cache/mem_cache_store.rb +75 -66
  10. data/lib/active_support/cache/memory_store.rb +31 -23
  11. data/lib/active_support/cache/null_store.rb +41 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +73 -70
  13. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  14. data/lib/active_support/cache.rb +360 -294
  15. data/lib/active_support/callbacks.rb +563 -393
  16. data/lib/active_support/concern.rb +42 -34
  17. data/lib/active_support/concurrency/latch.rb +19 -0
  18. data/lib/active_support/concurrency/share_lock.rb +186 -0
  19. data/lib/active_support/configurable.rb +70 -12
  20. data/lib/active_support/core_ext/array/access.rb +53 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +109 -62
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +39 -32
  24. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  25. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  26. data/lib/active_support/core_ext/array/wrap.rb +16 -18
  27. data/lib/active_support/core_ext/array.rb +2 -2
  28. data/lib/active_support/core_ext/benchmark.rb +7 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
  30. data/lib/active_support/core_ext/class/attribute.rb +47 -34
  31. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
  32. data/lib/active_support/core_ext/class/subclasses.rb +12 -7
  33. data/lib/active_support/core_ext/class.rb +0 -3
  34. data/lib/active_support/core_ext/date/blank.rb +12 -0
  35. data/lib/active_support/core_ext/date/calculations.rb +57 -167
  36. data/lib/active_support/core_ext/date/conversions.rb +31 -42
  37. data/lib/active_support/core_ext/date/zones.rb +2 -10
  38. data/lib/active_support/core_ext/date.rb +5 -0
  39. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  40. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
  41. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  42. data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
  43. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  44. data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
  45. data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
  46. data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
  47. data/lib/active_support/core_ext/date_time.rb +5 -0
  48. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  49. data/lib/active_support/core_ext/enumerable.rb +81 -74
  50. data/lib/active_support/core_ext/file/atomic.rb +53 -26
  51. data/lib/active_support/core_ext/file.rb +0 -1
  52. data/lib/active_support/core_ext/hash/compact.rb +20 -0
  53. data/lib/active_support/core_ext/hash/conversions.rb +175 -70
  54. data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
  55. data/lib/active_support/core_ext/hash/except.rb +11 -12
  56. data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
  57. data/lib/active_support/core_ext/hash/keys.rb +147 -24
  58. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  59. data/lib/active_support/core_ext/hash/slice.rb +22 -14
  60. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  61. data/lib/active_support/core_ext/hash.rb +2 -2
  62. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  63. data/lib/active_support/core_ext/integer/multiple.rb +4 -0
  64. data/lib/active_support/core_ext/integer/time.rb +12 -22
  65. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
  66. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  67. data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
  68. data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
  69. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  70. data/lib/active_support/core_ext/kernel.rb +2 -3
  71. data/lib/active_support/core_ext/load_error.rb +14 -7
  72. data/lib/active_support/core_ext/marshal.rb +22 -0
  73. data/lib/active_support/core_ext/module/aliasing.rb +16 -12
  74. data/lib/active_support/core_ext/module/anonymous.rb +12 -8
  75. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  76. data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
  77. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  78. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  79. data/lib/active_support/core_ext/module/delegation.rb +141 -68
  80. data/lib/active_support/core_ext/module/deprecation.rb +17 -3
  81. data/lib/active_support/core_ext/module/introspection.rb +9 -31
  82. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  83. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  84. data/lib/active_support/core_ext/module/reachable.rb +1 -3
  85. data/lib/active_support/core_ext/module/remove_method.rb +24 -5
  86. data/lib/active_support/core_ext/module.rb +3 -3
  87. data/lib/active_support/core_ext/name_error.rb +15 -2
  88. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  89. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  90. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  91. data/lib/active_support/core_ext/numeric/time.rb +31 -36
  92. data/lib/active_support/core_ext/numeric.rb +2 -0
  93. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  94. data/lib/active_support/core_ext/object/blank.rb +52 -18
  95. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  96. data/lib/active_support/core_ext/object/duplicable.rb +12 -20
  97. data/lib/active_support/core_ext/object/inclusion.rb +13 -1
  98. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  99. data/lib/active_support/core_ext/object/json.rb +205 -0
  100. data/lib/active_support/core_ext/object/to_param.rb +1 -55
  101. data/lib/active_support/core_ext/object/to_query.rb +66 -9
  102. data/lib/active_support/core_ext/object/try.rb +124 -33
  103. data/lib/active_support/core_ext/object/with_options.rb +37 -11
  104. data/lib/active_support/core_ext/object.rb +2 -1
  105. data/lib/active_support/core_ext/range/conversions.rb +17 -7
  106. data/lib/active_support/core_ext/range/each.rb +21 -0
  107. data/lib/active_support/core_ext/range/include_range.rb +20 -18
  108. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  109. data/lib/active_support/core_ext/range.rb +1 -2
  110. data/lib/active_support/core_ext/securerandom.rb +23 -0
  111. data/lib/active_support/core_ext/string/access.rb +95 -90
  112. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  113. data/lib/active_support/core_ext/string/conversions.rb +41 -38
  114. data/lib/active_support/core_ext/string/exclude.rb +6 -1
  115. data/lib/active_support/core_ext/string/filters.rb +70 -17
  116. data/lib/active_support/core_ext/string/indent.rb +43 -0
  117. data/lib/active_support/core_ext/string/inflections.rb +139 -59
  118. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  119. data/lib/active_support/core_ext/string/multibyte.rb +46 -65
  120. data/lib/active_support/core_ext/string/output_safety.rb +153 -56
  121. data/lib/active_support/core_ext/string/strip.rb +3 -6
  122. data/lib/active_support/core_ext/string/zones.rb +14 -0
  123. data/lib/active_support/core_ext/string.rb +2 -3
  124. data/lib/active_support/core_ext/struct.rb +3 -0
  125. data/lib/active_support/core_ext/time/calculations.rb +173 -173
  126. data/lib/active_support/core_ext/time/compatibility.rb +5 -0
  127. data/lib/active_support/core_ext/time/conversions.rb +33 -29
  128. data/lib/active_support/core_ext/time/marshal.rb +2 -56
  129. data/lib/active_support/core_ext/time/zones.rb +57 -32
  130. data/lib/active_support/core_ext/time.rb +5 -0
  131. data/lib/active_support/core_ext/uri.rb +13 -19
  132. data/lib/active_support/core_ext.rb +3 -2
  133. data/lib/active_support/dependencies/autoload.rb +47 -20
  134. data/lib/active_support/dependencies/interlock.rb +51 -0
  135. data/lib/active_support/dependencies.rb +315 -265
  136. data/lib/active_support/deprecation/behaviors.rb +71 -30
  137. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  138. data/lib/active_support/deprecation/method_wrappers.rb +59 -18
  139. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
  140. data/lib/active_support/deprecation/reporting.rb +61 -14
  141. data/lib/active_support/deprecation.rb +38 -13
  142. data/lib/active_support/descendants_tracker.rb +34 -19
  143. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  144. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  145. data/lib/active_support/duration.rb +85 -14
  146. data/lib/active_support/evented_file_update_checker.rb +194 -0
  147. data/lib/active_support/execution_wrapper.rb +117 -0
  148. data/lib/active_support/executor.rb +6 -0
  149. data/lib/active_support/file_update_checker.rb +138 -17
  150. data/lib/active_support/gem_version.rb +15 -0
  151. data/lib/active_support/gzip.rb +11 -5
  152. data/lib/active_support/hash_with_indifferent_access.rb +199 -49
  153. data/lib/active_support/i18n.rb +6 -2
  154. data/lib/active_support/i18n_railtie.rb +40 -21
  155. data/lib/active_support/inflections.rb +22 -13
  156. data/lib/active_support/inflector/inflections.rb +175 -144
  157. data/lib/active_support/inflector/methods.rb +328 -91
  158. data/lib/active_support/inflector/transliterate.rb +51 -37
  159. data/lib/active_support/json/decoding.rb +31 -22
  160. data/lib/active_support/json/encoding.rb +88 -248
  161. data/lib/active_support/key_generator.rb +71 -0
  162. data/lib/active_support/lazy_load_hooks.rb +27 -25
  163. data/lib/active_support/locale/en.yml +102 -3
  164. data/lib/active_support/log_subscriber/test_helper.rb +24 -21
  165. data/lib/active_support/log_subscriber.rb +36 -49
  166. data/lib/active_support/logger.rb +106 -0
  167. data/lib/active_support/logger_silence.rb +28 -0
  168. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  169. data/lib/active_support/message_encryptor.rb +72 -36
  170. data/lib/active_support/message_verifier.rb +96 -24
  171. data/lib/active_support/multibyte/chars.rb +88 -333
  172. data/lib/active_support/multibyte/unicode.rb +156 -136
  173. data/lib/active_support/multibyte.rb +5 -28
  174. data/lib/active_support/notifications/fanout.rb +115 -19
  175. data/lib/active_support/notifications/instrumenter.rb +52 -15
  176. data/lib/active_support/notifications.rb +168 -33
  177. data/lib/active_support/number_helper/number_converter.rb +182 -0
  178. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  179. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  180. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  181. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  182. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  183. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  184. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  185. data/lib/active_support/number_helper.rb +368 -0
  186. data/lib/active_support/option_merger.rb +1 -1
  187. data/lib/active_support/ordered_hash.rb +18 -183
  188. data/lib/active_support/ordered_options.rb +44 -24
  189. data/lib/active_support/per_thread_registry.rb +58 -0
  190. data/lib/active_support/proxy_object.rb +13 -0
  191. data/lib/active_support/rails.rb +27 -0
  192. data/lib/active_support/railtie.rb +25 -34
  193. data/lib/active_support/reloader.rb +129 -0
  194. data/lib/active_support/rescuable.rb +98 -48
  195. data/lib/active_support/security_utils.rb +27 -0
  196. data/lib/active_support/string_inquirer.rb +14 -9
  197. data/lib/active_support/subscriber.rb +120 -0
  198. data/lib/active_support/tagged_logging.rb +78 -0
  199. data/lib/active_support/test_case.rb +69 -17
  200. data/lib/active_support/testing/assertions.rb +43 -41
  201. data/lib/active_support/testing/autorun.rb +12 -0
  202. data/lib/active_support/testing/constant_lookup.rb +50 -0
  203. data/lib/active_support/testing/declarative.rb +7 -21
  204. data/lib/active_support/testing/deprecation.rb +14 -33
  205. data/lib/active_support/testing/file_fixtures.rb +34 -0
  206. data/lib/active_support/testing/isolation.rb +53 -95
  207. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  208. data/lib/active_support/testing/setup_and_teardown.rb +21 -82
  209. data/lib/active_support/testing/stream.rb +42 -0
  210. data/lib/active_support/testing/tagged_logging.rb +25 -0
  211. data/lib/active_support/testing/time_helpers.rb +134 -0
  212. data/lib/active_support/time.rb +6 -23
  213. data/lib/active_support/time_with_zone.rb +239 -92
  214. data/lib/active_support/values/time_zone.rb +236 -160
  215. data/lib/active_support/values/unicode_tables.dat +0 -0
  216. data/lib/active_support/version.rb +5 -7
  217. data/lib/active_support/xml_mini/jdom.rb +19 -13
  218. data/lib/active_support/xml_mini/libxml.rb +3 -4
  219. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  220. data/lib/active_support/xml_mini/nokogiri.rb +3 -4
  221. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  222. data/lib/active_support/xml_mini/rexml.rb +8 -10
  223. data/lib/active_support/xml_mini.rb +66 -34
  224. data/lib/active_support.rb +40 -23
  225. metadata +185 -134
  226. data/CHANGELOG +0 -1534
  227. data/lib/active_support/base64.rb +0 -42
  228. data/lib/active_support/basic_object.rb +0 -21
  229. data/lib/active_support/buffered_logger.rb +0 -137
  230. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  231. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  232. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  233. data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
  234. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
  235. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
  236. data/lib/active_support/core_ext/date/freeze.rb +0 -31
  237. data/lib/active_support/core_ext/date_time/zones.rb +0 -21
  238. data/lib/active_support/core_ext/exception.rb +0 -3
  239. data/lib/active_support/core_ext/file/path.rb +0 -5
  240. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  241. data/lib/active_support/core_ext/float.rb +0 -1
  242. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
  243. data/lib/active_support/core_ext/hash/diff.rb +0 -13
  244. data/lib/active_support/core_ext/kernel/requires.rb +0 -28
  245. data/lib/active_support/core_ext/logger.rb +0 -81
  246. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  247. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  248. data/lib/active_support/core_ext/module/synchronization.rb +0 -43
  249. data/lib/active_support/core_ext/object/to_json.rb +0 -19
  250. data/lib/active_support/core_ext/proc.rb +0 -14
  251. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  252. data/lib/active_support/core_ext/process.rb +0 -1
  253. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  254. data/lib/active_support/core_ext/range/cover.rb +0 -3
  255. data/lib/active_support/core_ext/rexml.rb +0 -46
  256. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  257. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  258. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  259. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  260. data/lib/active_support/file_watcher.rb +0 -36
  261. data/lib/active_support/json/variable.rb +0 -9
  262. data/lib/active_support/memoizable.rb +0 -105
  263. data/lib/active_support/multibyte/exceptions.rb +0 -8
  264. data/lib/active_support/multibyte/utils.rb +0 -60
  265. data/lib/active_support/ruby/shim.rb +0 -22
  266. data/lib/active_support/secure_random.rb +0 -6
  267. data/lib/active_support/testing/mochaing.rb +0 -7
  268. data/lib/active_support/testing/pending.rb +0 -52
  269. data/lib/active_support/testing/performance/jruby.rb +0 -115
  270. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  271. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  272. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  273. data/lib/active_support/testing/performance/ruby.rb +0 -152
  274. data/lib/active_support/testing/performance.rb +0 -317
  275. data/lib/active_support/time/autoload.rb +0 -5
  276. data/lib/active_support/whiny_nil.rb +0 -60
@@ -1,106 +1,157 @@
1
1
  require 'active_support/duration'
2
- require 'active_support/core_ext/time/zones'
3
2
  require 'active_support/core_ext/time/conversions'
3
+ require 'active_support/time_with_zone'
4
+ require 'active_support/core_ext/time/zones'
5
+ require 'active_support/core_ext/date_and_time/calculations'
6
+ require 'active_support/core_ext/date/calculations'
4
7
 
5
8
  class Time
9
+ include DateAndTime::Calculations
10
+
6
11
  COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
7
- DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
8
12
 
9
13
  class << self
10
14
  # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
11
15
  def ===(other)
12
- other.is_a?(::Time)
16
+ super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
13
17
  end
14
18
 
15
- # Return the number of days in the given month.
19
+ # Returns the number of days in the given month.
16
20
  # If no year is specified, it will use the current year.
17
- def days_in_month(month, year = now.year)
18
- return 29 if month == 2 && ::Date.gregorian_leap?(year)
19
- COMMON_YEAR_DAYS_IN_MONTH[month]
20
- end
21
-
22
- # Returns a new Time if requested year can be accommodated by Ruby's Time class
23
- # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
24
- # otherwise returns a DateTime.
25
- def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
26
- time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
27
- # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
28
- time.year == year ? time : ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
29
- rescue
30
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
31
- end
32
-
33
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
34
- def utc_time(*args)
35
- time_with_datetime_fallback(:utc, *args)
21
+ def days_in_month(month, year = current.year)
22
+ if month == 2 && ::Date.gregorian_leap?(year)
23
+ 29
24
+ else
25
+ COMMON_YEAR_DAYS_IN_MONTH[month]
26
+ end
36
27
  end
37
28
 
38
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
39
- def local_time(*args)
40
- time_with_datetime_fallback(:local, *args)
29
+ # Returns the number of days in the given year.
30
+ # If no year is specified, it will use the current year.
31
+ def days_in_year(year = current.year)
32
+ days_in_month(2, year) + 337
41
33
  end
42
34
 
43
35
  # 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>.
44
36
  def current
45
37
  ::Time.zone ? ::Time.zone.now : ::Time.now
46
38
  end
47
- end
48
39
 
49
- # Tells whether the Time object's time lies in the past
50
- def past?
51
- self < ::Time.current
52
- end
40
+ # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
41
+ # instances can be used when called with a single argument
42
+ def at_with_coercion(*args)
43
+ return at_without_coercion(*args) if args.size != 1
53
44
 
54
- # Tells whether the Time object's time is today
55
- def today?
56
- to_date == ::Date.current
57
- end
45
+ # Time.at can be called with a time or numerical value
46
+ time_or_number = args.first
58
47
 
59
- # Tells whether the Time object's time lies in the future
60
- def future?
61
- self > ::Time.current
48
+ if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime)
49
+ at_without_coercion(time_or_number.to_f).getlocal
50
+ else
51
+ at_without_coercion(time_or_number)
52
+ end
53
+ end
54
+ alias_method :at_without_coercion, :at
55
+ alias_method :at, :at_with_coercion
62
56
  end
63
57
 
64
- # Seconds since midnight: Time.now.seconds_since_midnight
58
+ # Returns the number of seconds since 00:00:00.
59
+ #
60
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
61
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
62
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
65
63
  def seconds_since_midnight
66
64
  to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
67
65
  end
68
66
 
69
- # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
70
- # (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
71
- # minute is passed, then sec and usec is set to 0.
67
+ # Returns the number of seconds until 23:59:59.
68
+ #
69
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
70
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
71
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
72
+ def seconds_until_end_of_day
73
+ end_of_day.to_i - to_i
74
+ end
75
+
76
+ # Returns the fraction of a second as a +Rational+
77
+ #
78
+ # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
79
+ def sec_fraction
80
+ subsec
81
+ end
82
+
83
+ # Returns a new Time where one or more of the elements have been changed according
84
+ # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
85
+ # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
86
+ # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
87
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+
88
+ # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
89
+ # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
90
+ # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
91
+ #
92
+ # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
93
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
94
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
72
95
  def change(options)
73
- ::Time.send(
74
- utc? ? :utc_time : :local_time,
75
- options[:year] || year,
76
- options[:month] || month,
77
- options[:day] || day,
78
- options[:hour] || hour,
79
- options[:min] || (options[:hour] ? 0 : min),
80
- options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec),
81
- options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : usec)
82
- )
96
+ new_year = options.fetch(:year, year)
97
+ new_month = options.fetch(:month, month)
98
+ new_day = options.fetch(:day, day)
99
+ new_hour = options.fetch(:hour, hour)
100
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
101
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
102
+
103
+ if new_nsec = options[:nsec]
104
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
105
+ new_usec = Rational(new_nsec, 1000)
106
+ else
107
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
108
+ end
109
+
110
+ if utc?
111
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
112
+ elsif zone
113
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
114
+ else
115
+ raise ArgumentError, 'argument out of range' if new_usec >= 1000000
116
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
117
+ end
83
118
  end
84
119
 
85
- # Uses Date to provide precise Time calculations for years, months, and days.
86
- # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
87
- # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
88
- # <tt>:minutes</tt>, <tt>:seconds</tt>.
120
+ # Uses Date to provide precise Time calculations for years, months, and days
121
+ # according to the proleptic Gregorian calendar. The +options+ parameter
122
+ # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
123
+ # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
124
+ # <tt>:seconds</tt>.
125
+ #
126
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
127
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
128
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
129
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
130
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
89
131
  def advance(options)
90
132
  unless options[:weeks].nil?
91
133
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
92
- options[:days] = (options[:days] || 0) + 7 * partial_weeks
134
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
93
135
  end
94
136
 
95
137
  unless options[:days].nil?
96
138
  options[:days], partial_days = options[:days].divmod(1)
97
- options[:hours] = (options[:hours] || 0) + 24 * partial_days
139
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
98
140
  end
99
141
 
100
142
  d = to_date.advance(options)
143
+ d = d.gregorian if d.julian?
101
144
  time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
102
- seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
103
- seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
145
+ seconds_to_advance = \
146
+ options.fetch(:seconds, 0) +
147
+ options.fetch(:minutes, 0) * 60 +
148
+ options.fetch(:hours, 0) * 3600
149
+
150
+ if seconds_to_advance.zero?
151
+ time_advanced_by_date
152
+ else
153
+ time_advanced_by_date.since(seconds_to_advance)
154
+ end
104
155
  end
105
156
 
106
157
  # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
@@ -116,137 +167,69 @@ class Time
116
167
  end
117
168
  alias :in :since
118
169
 
119
- # Returns a new Time representing the time a number of specified weeks ago.
120
- def weeks_ago(weeks)
121
- advance(:weeks => -weeks)
122
- end
123
-
124
- # Returns a new Time representing the time a number of specified months ago
125
- def months_ago(months)
126
- advance(:months => -months)
127
- end
128
-
129
- # Returns a new Time representing the time a number of specified months in the future
130
- def months_since(months)
131
- advance(:months => months)
132
- end
133
-
134
- # Returns a new Time representing the time a number of specified years ago
135
- def years_ago(years)
136
- advance(:years => -years)
137
- end
138
-
139
- # Returns a new Time representing the time a number of specified years in the future
140
- def years_since(years)
141
- advance(:years => years)
142
- end
143
-
144
- # Short-hand for years_ago(1)
145
- def prev_year
146
- years_ago(1)
147
- end
148
-
149
- # Short-hand for years_since(1)
150
- def next_year
151
- years_since(1)
152
- end
153
-
154
- # Short-hand for months_ago(1)
155
- def prev_month
156
- months_ago(1)
157
- end
158
-
159
- # Short-hand for months_since(1)
160
- def next_month
161
- months_since(1)
162
- end
163
-
164
- # Returns a new Time representing the "start" of this week (Monday, 0:00)
165
- def beginning_of_week
166
- days_to_monday = wday!=0 ? wday-1 : 6
167
- (self - days_to_monday.days).midnight
168
- end
169
- alias :monday :beginning_of_week
170
- alias :at_beginning_of_week :beginning_of_week
171
-
172
- # Returns a new Time representing the end of this week, (end of Sunday)
173
- def end_of_week
174
- days_to_sunday = wday!=0 ? 7-wday : 0
175
- (self + days_to_sunday.days).end_of_day
176
- end
177
- alias :at_end_of_week :end_of_week
178
-
179
- # Returns a new Time representing the start of the given day in the previous week (default is Monday).
180
- def prev_week(day = :monday)
181
- ago(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
182
- end
183
-
184
- # Returns a new Time representing the start of the given day in next week (default is Monday).
185
- def next_week(day = :monday)
186
- since(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
187
- end
188
-
189
170
  # Returns a new Time representing the start of the day (0:00)
190
171
  def beginning_of_day
191
- #(self - seconds_since_midnight).change(:usec => 0)
192
172
  change(:hour => 0)
193
173
  end
194
174
  alias :midnight :beginning_of_day
195
175
  alias :at_midnight :beginning_of_day
196
176
  alias :at_beginning_of_day :beginning_of_day
197
177
 
198
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
199
- def end_of_day
200
- change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
201
- end
202
-
203
- # Returns a new Time representing the start of the month (1st of the month, 0:00)
204
- def beginning_of_month
205
- #self - ((self.mday-1).days + self.seconds_since_midnight)
206
- change(:day => 1, :hour => 0)
207
- end
208
- alias :at_beginning_of_month :beginning_of_month
209
-
210
- # Returns a new Time representing the end of the month (end of the last day of the month)
211
- def end_of_month
212
- #self - ((self.mday-1).days + self.seconds_since_midnight)
213
- last_day = ::Time.days_in_month(month, year)
214
- change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
178
+ # Returns a new Time representing the middle of the day (12:00)
179
+ def middle_of_day
180
+ change(:hour => 12)
215
181
  end
216
- alias :at_end_of_month :end_of_month
182
+ alias :midday :middle_of_day
183
+ alias :noon :middle_of_day
184
+ alias :at_midday :middle_of_day
185
+ alias :at_noon :middle_of_day
186
+ alias :at_middle_of_day :middle_of_day
217
187
 
218
- # Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)
219
- def beginning_of_quarter
220
- beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= month })
188
+ # Returns a new Time representing the end of the day, 23:59:59.999999
189
+ def end_of_day
190
+ change(
191
+ :hour => 23,
192
+ :min => 59,
193
+ :sec => 59,
194
+ :usec => Rational(999999999, 1000)
195
+ )
221
196
  end
222
- alias :at_beginning_of_quarter :beginning_of_quarter
197
+ alias :at_end_of_day :end_of_day
223
198
 
224
- # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
225
- def end_of_quarter
226
- beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= month }).end_of_month
199
+ # Returns a new Time representing the start of the hour (x:00)
200
+ def beginning_of_hour
201
+ change(:min => 0)
227
202
  end
228
- alias :at_end_of_quarter :end_of_quarter
203
+ alias :at_beginning_of_hour :beginning_of_hour
229
204
 
230
- # Returns a new Time representing the start of the year (1st of january, 0:00)
231
- def beginning_of_year
232
- change(:month => 1, :day => 1, :hour => 0)
205
+ # Returns a new Time representing the end of the hour, x:59:59.999999
206
+ def end_of_hour
207
+ change(
208
+ :min => 59,
209
+ :sec => 59,
210
+ :usec => Rational(999999999, 1000)
211
+ )
233
212
  end
234
- alias :at_beginning_of_year :beginning_of_year
213
+ alias :at_end_of_hour :end_of_hour
235
214
 
236
- # Returns a new Time representing the end of the year (end of the 31st of december)
237
- def end_of_year
238
- change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
215
+ # Returns a new Time representing the start of the minute (x:xx:00)
216
+ def beginning_of_minute
217
+ change(:sec => 0)
239
218
  end
240
- alias :at_end_of_year :end_of_year
219
+ alias :at_beginning_of_minute :beginning_of_minute
241
220
 
242
- # Convenience method which returns a new Time representing the time 1 day ago
243
- def yesterday
244
- advance(:days => -1)
221
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
222
+ def end_of_minute
223
+ change(
224
+ :sec => 59,
225
+ :usec => Rational(999999999, 1000)
226
+ )
245
227
  end
228
+ alias :at_end_of_minute :end_of_minute
246
229
 
247
- # Convenience method which returns a new Time representing the time 1 day since the instance time
248
- def tomorrow
249
- advance(:days => 1)
230
+ # Returns a Range representing the whole day of the current time.
231
+ def all_day
232
+ beginning_of_day..end_of_day
250
233
  end
251
234
 
252
235
  def plus_with_duration(other) #:nodoc:
@@ -282,9 +265,26 @@ class Time
282
265
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
283
266
  # can be chronologically compared with a Time
284
267
  def compare_with_coercion(other)
285
- # we're avoiding Time#to_datetime cause it's expensive
286
- other.is_a?(Time) ? compare_without_coercion(other.to_time) : to_datetime <=> other
268
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
269
+ if other.class == Time
270
+ compare_without_coercion(other)
271
+ elsif other.is_a?(Time)
272
+ compare_without_coercion(other.to_time)
273
+ else
274
+ to_datetime <=> other
275
+ end
287
276
  end
288
277
  alias_method :compare_without_coercion, :<=>
289
278
  alias_method :<=>, :compare_with_coercion
279
+
280
+ # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
281
+ # can be eql? to an equivalent Time
282
+ def eql_with_coercion(other)
283
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
284
+ other = other.comparable_time if other.respond_to?(:comparable_time)
285
+ eql_without_coercion(other)
286
+ end
287
+ alias_method :eql_without_coercion, :eql?
288
+ alias_method :eql?, :eql_with_coercion
289
+
290
290
  end
@@ -0,0 +1,5 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+
3
+ class Time
4
+ prepend DateAndTime::Compatibility
5
+ end
@@ -1,33 +1,42 @@
1
1
  require 'active_support/inflector/methods'
2
- require 'active_support/core_ext/time/publicize_conversion_methods'
3
2
  require 'active_support/values/time_zone'
4
3
 
5
4
  class Time
6
5
  DATE_FORMATS = {
7
- :db => "%Y-%m-%d %H:%M:%S",
8
- :number => "%Y%m%d%H%M%S",
9
- :time => "%H:%M",
10
- :short => "%d %b %H:%M",
11
- :long => "%B %d, %Y %H:%M",
12
- :long_ordinal => lambda { |time| time.strftime("%B #{ActiveSupport::Inflector.ordinalize(time.day)}, %Y %H:%M") },
13
- :rfc822 => lambda { |time| time.strftime("%a, %d %b %Y %H:%M:%S #{time.formatted_offset(false)}") }
6
+ :db => '%Y-%m-%d %H:%M:%S',
7
+ :number => '%Y%m%d%H%M%S',
8
+ :nsec => '%Y%m%d%H%M%S%9N',
9
+ :usec => '%Y%m%d%H%M%S%6N',
10
+ :time => '%H:%M',
11
+ :short => '%d %b %H:%M',
12
+ :long => '%B %d, %Y %H:%M',
13
+ :long_ordinal => lambda { |time|
14
+ day_format = ActiveSupport::Inflector.ordinalize(time.day)
15
+ time.strftime("%B #{day_format}, %Y %H:%M")
16
+ },
17
+ :rfc822 => lambda { |time|
18
+ offset_format = time.formatted_offset(false)
19
+ time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
20
+ },
21
+ :iso8601 => lambda { |time| time.iso8601 }
14
22
  }
15
23
 
16
- # Converts to a formatted string. See DATE_FORMATS for builtin formats.
24
+ # Converts to a formatted string. See DATE_FORMATS for built-in formats.
17
25
  #
18
26
  # This method is aliased to <tt>to_s</tt>.
19
27
  #
20
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
28
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
21
29
  #
22
- # time.to_formatted_s(:time) # => "06:10"
23
- # time.to_s(:time) # => "06:10"
30
+ # time.to_formatted_s(:time) # => "06:10"
31
+ # time.to_s(:time) # => "06:10"
24
32
  #
25
- # time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
26
- # time.to_formatted_s(:number) # => "20070118061017"
27
- # time.to_formatted_s(:short) # => "18 Jan 06:10"
28
- # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
29
- # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
30
- # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
33
+ # time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
34
+ # time.to_formatted_s(:number) # => "20070118061017"
35
+ # time.to_formatted_s(:short) # => "18 Jan 06:10"
36
+ # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
37
+ # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
38
+ # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
39
+ # time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00"
31
40
  #
32
41
  # == Adding your own time formats to +to_formatted_s+
33
42
  # You can add your own formats to the Time::DATE_FORMATS hash.
@@ -35,8 +44,8 @@ class Time
35
44
  # or Proc instance that takes a time argument as the value.
36
45
  #
37
46
  # # config/initializers/time_formats.rb
38
- # Time::DATE_FORMATS[:month_and_year] = "%B %Y"
39
- # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
47
+ # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
48
+ # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
40
49
  def to_formatted_s(format = :default)
41
50
  if formatter = DATE_FORMATS[format]
42
51
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
@@ -47,17 +56,12 @@ class Time
47
56
  alias_method :to_default_s, :to_s
48
57
  alias_method :to_s, :to_formatted_s
49
58
 
50
- # Returns the UTC offset as an +HH:MM formatted string.
59
+ # Returns a formatted string of the offset from UTC, or an alternative
60
+ # string if the time zone is already UTC.
51
61
  #
52
- # Time.local(2000).formatted_offset # => "-06:00"
53
- # Time.local(2000).formatted_offset(false) # => "-0600"
62
+ # Time.local(2000).formatted_offset # => "-06:00"
63
+ # Time.local(2000).formatted_offset(false) # => "-0600"
54
64
  def formatted_offset(colon = true, alternate_utc_string = nil)
55
65
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
56
66
  end
57
-
58
- # A method to keep Time, Date and DateTime instances interchangeable on conversions.
59
- # In this case, it simply returns +self+.
60
- def to_time
61
- self
62
- end unless method_defined?(:to_time)
63
67
  end
@@ -1,57 +1,3 @@
1
- # Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
2
- # unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load
3
- # methods so that utc instances can be flagged on dump, and coerced back to utc on load.
4
- if !Marshal.load(Marshal.dump(Time.now.utc)).utc?
5
- class Time
6
- class << self
7
- alias_method :_load_without_utc_flag, :_load
8
- def _load(marshaled_time)
9
- time = _load_without_utc_flag(marshaled_time)
10
- time.instance_eval do
11
- if defined?(@marshal_with_utc_coercion)
12
- val = remove_instance_variable("@marshal_with_utc_coercion")
13
- end
14
- val ? utc : self
15
- end
16
- end
17
- end
1
+ require 'active_support/deprecation'
18
2
 
19
- alias_method :_dump_without_utc_flag, :_dump
20
- def _dump(*args)
21
- obj = dup
22
- obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
23
- obj._dump_without_utc_flag(*args)
24
- end
25
- end
26
- end
27
-
28
- # Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
29
- # preserves utc_offset. Preserve zone also, even though it may not
30
- # work in some edge cases.
31
- if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
32
- class Time
33
- class << self
34
- alias_method :_load_without_zone, :_load
35
- def _load(marshaled_time)
36
- time = _load_without_zone(marshaled_time)
37
- time.instance_eval do
38
- if zone = defined?(@_zone) && remove_instance_variable('@_zone')
39
- ary = to_a
40
- ary[0] += subsec if ary[0] == sec
41
- ary[-1] = zone
42
- utc? ? Time.utc(*ary) : Time.local(*ary)
43
- else
44
- self
45
- end
46
- end
47
- end
48
- end
49
-
50
- alias_method :_dump_without_zone, :_dump
51
- def _dump(*args)
52
- obj = dup
53
- obj.instance_variable_set('@_zone', zone)
54
- obj._dump_without_zone(*args)
55
- end
56
- end
57
- end
3
+ ActiveSupport::Deprecation.warn("This is deprecated and will be removed in Rails 5.1 with no replacement.")