You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以更具Rails风格的方式获取某一天的小时数?

Rails风格计算夏令日当天小时数的方法

嘿,这个问题问到点子上了!你当前的写法确实能算出结果,但不仅有浮点精度的小问题(比如得到24.99999999999972而不是精确的25.0),而且代码也不够直观简洁——完全可以用更符合Rails优雅风格的方式来实现。

第一步:先解决精度问题

首先,你可以通过整数时间戳计算来避免浮点误差,写法更严谨:

start = Time.zone.parse('31-10-2021').beginning_of_day
end_day = Time.zone.parse('31-10-2021').end_of_day
(end_day.to_i - start.to_i) / 3600.0 # => 25.0

用时间戳(整数)相减再转浮点数,就能得到精确的小时数,不会出现奇怪的近似值。

第二步:封装成Rails风格的便捷方法

Rails核心本身没有内置hours_in_day这类方法,但我们可以通过扩展核心类的方式,实现你期望的那种简洁调用,这完全符合Rails的“优雅封装”理念。

你可以在项目的config/initializers/date_extensions.rb文件中添加以下代码(初始化文件会在Rails启动时加载):

class Date
  # 传入时区参数,默认使用项目配置的Time.zone
  def hours_in_day(time_zone = Time.zone)
    start_time = time_zone.local(year, month, day)
    end_time = start_time.end_of_day
    (end_time.to_i - start_time.to_i) / 3600.0
  end
end

之后你就能像预想的那样,用非常直观的方式调用:

Date.parse('31-10-2021').hours_in_day # => 25.0
# 如果需要指定其他时区,也可以传参
Date.parse('31-10-2021').hours_in_day(ActiveSupport::TimeZone['New York'])

如果你更习惯从TimeWithZone对象调用,也可以扩展ActiveSupport::TimeWithZone:

class ActiveSupport::TimeWithZone
  def hours_in_day
    (end_of_day.to_i - beginning_of_day.to_i) / 3600.0
  end
end

调用方式:

Time.zone.parse('31-10-2021').hours_in_day # => 25.0

这种封装的好处在于:代码可读性极强,复用性高,完全贴合Rails追求的简洁、直观的编码风格。

内容的提问来源于stack exchange,提问作者mejiaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:33:10