aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/helpers/date_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view/helpers/date_helper.rb')
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb53
1 files changed, 45 insertions, 8 deletions
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 326ad40c8d..853ab061d2 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -94,9 +94,20 @@ module ActionView
when 43200..86399 then locale.t :about_x_months, :count => 1
when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
else
- distance_in_years = distance_in_minutes / 525600
- minute_offset_for_leap_year = (distance_in_years / 4) * 1440
- remainder = ((distance_in_minutes - minute_offset_for_leap_year) % 525600)
+ fyear = from_time.year
+ fyear += 1 if from_time.month >= 3
+ tyear = to_time.year
+ tyear -= 1 if to_time.month < 3
+ leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
+ minute_offset_for_leap_year = leap_years * 1440
+ # Discount the leap year days when calculating year distance.
+ # e.g. if there are 20 leap year days between 2 dates having the same day
+ # and month then the based on 365 days calculation
+ # the distance in years will come out to over 80 years when in written
+ # english it would read better as about 80 years.
+ minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
+ remainder = (minutes_with_offset % 525600)
+ distance_in_years = (minutes_with_offset / 525600)
if remainder < 131400
locale.t(:about_x_years, :count => distance_in_years)
elsif remainder < 394200
@@ -207,7 +218,8 @@ module ActionView
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
# specified time-based attribute (identified by +method+) on an object assigned to the template (identified by
- # +object+). You can include the seconds with <tt>:include_seconds</tt>.
+ # +object+). You can include the seconds with <tt>:include_seconds</tt>. You can get hours in the AM/PM format
+ # with <tt>:ampm</tt> option.
#
# This method will also generate 3 input hidden tags, for the actual year, month and day unless the option
# <tt>:ignore_date</tt> is set to +true+. If you set the <tt>:ignore_date</tt> to +true+, you must have a
@@ -231,6 +243,9 @@ module ActionView
# time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
# time_select("post", "written_on", :prompt => true) # generic prompts for all
#
+ # # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
+ # time_select 'game', 'game_time', {:ampm => true}
+ #
# The selects are prepared for multi-parameter assignment to an Active Record object.
#
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
@@ -258,6 +273,9 @@ module ActionView
# # be stored in the trip variable in the departing attribute.
# datetime_select("trip", "departing", :default => 3.days.from_now)
#
+ # # Generate a datetime select with hours in the AM/PM format
+ # datetime_select("post", "written_on", :ampm => true)
+ #
# # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
# # as the written_on attribute.
# datetime_select("post", "written_on", :discard_type => true)
@@ -307,6 +325,9 @@ module ActionView
# # my_date_time (four days after today)
# select_datetime(my_date_time, :discard_type => true)
#
+ # # Generate a datetime field with hours in the AM/PM format
+ # select_datetime(my_date_time, :ampm => true)
+ #
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
# # prefixed with 'payday' rather than 'date'
# select_datetime(my_date_time, :prefix => 'payday')
@@ -388,7 +409,10 @@ module ActionView
# # separated by ':' and includes an input for seconds.
# select_time(my_time, :time_separator => ':', :include_seconds => true)
#
- # # Generates a time select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
+ # # Generate a time select field with hours in the AM/PM format
+ # select_time(my_time, :ampm => true)
+ #
+ # # Generates a time select with a custom prompt. Use <tt>:prompt</tt> to true for generic prompts.
# select_time(my_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
# select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
# select_time(my_time, :prompt => true) # generic prompts for all
@@ -469,6 +493,9 @@ module ActionView
# # generic prompt.
# select_hour(13, :prompt => 'Choose hour')
#
+ # # Generate a select field for hours in the AM/PM format
+ # select_hour(my_time, :ampm => true)
+ #
def select_hour(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_hour
end
@@ -602,6 +629,15 @@ module ActionView
:year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
}.freeze
+ AMPM_TRANSLATION = Hash[
+ [[0, "12 AM"], [1, "01 AM"], [2, "02 AM"], [3, "03 AM"],
+ [4, "04 AM"], [5, "05 AM"], [6, "06 AM"], [7, "07 AM"],
+ [8, "08 AM"], [9, "09 AM"], [10, "10 AM"], [11, "11 AM"],
+ [12, "12 PM"], [13, "01 PM"], [14, "02 PM"], [15, "03 PM"],
+ [16, "04 PM"], [17, "05 PM"], [18, "06 PM"], [19, "07 PM"],
+ [20, "08 PM"], [21, "09 PM"], [22, "10 PM"], [23, "11 PM"]]
+ ].freeze
+
def initialize(datetime, options = {}, html_options = {})
@options = options.dup
@html_options = html_options.dup
@@ -693,7 +729,7 @@ module ActionView
if @options[:use_hidden] || @options[:discard_hour]
build_hidden(:hour, hour)
else
- build_options_and_select(:hour, hour, :end => 23)
+ build_options_and_select(:hour, hour, :end => 23, :ampm => @options[:ampm])
end
end
@@ -817,7 +853,7 @@ module ActionView
start = options.delete(:start) || 0
stop = options.delete(:end) || 59
step = options.delete(:step) || 1
- options.reverse_merge!({:leading_zeros => true})
+ options.reverse_merge!({:leading_zeros => true, :ampm => false})
leading_zeros = options.delete(:leading_zeros)
select_options = []
@@ -825,7 +861,8 @@ module ActionView
value = leading_zeros ? sprintf("%02d", i) : i
tag_options = { :value => value }
tag_options[:selected] = "selected" if selected == i
- select_options << content_tag(:option, value, tag_options)
+ text = options[:ampm] ? AMPM_TRANSLATION[i] : value
+ select_options << content_tag(:option, text, tag_options)
end
(select_options.join("\n") + "\n").html_safe
end