activesupport 2.0.5 → 2.1.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 (236) hide show
  1. data/CHANGELOG +183 -5
  2. data/lib/active_support.rb +6 -2
  3. data/lib/active_support/base64.rb +5 -0
  4. data/lib/active_support/basic_object.rb +23 -4
  5. data/lib/active_support/buffered_logger.rb +17 -3
  6. data/lib/active_support/cache.rb +145 -0
  7. data/lib/active_support/cache/compressed_mem_cache_store.rb +15 -0
  8. data/lib/active_support/cache/drb_store.rb +15 -0
  9. data/lib/active_support/cache/file_store.rb +70 -0
  10. data/lib/active_support/cache/mem_cache_store.rb +100 -0
  11. data/lib/active_support/cache/memory_store.rb +38 -0
  12. data/lib/active_support/callbacks.rb +275 -0
  13. data/lib/active_support/core_ext/array/access.rb +2 -4
  14. data/lib/active_support/core_ext/array/conversions.rb +89 -5
  15. data/lib/active_support/core_ext/array/extract_options.rb +2 -1
  16. data/lib/active_support/core_ext/array/grouping.rb +3 -8
  17. data/lib/active_support/core_ext/array/random_access.rb +1 -1
  18. data/lib/active_support/core_ext/base64.rb +4 -0
  19. data/lib/active_support/core_ext/base64/encoding.rb +13 -0
  20. data/lib/active_support/core_ext/benchmark.rb +12 -0
  21. data/lib/active_support/core_ext/bigdecimal.rb +4 -0
  22. data/lib/active_support/core_ext/bigdecimal/conversions.rb +39 -4
  23. data/lib/active_support/core_ext/blank.rb +5 -2
  24. data/lib/active_support/core_ext/class/attribute_accessors.rb +7 -1
  25. data/lib/active_support/core_ext/class/delegating_attributes.rb +7 -1
  26. data/lib/active_support/core_ext/class/inheritable_attributes.rb +1 -1
  27. data/lib/active_support/core_ext/class/removal.rb +26 -0
  28. data/lib/active_support/core_ext/date/calculations.rb +28 -1
  29. data/lib/active_support/core_ext/date/conversions.rb +1 -0
  30. data/lib/active_support/core_ext/date_time.rb +2 -0
  31. data/lib/active_support/core_ext/date_time/calculations.rb +37 -2
  32. data/lib/active_support/core_ext/date_time/conversions.rb +27 -14
  33. data/lib/active_support/core_ext/enumerable.rb +16 -9
  34. data/lib/active_support/core_ext/exception.rb +8 -0
  35. data/lib/active_support/core_ext/file.rb +6 -6
  36. data/lib/active_support/core_ext/hash/conversions.rb +26 -8
  37. data/lib/active_support/core_ext/hash/indifferent_access.rb +35 -0
  38. data/lib/active_support/core_ext/hash/reverse_merge.rb +4 -1
  39. data/lib/active_support/core_ext/integer/even_odd.rb +10 -5
  40. data/lib/active_support/core_ext/integer/inflections.rb +0 -1
  41. data/lib/active_support/core_ext/kernel/daemonizing.rb +2 -10
  42. data/lib/active_support/core_ext/kernel/reporting.rb +8 -0
  43. data/lib/active_support/core_ext/module/attr_internal.rb +4 -3
  44. data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -1
  45. data/lib/active_support/core_ext/module/delegation.rb +5 -3
  46. data/lib/active_support/core_ext/module/inclusion.rb +19 -0
  47. data/lib/active_support/core_ext/module/introspection.rb +50 -16
  48. data/lib/active_support/core_ext/module/loading.rb +10 -0
  49. data/lib/active_support/core_ext/numeric.rb +3 -1
  50. data/lib/active_support/core_ext/numeric/conversions.rb +19 -0
  51. data/lib/active_support/core_ext/object/instance_variables.rb +52 -0
  52. data/lib/active_support/core_ext/object/misc.rb +1 -1
  53. data/lib/active_support/core_ext/process.rb +1 -0
  54. data/lib/active_support/core_ext/process/daemon.rb +25 -0
  55. data/lib/active_support/core_ext/range/conversions.rb +5 -1
  56. data/lib/active_support/core_ext/range/include_range.rb +8 -0
  57. data/lib/active_support/core_ext/range/overlaps.rb +3 -0
  58. data/lib/active_support/core_ext/string.rb +5 -10
  59. data/lib/active_support/core_ext/string/access.rb +72 -48
  60. data/lib/active_support/core_ext/string/conversions.rb +4 -4
  61. data/lib/active_support/core_ext/string/filters.rb +26 -0
  62. data/lib/active_support/core_ext/string/inflections.rb +56 -64
  63. data/lib/active_support/core_ext/string/iterators.rb +4 -0
  64. data/lib/active_support/core_ext/string/starts_ends_with.rb +12 -4
  65. data/lib/active_support/core_ext/string/unicode.rb +14 -7
  66. data/lib/active_support/core_ext/symbol.rb +1 -1
  67. data/lib/active_support/core_ext/time.rb +2 -0
  68. data/lib/active_support/core_ext/time/calculations.rb +75 -23
  69. data/lib/active_support/core_ext/time/conversions.rb +22 -35
  70. data/lib/active_support/core_ext/time/zones.rb +86 -0
  71. data/lib/active_support/dependencies.rb +92 -80
  72. data/lib/active_support/deprecation.rb +2 -16
  73. data/lib/active_support/duration.rb +4 -4
  74. data/lib/active_support/gzip.rb +25 -0
  75. data/lib/active_support/inflector.rb +92 -69
  76. data/lib/active_support/json.rb +17 -25
  77. data/lib/active_support/json/decoding.rb +1 -1
  78. data/lib/active_support/json/encoders/date.rb +11 -2
  79. data/lib/active_support/json/encoders/date_time.rb +11 -2
  80. data/lib/active_support/json/encoders/enumerable.rb +2 -2
  81. data/lib/active_support/json/encoders/hash.rb +3 -6
  82. data/lib/active_support/json/encoders/object.rb +1 -1
  83. data/lib/active_support/json/encoders/string.rb +8 -2
  84. data/lib/active_support/json/encoders/time.rb +11 -2
  85. data/lib/active_support/json/encoding.rb +0 -1
  86. data/lib/active_support/multibyte/chars.rb +8 -6
  87. data/lib/active_support/multibyte/handlers/utf8_handler.rb +11 -11
  88. data/lib/active_support/ordered_hash.rb +43 -0
  89. data/lib/active_support/ordered_options.rb +0 -38
  90. data/lib/active_support/test_case.rb +10 -2
  91. data/lib/active_support/testing/default.rb +3 -6
  92. data/lib/active_support/testing/setup_and_teardown.rb +93 -0
  93. data/lib/active_support/time_with_zone.rb +283 -0
  94. data/lib/active_support/values/time_zone.rb +336 -123
  95. data/lib/active_support/vendor.rb +12 -0
  96. data/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb +849 -0
  97. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo.rb +33 -0
  98. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone.rb +47 -0
  99. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone_info.rb +226 -0
  100. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Algiers.rb +55 -0
  101. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Cairo.rb +219 -0
  102. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Casablanca.rb +38 -0
  103. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Harare.rb +18 -0
  104. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Johannesburg.rb +25 -0
  105. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Monrovia.rb +22 -0
  106. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Nairobi.rb +23 -0
  107. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +166 -0
  108. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/San_Juan.rb +170 -0
  109. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Bogota.rb +23 -0
  110. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Caracas.rb +23 -0
  111. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chicago.rb +283 -0
  112. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chihuahua.rb +136 -0
  113. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Denver.rb +204 -0
  114. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Godthab.rb +161 -0
  115. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Guatemala.rb +27 -0
  116. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Halifax.rb +274 -0
  117. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Indiana/Indianapolis.rb +149 -0
  118. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Juneau.rb +194 -0
  119. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/La_Paz.rb +22 -0
  120. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Lima.rb +35 -0
  121. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Los_Angeles.rb +232 -0
  122. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mazatlan.rb +139 -0
  123. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mexico_City.rb +144 -0
  124. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Monterrey.rb +131 -0
  125. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/New_York.rb +282 -0
  126. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Phoenix.rb +30 -0
  127. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Regina.rb +74 -0
  128. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Santiago.rb +205 -0
  129. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/St_Johns.rb +288 -0
  130. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Tijuana.rb +196 -0
  131. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Almaty.rb +67 -0
  132. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baghdad.rb +73 -0
  133. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baku.rb +161 -0
  134. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Bangkok.rb +20 -0
  135. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Chongqing.rb +33 -0
  136. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Dhaka.rb +27 -0
  137. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
  138. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Irkutsk.rb +165 -0
  139. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jakarta.rb +30 -0
  140. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jerusalem.rb +163 -0
  141. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kabul.rb +20 -0
  142. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kamchatka.rb +163 -0
  143. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Karachi.rb +28 -0
  144. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Katmandu.rb +20 -0
  145. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kolkata.rb +25 -0
  146. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Krasnoyarsk.rb +163 -0
  147. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuala_Lumpur.rb +31 -0
  148. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuwait.rb +18 -0
  149. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Magadan.rb +163 -0
  150. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Muscat.rb +18 -0
  151. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Novosibirsk.rb +164 -0
  152. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Rangoon.rb +24 -0
  153. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Riyadh.rb +18 -0
  154. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Seoul.rb +34 -0
  155. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Shanghai.rb +35 -0
  156. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Singapore.rb +33 -0
  157. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Taipei.rb +59 -0
  158. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tashkent.rb +47 -0
  159. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tbilisi.rb +78 -0
  160. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tehran.rb +121 -0
  161. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tokyo.rb +30 -0
  162. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Ulaanbaatar.rb +65 -0
  163. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Urumqi.rb +33 -0
  164. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Vladivostok.rb +164 -0
  165. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yakutsk.rb +163 -0
  166. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yekaterinburg.rb +165 -0
  167. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yerevan.rb +165 -0
  168. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Azores.rb +270 -0
  169. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Cape_Verde.rb +23 -0
  170. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/South_Georgia.rb +18 -0
  171. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Adelaide.rb +187 -0
  172. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Brisbane.rb +35 -0
  173. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Darwin.rb +29 -0
  174. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Hobart.rb +193 -0
  175. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Melbourne.rb +185 -0
  176. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Perth.rb +37 -0
  177. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Sydney.rb +185 -0
  178. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Etc/UTC.rb +16 -0
  179. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Amsterdam.rb +228 -0
  180. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Athens.rb +185 -0
  181. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Belgrade.rb +163 -0
  182. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Berlin.rb +188 -0
  183. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bratislava.rb +13 -0
  184. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Brussels.rb +232 -0
  185. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bucharest.rb +181 -0
  186. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Budapest.rb +197 -0
  187. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Copenhagen.rb +179 -0
  188. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Dublin.rb +276 -0
  189. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Helsinki.rb +163 -0
  190. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Istanbul.rb +218 -0
  191. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Kiev.rb +168 -0
  192. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Lisbon.rb +268 -0
  193. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Ljubljana.rb +13 -0
  194. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/London.rb +288 -0
  195. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Madrid.rb +211 -0
  196. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Minsk.rb +170 -0
  197. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Moscow.rb +181 -0
  198. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Paris.rb +232 -0
  199. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Prague.rb +187 -0
  200. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Riga.rb +176 -0
  201. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Rome.rb +215 -0
  202. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sarajevo.rb +13 -0
  203. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Skopje.rb +13 -0
  204. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sofia.rb +173 -0
  205. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Stockholm.rb +165 -0
  206. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Tallinn.rb +172 -0
  207. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vienna.rb +183 -0
  208. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vilnius.rb +170 -0
  209. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Warsaw.rb +212 -0
  210. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Zagreb.rb +13 -0
  211. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Auckland.rb +202 -0
  212. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Fiji.rb +23 -0
  213. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Guam.rb +22 -0
  214. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Honolulu.rb +28 -0
  215. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Majuro.rb +20 -0
  216. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Midway.rb +25 -0
  217. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Noumea.rb +25 -0
  218. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Pago_Pago.rb +26 -0
  219. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
  220. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
  221. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/info_timezone.rb +52 -0
  222. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone.rb +51 -0
  223. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone_info.rb +44 -0
  224. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb +95 -0
  225. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/time_or_datetime.rb +292 -0
  226. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone.rb +508 -0
  227. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_definition.rb +56 -0
  228. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_info.rb +40 -0
  229. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_offset_info.rb +94 -0
  230. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_period.rb +198 -0
  231. data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_transition_info.rb +138 -0
  232. data/lib/active_support/version.rb +2 -2
  233. data/lib/active_support/whiny_nil.rb +30 -10
  234. metadata +175 -5
  235. data/lib/active_support/core_ext/rexml.rb +0 -38
  236. data/lib/active_support/testing.rb +0 -1
@@ -1,4 +1,4 @@
1
- require 'parsedate'
1
+ require 'date'
2
2
 
3
3
  module ActiveSupport #:nodoc:
4
4
  module CoreExtensions #:nodoc:
@@ -12,15 +12,15 @@ module ActiveSupport #:nodoc:
12
12
 
13
13
  # Form can be either :utc (default) or :local.
14
14
  def to_time(form = :utc)
15
- ::Time.send("#{form}_time", *ParseDate.parsedate(self)[0..5].map {|arg| arg || 0})
15
+ ::Time.send("#{form}_time", *::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 })
16
16
  end
17
17
 
18
18
  def to_date
19
- ::Date.new(*ParseDate.parsedate(self)[0..2])
19
+ ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
20
20
  end
21
21
 
22
22
  def to_datetime
23
- ::DateTime.civil(*ParseDate.parsedate(self)[0..5].map {|arg| arg || 0} << 0)
23
+ ::DateTime.civil(*::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 })
24
24
  end
25
25
  end
26
26
  end
@@ -0,0 +1,26 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module String #:nodoc:
4
+ module Filters
5
+ # Returns the string, first removing all whitespace on both ends of
6
+ # the string, and then changing remaining consecutive whitespace
7
+ # groups into one space each.
8
+ #
9
+ # Examples:
10
+ # %{ Multi-line
11
+ # string }.squish # => "Multi-line string"
12
+ # " foo bar \n \t boo".squish # => "foo bar boo"
13
+ def squish
14
+ dup.squish!
15
+ end
16
+
17
+ # Performs a destructive squish. See String#squish.
18
+ def squish!
19
+ strip!
20
+ gsub!(/\s+/, ' ')
21
+ self
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,44 +5,42 @@ module ActiveSupport #:nodoc:
5
5
  module String #:nodoc:
6
6
  # String inflections define new methods on the String class to transform names for different purposes.
7
7
  # For instance, you can figure out the name of a database from the name of a class.
8
- # "ScaleScore".tableize => "scale_scores"
8
+ #
9
+ # "ScaleScore".tableize # => "scale_scores"
9
10
  module Inflections
10
11
  # Returns the plural form of the word in the string.
11
12
  #
12
- # Examples
13
- # "post".pluralize #=> "posts"
14
- # "octopus".pluralize #=> "octopi"
15
- # "sheep".pluralize #=> "sheep"
16
- # "words".pluralize #=> "words"
17
- # "the blue mailman".pluralize #=> "the blue mailmen"
18
- # "CamelOctopus".pluralize #=> "CamelOctopi"
13
+ # "post".pluralize # => "posts"
14
+ # "octopus".pluralize # => "octopi"
15
+ # "sheep".pluralize # => "sheep"
16
+ # "words".pluralize # => "words"
17
+ # "the blue mailman".pluralize # => "the blue mailmen"
18
+ # "CamelOctopus".pluralize # => "CamelOctopi"
19
19
  def pluralize
20
20
  Inflector.pluralize(self)
21
21
  end
22
22
 
23
- # The reverse of pluralize, returns the singular form of a word in a string.
23
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
24
24
  #
25
- # Examples
26
- # "posts".singularize #=> "post"
27
- # "octopi".singularize #=> "octopus"
28
- # "sheep".singluarize #=> "sheep"
29
- # "word".singluarize #=> "word"
30
- # "the blue mailmen".singularize #=> "the blue mailman"
31
- # "CamelOctopi".singularize #=> "CamelOctopus"
25
+ # "posts".singularize # => "post"
26
+ # "octopi".singularize # => "octopus"
27
+ # "sheep".singluarize # => "sheep"
28
+ # "word".singluarize # => "word"
29
+ # "the blue mailmen".singularize # => "the blue mailman"
30
+ # "CamelOctopi".singularize # => "CamelOctopus"
32
31
  def singularize
33
32
  Inflector.singularize(self)
34
33
  end
35
34
 
36
- # By default, camelize converts strings to UpperCamelCase. If the argument to camelize
37
- # is set to ":lower" then camelize produces lowerCamelCase.
35
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
36
+ # is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
38
37
  #
39
- # camelize will also convert '/' to '::' which is useful for converting paths to namespaces
38
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
40
39
  #
41
- # Examples
42
- # "active_record".camelize #=> "ActiveRecord"
43
- # "active_record".camelize(:lower) #=> "activeRecord"
44
- # "active_record/errors".camelize #=> "ActiveRecord::Errors"
45
- # "active_record/errors".camelize(:lower) #=> "activeRecord::Errors"
40
+ # "active_record".camelize # => "ActiveRecord"
41
+ # "active_record".camelize(:lower) # => "activeRecord"
42
+ # "active_record/errors".camelize # => "ActiveRecord::Errors"
43
+ # "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
46
44
  def camelize(first_letter = :upper)
47
45
  case first_letter
48
46
  when :upper then Inflector.camelize(self, true)
@@ -52,78 +50,72 @@ module ActiveSupport #:nodoc:
52
50
  alias_method :camelcase, :camelize
53
51
 
54
52
  # Capitalizes all the words and replaces some characters in the string to create
55
- # a nicer looking title. Titleize is meant for creating pretty output. It is not
53
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
56
54
  # used in the Rails internals.
57
55
  #
58
- # titleize is also aliased as as titlecase
56
+ # +titleize+ is also aliased as +titlecase+.
59
57
  #
60
- # Examples
61
- # "man from the boondocks".titleize #=> "Man From The Boondocks"
62
- # "x-men: the last stand".titleize #=> "X Men: The Last Stand"
58
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
59
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
63
60
  def titleize
64
61
  Inflector.titleize(self)
65
62
  end
66
63
  alias_method :titlecase, :titleize
67
64
 
68
- # The reverse of +camelize+. Makes an underscored form from the expression in the string.
65
+ # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
69
66
  #
70
- # Changes '::' to '/' to convert namespaces to paths.
67
+ # +underscore+ will also change '::' to '/' to convert namespaces to paths.
71
68
  #
72
- # Examples
73
- # "ActiveRecord".underscore #=> "active_record"
74
- # "ActiveRecord::Errors".underscore #=> active_record/errors
69
+ # "ActiveRecord".underscore # => "active_record"
70
+ # "ActiveRecord::Errors".underscore # => active_record/errors
75
71
  def underscore
76
72
  Inflector.underscore(self)
77
73
  end
78
74
 
79
75
  # Replaces underscores with dashes in the string.
80
76
  #
81
- # Example
82
- # "puni_puni" #=> "puni-puni"
77
+ # "puni_puni" # => "puni-puni"
83
78
  def dasherize
84
79
  Inflector.dasherize(self)
85
80
  end
86
81
 
87
- # Removes the module part from the expression in the string
82
+ # Removes the module part from the constant expression in the string.
88
83
  #
89
- # Examples
90
- # "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
91
- # "Inflections".demodulize #=> "Inflections"
84
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
85
+ # "Inflections".demodulize # => "Inflections"
92
86
  def demodulize
93
87
  Inflector.demodulize(self)
94
88
  end
95
89
 
96
- # Create the name of a table like Rails does for models to table names. This method
97
- # uses the pluralize method on the last word in the string.
90
+ # Creates the name of a table like Rails does for models to table names. This method
91
+ # uses the +pluralize+ method on the last word in the string.
98
92
  #
99
- # Examples
100
- # "RawScaledScorer".tableize #=> "raw_scaled_scorers"
101
- # "egg_and_ham".tableize #=> "egg_and_hams"
102
- # "fancyCategory".tableize #=> "fancy_categories"
93
+ # "RawScaledScorer".tableize # => "raw_scaled_scorers"
94
+ # "egg_and_ham".tableize # => "egg_and_hams"
95
+ # "fancyCategory".tableize # => "fancy_categories"
103
96
  def tableize
104
97
  Inflector.tableize(self)
105
98
  end
106
99
 
107
100
  # Create a class name from a plural table name like Rails does for table names to models.
108
- # Note that this returns a string and not a Class. (To convert to an actual class
109
- # follow classify with constantize.)
101
+ # Note that this returns a string and not a class. (To convert to an actual class
102
+ # follow +classify+ with +constantize+.)
110
103
  #
111
- # Examples
112
- # "egg_and_hams".classify #=> "EggAndHam"
113
- # "posts".classify #=> "Post"
104
+ # "egg_and_hams".classify # => "EggAndHam"
105
+ # "posts".classify # => "Post"
114
106
  #
115
- # Singular names are not handled correctly
116
- # "business".classify #=> "Busines"
107
+ # Singular names are not handled correctly.
108
+ #
109
+ # "business".classify # => "Busines"
117
110
  def classify
118
111
  Inflector.classify(self)
119
112
  end
120
113
 
121
- # Capitalizes the first word and turns underscores into spaces and strips _id.
122
- # Like titleize, this is meant for creating pretty output.
114
+ # Capitalizes the first word, turns underscores into spaces, and strips '_id'.
115
+ # Like +titleize+, this is meant for creating pretty output.
123
116
  #
124
- # Examples
125
- # "employee_salary" #=> "Employee salary"
126
- # "author_id" #=> "Author"
117
+ # "employee_salary" # => "Employee salary"
118
+ # "author_id" # => "Author"
127
119
  def humanize
128
120
  Inflector.humanize(self)
129
121
  end
@@ -133,20 +125,20 @@ module ActiveSupport #:nodoc:
133
125
  # the method should put '_' between the name and 'id'.
134
126
  #
135
127
  # Examples
136
- # "Message".foreign_key #=> "message_id"
137
- # "Message".foreign_key(false) #=> "messageid"
138
- # "Admin::Post".foreign_key #=> "post_id"
128
+ # "Message".foreign_key # => "message_id"
129
+ # "Message".foreign_key(false) # => "messageid"
130
+ # "Admin::Post".foreign_key # => "post_id"
139
131
  def foreign_key(separate_class_name_and_id_with_underscore = true)
140
132
  Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
141
133
  end
142
134
 
143
- # Constantize tries to find a declared constant with the name specified
135
+ # +constantize+ tries to find a declared constant with the name specified
144
136
  # in the string. It raises a NameError when the name is not in CamelCase
145
137
  # or is not initialized.
146
138
  #
147
139
  # Examples
148
- # "Module".constantize #=> Module
149
- # "Class".constantize #=> Class
140
+ # "Module".constantize # => Module
141
+ # "Class".constantize # => Class
150
142
  def constantize
151
143
  Inflector.constantize(self)
152
144
  end
@@ -5,6 +5,10 @@ module ActiveSupport #:nodoc:
5
5
  module String #:nodoc:
6
6
  # Custom string iterators
7
7
  module Iterators
8
+ def self.append_features(base)
9
+ super unless '1.9'.respond_to?(:each_char)
10
+ end
11
+
8
12
  # Yields a single-character string for each character in the string.
9
13
  # When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
10
14
  def each_char
@@ -3,10 +3,18 @@ module ActiveSupport #:nodoc:
3
3
  module String #:nodoc:
4
4
  # Additional string tests.
5
5
  module StartsEndsWith
6
- def self.included(base)
7
- base.class_eval do
8
- alias_method :start_with?, :starts_with?
9
- alias_method :end_with?, :ends_with?
6
+ def self.append_features(base)
7
+ if '1.8.7 and up'.respond_to?(:start_with?)
8
+ base.class_eval do
9
+ alias_method :starts_with?, :start_with?
10
+ alias_method :ends_with?, :end_with?
11
+ end
12
+ else
13
+ super
14
+ base.class_eval do
15
+ alias_method :start_with?, :starts_with?
16
+ alias_method :end_with?, :ends_with?
17
+ end
10
18
  end
11
19
  end
12
20
 
@@ -1,33 +1,40 @@
1
1
  module ActiveSupport #:nodoc:
2
2
  module CoreExtensions #:nodoc:
3
3
  module String #:nodoc:
4
- if RUBY_VERSION < '1.9'
4
+ unless '1.9'.respond_to?(:force_encoding)
5
5
  # Define methods for handling unicode data.
6
6
  module Unicode
7
+ def self.append_features(base)
8
+ if '1.8.7'.respond_to?(:chars)
9
+ base.class_eval { remove_method :chars }
10
+ end
11
+ super
12
+ end
13
+
7
14
  # +chars+ is a Unicode safe proxy for string methods. It creates and returns an instance of the
8
15
  # ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all
9
16
  # the String methods are defined on this proxy class. Undefined methods are forwarded to String, so all of the
10
17
  # string overrides can also be called through the +chars+ proxy.
11
18
  #
12
19
  # name = 'Claus Müller'
13
- # name.reverse #=> "rell??M sualC"
14
- # name.length #=> 13
20
+ # name.reverse # => "rell??M sualC"
21
+ # name.length # => 13
15
22
  #
16
- # name.chars.reverse.to_s #=> "rellüM sualC"
17
- # name.chars.length #=> 12
23
+ # name.chars.reverse.to_s # => "rellüM sualC"
24
+ # name.chars.length # => 12
18
25
  #
19
26
  #
20
27
  # All the methods on the chars proxy which normally return a string will return a Chars object. This allows
21
28
  # method chaining on the result of any of these methods.
22
29
  #
23
- # name.chars.reverse.length #=> 12
30
+ # name.chars.reverse.length # => 12
24
31
  #
25
32
  # The Char object tries to be as interchangeable with String objects as possible: sorting and comparing between
26
33
  # String and Char work like expected. The bang! methods change the internal string representation in the Chars
27
34
  # object. Interoperability problems can be resolved easily with a +to_s+ call.
28
35
  #
29
36
  # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars and
30
- # ActiveSupport::Multibyte::Handlers::UTF8Handler
37
+ # ActiveSupport::Multibyte::Handlers::UTF8Handler.
31
38
  def chars
32
39
  ActiveSupport::Multibyte::Chars.new(self)
33
40
  end
@@ -1,4 +1,4 @@
1
- unless :test.respond_to?(:to_proc)
1
+ unless :to_proc.respond_to?(:to_proc)
2
2
  class Symbol
3
3
  # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
4
4
  #
@@ -11,9 +11,11 @@ end
11
11
  require 'active_support/core_ext/time/behavior'
12
12
  require 'active_support/core_ext/time/calculations'
13
13
  require 'active_support/core_ext/time/conversions'
14
+ require 'active_support/core_ext/time/zones'
14
15
 
15
16
  class Time#:nodoc:
16
17
  include ActiveSupport::CoreExtensions::Time::Behavior
17
18
  include ActiveSupport::CoreExtensions::Time::Calculations
18
19
  include ActiveSupport::CoreExtensions::Time::Conversions
20
+ include ActiveSupport::CoreExtensions::Time::Zones
19
21
  end
@@ -9,24 +9,31 @@ module ActiveSupport #:nodoc:
9
9
  base.class_eval do
10
10
  alias_method :plus_without_duration, :+
11
11
  alias_method :+, :plus_with_duration
12
+
12
13
  alias_method :minus_without_duration, :-
13
14
  alias_method :-, :minus_with_duration
15
+
16
+ alias_method :minus_without_coercion, :-
17
+ alias_method :-, :minus_with_coercion
18
+
19
+ alias_method :compare_without_coercion, :<=>
20
+ alias_method :<=>, :compare_with_coercion
14
21
  end
15
22
  end
16
23
 
24
+ COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
25
+
17
26
  module ClassMethods
18
- # Return the number of days in the given month. If a year is given,
19
- # February will return the correct number of days for leap years.
20
- # Otherwise, this method will always report February as having 28
21
- # days.
22
- def days_in_month(month, year=nil)
23
- if month == 2
24
- !year.nil? && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) ? 29 : 28
25
- elsif month <= 7
26
- month % 2 == 0 ? 30 : 31
27
- else
28
- month % 2 == 0 ? 31 : 30
29
- end
27
+ # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
28
+ def ===(other)
29
+ other.is_a?(::Time)
30
+ end
31
+
32
+ # Return the number of days in the given month.
33
+ # If no year is specified, it will use the current year.
34
+ def days_in_month(month, year = now.year)
35
+ return 29 if month == 2 && ::Date.gregorian_leap?(year)
36
+ COMMON_YEAR_DAYS_IN_MONTH[month]
30
37
  end
31
38
 
32
39
  # Returns a new Time if requested year can be accommodated by Ruby's Time class
@@ -39,12 +46,12 @@ module ActiveSupport #:nodoc:
39
46
  ::DateTime.civil(year, month, day, hour, min, sec, offset)
40
47
  end
41
48
 
42
- # wraps class method time_with_datetime_fallback with utc_or_local == :utc
49
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
43
50
  def utc_time(*args)
44
51
  time_with_datetime_fallback(:utc, *args)
45
52
  end
46
53
 
47
- # wraps class method time_with_datetime_fallback with utc_or_local == :local
54
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
48
55
  def local_time(*args)
49
56
  time_with_datetime_fallback(:local, *args)
50
57
  end
@@ -71,8 +78,10 @@ module ActiveSupport #:nodoc:
71
78
  )
72
79
  end
73
80
 
74
- # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with
75
- # any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
81
+ # Uses Date to provide precise Time calculations for years, months, and days.
82
+ # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
83
+ # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
84
+ # <tt>:minutes</tt>, <tt>:seconds</tt>.
76
85
  def advance(options)
77
86
  d = to_date.advance(options)
78
87
  time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
@@ -81,18 +90,21 @@ module ActiveSupport #:nodoc:
81
90
  end
82
91
 
83
92
  # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
84
- # Do not use this method in combination with x.months, use months_ago instead!
85
93
  def ago(seconds)
86
94
  self.since(-seconds)
87
95
  end
88
96
 
89
97
  # Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around
90
- # the Numeric extension. Do not use this method in combination with x.months, use months_since instead!
98
+ # the Numeric extension.
91
99
  def since(seconds)
92
- initial_dst = self.dst? ? 1 : 0
93
100
  f = seconds.since(self)
94
- final_dst = f.dst? ? 1 : 0
95
- (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
101
+ if ActiveSupport::Duration === seconds
102
+ f
103
+ else
104
+ initial_dst = self.dst? ? 1 : 0
105
+ final_dst = f.dst? ? 1 : 0
106
+ (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
107
+ end
96
108
  rescue
97
109
  self.to_datetime.since(seconds)
98
110
  end
@@ -147,6 +159,13 @@ module ActiveSupport #:nodoc:
147
159
  alias :monday :beginning_of_week
148
160
  alias :at_beginning_of_week :beginning_of_week
149
161
 
162
+ # Returns a new Time representing the end of this week (Sunday, 23:59:59)
163
+ def end_of_week
164
+ days_to_sunday = self.wday!=0 ? 7-self.wday : 0
165
+ (self + days_to_sunday.days).end_of_day
166
+ end
167
+ alias :at_end_of_week :end_of_week
168
+
150
169
  # Returns a new Time representing the start of the given day in next week (default is Monday).
151
170
  def next_week(day = :monday)
152
171
  days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
@@ -187,20 +206,32 @@ module ActiveSupport #:nodoc:
187
206
  end
188
207
  alias :at_beginning_of_quarter :beginning_of_quarter
189
208
 
209
+ # Returns a new Time representing the end of the quarter (last day of march, june, september, december, 23:59:59)
210
+ def end_of_quarter
211
+ change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
212
+ end
213
+ alias :at_end_of_quarter :end_of_quarter
214
+
190
215
  # Returns a new Time representing the start of the year (1st of january, 0:00)
191
216
  def beginning_of_year
192
217
  change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
193
218
  end
194
219
  alias :at_beginning_of_year :beginning_of_year
195
220
 
221
+ # Returns a new Time representing the end of the year (31st of december, 23:59:59)
222
+ def end_of_year
223
+ change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59)
224
+ end
225
+ alias :at_end_of_year :end_of_year
226
+
196
227
  # Convenience method which returns a new Time representing the time 1 day ago
197
228
  def yesterday
198
- self.ago(1.day)
229
+ advance(:days => -1)
199
230
  end
200
231
 
201
232
  # Convenience method which returns a new Time representing the time 1 day since the instance time
202
233
  def tomorrow
203
- self.since(1.day)
234
+ advance(:days => 1)
204
235
  end
205
236
 
206
237
  def plus_with_duration(other) #:nodoc:
@@ -218,6 +249,27 @@ module ActiveSupport #:nodoc:
218
249
  minus_without_duration(other)
219
250
  end
220
251
  end
252
+
253
+ # Time#- can also be used to determine the number of seconds between two Time instances.
254
+ # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
255
+ # are coerced into values that Time#- will recognize
256
+ def minus_with_coercion(other)
257
+ other = other.comparable_time if other.respond_to?(:comparable_time)
258
+ minus_without_coercion(other)
259
+ end
260
+
261
+ # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
262
+ # can be chronologically compared with a Time
263
+ def compare_with_coercion(other)
264
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparision
265
+ other = other.comparable_time if other.respond_to?(:comparable_time)
266
+ if other.acts_like?(:date)
267
+ # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
268
+ to_datetime.compare_without_coercion(other)
269
+ else
270
+ compare_without_coercion(other)
271
+ end
272
+ end
221
273
  end
222
274
  end
223
275
  end