轨。如何存储时间(按计划)?

时间:2012-08-15 16:30:32

标签: ruby-on-rails ruby

我正在编写一个跟踪学校课程的应用程序。

我需要存储时间表。例如:周一至周五 8:am-11am

我正在考虑使用一个简单的字符串列,但我需要稍后进行时间计算。

例如,我需要存储8am的表示,例如start_at:8am end_at:11am

所以我应该如何存储时间?我应该使用什么数据类型?我应该存储开始时间和秒数或分钟数,然后从那里计算?或者有更简单的方法吗?

我使用MySQL进行生产,使用SQLite进行开发。

8 个答案:

答案 0 :(得分:19)

我最近制作了一个应用程序,必须解决这个问题。我决定在一个简单的营业时间模型中从午夜开始存储open_at和closed_at。 ActiveSupport包含这个方便的帮助程序,用于查找自午夜以来的秒数时间:

Time.now.seconds_since_midnight

通过这种方式,我可以进行简单的查询,以确定场地是否开放:

BusinessHour.where("open_at > ? and close_at < ?", Time.now.seconds_since_midnight, Time.now.seconds_since_midnight)

任何提高效果的提示都将受到赞赏=)

答案 1 :(得分:11)

如果你正在使用Postgresql,你可以使用time列类型,它只是一天中的时间而没有日期。然后,您可以查询

Event.where("start_time > '10:00:00' and end_time < '12:00:00'")

也许MySQL有类似的东西

答案 2 :(得分:9)

查看Rails 4的gem 'tod'或Rails 3的Time_of_Day。它们都解决了在使用Active Record模型时在数据库中存储时间的问题。

SQL有时间数据类型但Ruby没有。 Active Record通过在规范日期2000-01-01上使用Ruby的Time类表示时间属性来解决这种差异。所有时间属性都被任意分配相同的日期。虽然属性可以相互比较而没有问题(日期相同),但当您尝试将它们与其他Time实例进行比较时会出现错误。只需在类似“10:05”的字符串上使用Time.parse即可将今天的日期添加到输出中。

Lailson Bandeira为这个问题创建了一个创建的解决方案,Rails 3的Time_of_Day gem。不幸的是,不再维护gem。使用Jack Christensen的'tod'宝石代替。它就像一个魅力。

答案 3 :(得分:3)

This ruby gem将时间从午夜转换为秒。秒值存储在数据库中,可用于计算和验证。

定义时间属性:

class BusinessHour < ActiveRecord::Base
  time_of_day_attr :opening, :closing
end

将时间转换为自设置字符串的午夜以来的秒数:

business_hour = BusinessHour.new(opening: '9:00', closing: '17:00')
business_hour.opening
 => 32400
business_hour.closing
 => 61200

要转换回时间:

TimeOfDayAttr.l(business_hour.opening)
 => '9:00'
TimeOfDayAttr.l(business_hour.closing)
 => '17:00'

您还可以在整个小时内省略分钟数:

TimeOfDayAttr.l(business_hour.opening, omit_minutes_at_full_hour: true)
 => '9'

答案 4 :(得分:2)

我会使用两个整数列来存储数据库中的起始小时和持续时间。

通过检索这两个值,您可以将起始时间转换为(假设您已知道当天:

# assuming date is the date of the day, datetime will hold the start time
datetime = date.change({:hour => your_stored_hour_value , :min => 0 , :sec => 0 })

# calculating the end time
end_time = datetime + your_stored_duration.seconds

否则,请看Chronic。宝石使处理时间更容易一些。请注意,change方法是rails的一部分,在纯Ruby中不可用。

可以找到关于普通Ruby的DateTime的文档here

此外,无论您做什么,都不要以12小时格式开始存储日期/时间,您可以在Rails中使用I18n来转换时间:

I18n.l Time.now, :format => "%I.%m %p",  :locale => :"en"
I18n.l Time.now + 12.hours, :format => "%I.%m %p",  :locale => :"en"

您也可以从这种表示法中获得,您可以按小时存储持续时间,如果需要,您可以通过以下方式轻松转换它们:

your_stored_value.hours

如果存储为整数,即。

答案 5 :(得分:1)

建议:

不要担心具体的数据类型。一个简单的解决方案是:

  1. 在数据库中,为 start_time 添加整数类型列,为 end_time 添加另一个整数类型列。每个都将存储自午夜起的分钟数 例如:上午8:30将存储为510(8 * 60 + 30)

  2. 在表单中,创建一个选择字段(下拉列表),以时间格式显示所有可用时间:
    例如:上午10点,上午10点半等。<登记/> 但是保存在数据库中的实际字段值是它们的等价整数:
    例如:600,630等(按照上面的例子)

答案 6 :(得分:0)

我假设您正在使用某种数据库。如果您使用的是MySQL或Postgresql,则可以使用datetime列类型,当读/写数据库时,Ruby / Rails将自动转换为Time对象。我不确定sqlite是否有类似的东西,但我想它可能会有。

答案 7 :(得分:0)

来自SQLite 3 website

“SQLite没有用于存储日期和/或时间的存储类。而是,SQLite的内置日期和时间函数能够将日期和时间存储为TEXT,REAL或INTEGER值:< / p>

TEXT as ISO8601 strings(“YYYY-MM-DD HH:MM:SS.SSS”)。 真实的朱利安日数,是公元前4714年11月24日格林威治中午以来的天数。根据公历格里高利历。 INTEGER as Unix Time,自1970-01-01 00:00:00 UTC以来的秒数。 应用程序可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。“

然后,您可以使用here概述的日期和时间功能来操纵值。