在Ruby on Rails中生成人类可读的时间范围可以通过内置的distance_of_time_in_words
方法和自定义逻辑实现。以下是完整解决方案:
Rails的ActionView::Helpers::DateHelper
模块提供了时间格式化工具,但需结合逻辑处理时间范围的展示。
distance_of_time_in_words
:include ActionView::Helpers::DateHelper
start_time = Time.now
end_time = 3.hours.from_now
puts distance_of_time_in_words(start_time, end_time)
# 输出:"about 3 hours"
def human_time_range(start_time, end_time)
if start_time.to_date == end_time.to_date
# 同一天显示: "Today from 10:00 to 12:00"
"Today from #{start_time.strftime('%H:%M')} to #{end_time.strftime('%H:%M')}"
elsif (end_time - start_time) <= 1.day
# 跨天但小于24小时: "Oct 1, 10:00 - Oct 2, 09:00"
"#{start_time.strftime('%b %-d, %H:%M')} - #{end_time.strftime('%b %-d, %H:%M')}"
else
# 长时间范围: "Oct 1 - Oct 3, 2023"
"#{start_time.strftime('%b %-d')} - #{end_time.strftime('%b %-d, %Y')}"
end
end
在config/locales/en.yml
中添加:
en:
time_range:
same_day: "%{date} from %{start_time} to %{end_time}"
multi_day: "%{start_date} - %{end_date}"
使用I18n的版本:
def localized_time_range(start_time, end_time)
if start_time.to_date == end_time.to_date
I18n.t('time_range.same_day',
date: start_time.to_date.to_s(:long),
start_time: start_time.strftime('%H:%M'),
end_time: end_time.strftime('%H:%M'))
else
I18n.t('time_range.multi_day',
start_date: start_time.to_date.to_s(:long),
end_date: end_time.to_date.to_s(:long))
end
end
安装dotiw
gem增强功能:
# Gemfile
gem 'dotiw'
# 使用示例
include ActionView::Helpers::DateHelper
include ActionView::Helpers::TextHelper
start = 1.day.ago
finish = Time.now
puts distance_of_time_in_words(start, finish, accumulate_on: :hours)
# 输出:"1 day and 6 hours"
# 确保使用应用配置的时区
Time.zone = 'Beijing'
Time.zone.now
Rails.cache.fetch("time_range_#{start_time}_#{end_time}") do
human_time_range(start_time, end_time)
end
以上方案可根据具体需求组合使用,推荐优先考虑I18n版本以实现多语言支持。
没有搜到相关的文章