mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 01:42:04 +08:00
30990006a9
This reduces chances of errors where consumers of strings mutate inputs and reduces memory usage of the app. Test suite passes now, but there may be some stuff left, so we will run a few sites on a branch prior to merging
75 lines
3.5 KiB
Ruby
75 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Sam: This has now forked of rails. Trouble is we would never like to use "about 1 month" ever, we only want months for 2 or more months.
|
|
#
|
|
# Backporting a fix to rails itself may get too complex
|
|
module FreedomPatches
|
|
module Rails4
|
|
|
|
def self.distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})
|
|
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)
|
|
distance = (to_time.to_f - from_time.to_f).abs
|
|
distance_in_minutes = (distance / 60.0).round
|
|
distance_in_seconds = distance.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 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..44 then locale.t :x_minutes, count: distance_in_minutes
|
|
when 45..89 then locale.t :about_x_hours, count: 1
|
|
when 90..1439 then locale.t :about_x_hours, count: (distance_in_minutes.to_f / 60.0).round
|
|
when 1440..2519 then locale.t :x_days, count: 1
|
|
|
|
# this is were we diverge from Rails
|
|
when 2520..129599 then locale.t :x_days, count: (distance_in_minutes.to_f / 1440.0).round
|
|
when 129600..525599 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round
|
|
else
|
|
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
|
|
locale.t(:over_x_years, count: distance_in_years)
|
|
else
|
|
locale.t(:almost_x_years, count: distance_in_years + 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.time_ago_in_words(from_time, include_seconds = false, options = {})
|
|
distance_of_time_in_words(from_time, Time.now, include_seconds, options)
|
|
end
|
|
end
|
|
end
|