40

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

我需要存储时间表。例如:周一至周五上午 8 点至上午 11 点

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

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

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

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

4

8 回答 8

23

我最近制作了一个必须解决这个问题的应用程序。我决定在一个简单的营业时间模型中存储 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)

任何使这更好的提示将不胜感激=)

于 2013-03-12T00:06:17.650 回答
12

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

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

也许 MySQL 有类似的东西

于 2013-11-26T23:05:53.407 回答
9

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

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

Lailson Bandeira 为这个问题创建了一个已创建的解决方案,即 Rails 3 的 Time_of_Day gem。不幸的是,该 gem 不再维护。请改用 Jack Christensen 的“tod”宝石。它就像一个魅力。

于 2014-09-10T04:21:04.030 回答
3

这颗红宝石将一天中的时间转换为自午夜以来的秒数。秒值存储在数据库中,可用于计算和验证。

定义时间属性:

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'
于 2014-01-05T11:24:51.753 回答
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 中不可用。

DateTime可以在此处找到有关纯 Ruby的文档。

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

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

如果存储为整数,即。

于 2012-08-15T17:18:23.197 回答
1

建议:

不要为此担心特定的数据类型。一个简单的解决方案是:

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

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

于 2016-02-04T06:10:59.853 回答
0

从 SQLite 3网站

“SQLite 没有专门用于存储日期和/或时间的存储类。相反,SQLite 的内置日期和时间函数能够将日期和时间存储为 TEXT、REAL 或 INTEGER 值:

TEXT 作为 ISO8601 字符串(“YYYY-MM-DD HH:MM:SS.SSS”)。REAL 作为儒略日数字,根据预测的公历,自公元前 4714 年 11 月 24 日格林威治中午以来的天数。INTEGER 作为 Unix 时间,自 1970-01-01 00:00:00 UTC 以来的秒数。应用程序可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。”

然后,您可以使用此处列出的日期和时间函数来操作这些值。

于 2012-08-15T17:05:39.543 回答
0

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

于 2012-08-15T16:49:26.820 回答