Last active
December 20, 2015 01:19
-
-
Save tclh123/6048598 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {}) | |
if include_seconds_or_options.is_a?(Hash) | |
options = include_seconds_or_options | |
else | |
ActiveSupport::Deprecation.warn "distance_of_time_in_words and time_ago_in_words now accept :include_seconds " + | |
"as a part of options hash, not a boolean argument" | |
options[:include_seconds] ||= !!include_seconds_or_options | |
end | |
options = { | |
scope: :'datetime.distance_in_words' | |
}.merge!(options) | |
from_time = from_time.to_time if from_time.respond_to?(:to_time) | |
to_time = to_time.to_time if to_time.respond_to?(:to_time) | |
from_time, to_time = to_time, from_time if from_time > to_time | |
distance_in_minutes = ((to_time - from_time)/60.0).round | |
distance_in_seconds = (to_time - from_time).round | |
I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale| | |
case distance_in_minutes | |
when 0..1 | |
return distance_in_minutes == 0 ? | |
locale.t(:less_than_x_minutes, :count => 1) : | |
locale.t(:x_minutes, :count => distance_in_minutes) unless options[:include_seconds] | |
case distance_in_seconds | |
when 0..4 then locale.t :less_than_x_seconds, :count => 5 | |
when 5..9 then locale.t :less_than_x_seconds, :count => 10 | |
when 10..19 then locale.t :less_than_x_seconds, :count => 20 | |
when 20..39 then locale.t :half_a_minute | |
when 40..59 then locale.t :less_than_x_minutes, :count => 1 | |
else locale.t :x_minutes, :count => 1 | |
end | |
when 2...45 then locale.t :x_minutes, :count => distance_in_minutes | |
when 45...90 then locale.t :about_x_hours, :count => 1 | |
# 90 mins up to 24 hours | |
when 90...1440 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round | |
# 24 hours up to 42 hours | |
when 1440...2520 then locale.t :x_days, :count => 1 | |
# 42 hours up to 30 days | |
when 2520...43200 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round | |
# 30 days up to 60 days | |
when 43200...86400 then locale.t :about_x_months, :count => (distance_in_minutes.to_f / 43200.0).round | |
# 60 days up to 365 days | |
when 86400...525600 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round | |
else | |
if from_time.acts_like?(:time) && to_time.acts_like?(:time) | |
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 | |
else | |
minutes_with_offset = distance_in_minutes | |
end | |
remainder = (minutes_with_offset % 525600) | |
distance_in_years = (minutes_with_offset.div 525600) | |
if remainder < 131400 | |
locale.t(:about_x_years, :count => distance_in_years) | |
elsif remainder < 394200 | |
locale.t(:over_x_years, :count => distance_in_years) | |
else | |
locale.t(:almost_x_years, :count => distance_in_years + 1) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment