在Rails中,用英语显示两个日期之间的时间
在Rails项目中,我想找到两个日期之间的差异,然后用自然语言显示它。 就像是
>> (date1 - date2).to_natural_language "3 years, 2 months, 1 week, 6 days"
基本上这是ruby。
谷歌和Rails API没有发现任何东西。 我发现了一些可以让你在一个单元中产生差异的东西(即两个日期之间有多少个星期)但不能准确计算出几年,几个月,几周,几天的东西。
其他答案可能不会给出您正在寻找的输出类型,因为Rails助手不是给出一些年,月等字符串,而是显示最大的单位。 如果你正在寻找更多分解的东西,这是另一种选择。 将此方法粘贴到帮助器中:
def time_diff_in_natural_language(from_time, to_time) 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_in_seconds = ((to_time - from_time).abs).round components = [] %w(year month week day).each do |interval| # For each interval type, if the amount of time remaining is greater than # one unit, calculate how many units fit into the remaining time. if distance_in_seconds >= 1.send(interval) delta = (distance_in_seconds / 1.send(interval)).floor distance_in_seconds -= delta.send(interval) components << pluralize(delta, interval) end end components.join(", ") end
然后在一个视图中你可以说:
<%= time_diff_in_natural_language(Time.now, 2.5.years.ago) %> => 2 years, 6 months, 2 days
给定的方法仅限于几天,但如果需要,可以很容易地扩展为添加更小的单位。
Rails的ActionView
模块包括两种ActionView
您需求的方法:
-
distance_of_time_in_words
-
distance_of_time_in_words_to_now
我尝试了Daniel的解决方案 ,发现一些测试用例的结果不正确,因为它没有正确处理几个月内发现的可变天数:
> 30.days <1.month =>假
所以,例如:
> d1 = DateTime.civil(2011,4,4) > d2 = d1 + 1.year + 5.months > time_diff_in_natural_language(d1,d2) >“1年,5个月,3天”
以下内容将为您提供{年,月,日,小时,分钟,秒}的正确数量:
def time_diff(from_time,to_time) %w(年月日小时分秒).map do | interval | distance_in_seconds =(to_time.to_i - from_time.to_i).round(1) delta =(distance_in_seconds / 1.send(interval))。floor delta - = 1如果from_time + delta.send(interval)> to_time from_time + = delta.send(interval) 三角洲 结束 结束 > time_diff(d1,d2) => [1,5,0,0,0,0]
distance_of_time_in_words
在这里是最准确的。 丹尼尔的答案是错误的:2。5年前,应该产生2年零6个月。 问题是,月份包含28-31天,而年份可能会飞跃。
我希望我知道如何解决这个问题:(
DateHelper#distance_of_time_in_words
def date_diff_in_natural_language(date_from, date_to) components = [] %w(years months days).each do |interval_name| interval = 1.send(interval_name) count_intervals = 0 while date_from + interval <= date_to date_from += interval count_intervals += 1 end components << pluralize(count_intervals, interval_name) if count_intervals > 0 end components.join(', ') end