Rails。如何存储一天的时间(为计划)?

时间:2022-10-21 10:52:46

I'm writing an app that keeps track of school classes.

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

I need to store the schedule. For example: Monday-Friday from 8:am-11am.

我需要保存时间表。例如:星期一到星期五上午8点到11点。

I was thinking about using a simple string column but I'm going to need to make time calculations later.

我在考虑使用一个简单的字符串列,但是我以后需要做时间计算。

For example, I need to store a representation of 8am, such as start_at:8am end_at:11am

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

So how should I store the time? What datatype should I use? Should I store start time and number of seconds or minutes and then calculate from there? or is there an easier way?

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

I use MySQL for production and SQLite for development.

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

8 个解决方案

#1


19  

I made an app recently that had to tackle this problem. I decided to store open_at and closed_at in seconds from midnight in a simple business hour model. ActiveSupport includes this handy helper for finding out the time in seconds since midnight:

我最近做了一个应用来解决这个问题。我决定用一个简单的业务时模型从午夜开始几秒内存储open_at和closed_at。ActiveSupport包括了这个方便的助手,可以从午夜开始以秒为单位计算时间:

Time.now.seconds_since_midnight

This way I can do a simple query to find out if a venue is open:

通过这种方式,我可以做一个简单的查询,以确定一个地点是否开放:

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

Any tips for making this better would be appreciated =)

如果您有更好的建议,我们将不胜感激。

#2


10  

If you're using Postgresql you can use a time column type which is just the time of day and no date. You can then query

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

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

Maybe MySQL has something similar

也许MySQL也有类似的功能

#3


8  

Check out the gem 'tod' for Rails 4 or Time_of_Day for Rails 3. They both solve the problem of storing time in a database while using an an Active Record model.

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

SQL has a time data type but Ruby does not. Active Record addresses this difference by representing time attributes using Ruby’s Time class on the canonical date 2000-01-01. All Time attributes are arbitrarily assigned the same dates. While the attributes can be compared with one another without an issue, (the dates are the same), errors arise when you attempt to compare them with other Time instances. Simply using Time.parse on a string like ”10:05” adds today’s date to the output.

SQL有时间数据类型,而Ruby没有。活动记录通过使用Ruby的时间类在标准日期2000-01-01表示时间属性来解决这一差异。所有时间属性都被任意分配相同的日期。虽然属性可以相互比较,但没有问题(日期是相同的),但是当您试图将它们与其他时间实例进行比较时,会出现错误。简单的使用时间。像“10:05”这样的字符串的解析将今天的日期添加到输出。

Lailson Bandeira created a created solution for this problem, the Time_of_Day gem for Rails 3. Unfortunately the gem is no longer maintained. Use Jack Christensen’s ‘tod’ gem instead. It works like a charm.

Lailson Bandeira为这个问题创建了一个解决方案,即Rails 3的Time_of_Day gem。不幸的是,宝石不再被维护。用杰克·克里斯滕森的“tod”宝石来代替。它就像一种魅力。

#4


2  

I would store the starting hour and the duration within the database, using two integer columns.

我将使用两个整数列在数据库中存储开始时间和持续时间。

By retrieving both values, you could convert the starting hour as in (assuming that you know the day already:

通过检索这两个值,您可以将开始时间转换为in(假设您已经知道日期:

# 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

Otherwise, hava a look at Chronic. The gem makes handling time a little bit easier. Note that the changemethod is part of rails, and not available in plain Ruby.

否则,我就看《慢性疲劳综合症》。宝石使处理时间稍微容易一些。注意,changemethod是rails的一部分,在普通Ruby中不可用。

The documentation on DateTime for plain Ruby can be found here.

可以在这里找到纯Ruby的DateTime文档。

Also, whatever you do, don't start storing your dates/time in 12-hour format, you can use I18nin Rails to convert the time:

另外,无论你做什么,不要开始以12小时的格式存储你的日期/时间,你可以使用I18nin Rails来转换时间:

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

You can also get from this notation, that you can store you duration in hours, if you want, you can then convert them rather easily by:

你也可以从这个表示法中得到,你可以将你的持续时间以小时为单位,如果你愿意,你可以很容易地通过:

your_stored_value.hours

if stored as an integer, that is.

如果存储为整数,则为。

#5


2  

This ruby gem converts time of day to seconds since midnight and back. The seconds value is stored in the database and can be used for calculations and validations.

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

Define the time of day attributes:

定义一天的时间属性:

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

Converts time of day to seconds since midnight when a string was set:

将一天中的时间转换为自设置字符串后的秒:

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

To convert back to time of day:

转换回到一天的时间:

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

You could also omit minutes at full hour:

你也可以在整点的时候省略几分钟:

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

#6


1  

Suggestion:

Don’t worry about a specific datatype for that. A simple solution would be:

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

  1. In the database, add an integer type column for start_time and another for end_time. Each will store the number of minutes since midnight.
    Ex: 8:30am would be stored as 510 (8*60+30)

    在数据库中,为start_time添加一个整数类型列,为end_time添加另一个整数类型列。每个人都将存储从午夜开始的分钟数。例:8:30am存储为510 (8*60+30)

  2. In the form, create a select field (dropdown) that displays all available times in time format:
    Ex.: 10am, 10:30am and so on.
    But the actual field values that get saved in the database are their integer equivalents:
    Ex: 600, 630 and so on (following the example above)

    在表单中,创建一个select字段(下拉),该字段以时间格式显示所有可用的时间:例如:上午10点、上午10点30分等等。但是,在数据库中保存的实际字段值是它们的整型值:Ex: 600,630等等(在上面的例子中)

#7


0  

I assume you are using some kind of database for this. If you are using MySQL or Postgresql, you can use the datetime column type, which Ruby/Rails will automatically convert to/from a Time object when reading/writing to the database. I'm not sure if sqlite has something similar, but I imagine it probably does.

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

#8


0  

From the SQLite 3 website,

从SQLite 3网站,

"SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

SQLite没有为存储日期和/或时间预留的存储类。SQLite的内置日期和时间函数可以将日期和时间存储为文本、实值或整数值:

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar. INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC. Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions."

文本为ISO8601字符串(“YYYY-MM-DD:MM:SS.SSS”)。真实的儒略历是儒略历的儒略历,从公元前4714年11月24日的中午算起。整数为Unix时间,从1970-01 00:00 UTC开始的秒数。应用程序可以选择在任何这些格式中存储日期和时间,并且可以使用内置的日期和时间函数*地转换格式。

You can then manipulate the values using the Date and Time functions outlined here.

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

#1


19  

I made an app recently that had to tackle this problem. I decided to store open_at and closed_at in seconds from midnight in a simple business hour model. ActiveSupport includes this handy helper for finding out the time in seconds since midnight:

我最近做了一个应用来解决这个问题。我决定用一个简单的业务时模型从午夜开始几秒内存储open_at和closed_at。ActiveSupport包括了这个方便的助手,可以从午夜开始以秒为单位计算时间:

Time.now.seconds_since_midnight

This way I can do a simple query to find out if a venue is open:

通过这种方式,我可以做一个简单的查询,以确定一个地点是否开放:

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

Any tips for making this better would be appreciated =)

如果您有更好的建议,我们将不胜感激。

#2


10  

If you're using Postgresql you can use a time column type which is just the time of day and no date. You can then query

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

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

Maybe MySQL has something similar

也许MySQL也有类似的功能

#3


8  

Check out the gem 'tod' for Rails 4 or Time_of_Day for Rails 3. They both solve the problem of storing time in a database while using an an Active Record model.

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

SQL has a time data type but Ruby does not. Active Record addresses this difference by representing time attributes using Ruby’s Time class on the canonical date 2000-01-01. All Time attributes are arbitrarily assigned the same dates. While the attributes can be compared with one another without an issue, (the dates are the same), errors arise when you attempt to compare them with other Time instances. Simply using Time.parse on a string like ”10:05” adds today’s date to the output.

SQL有时间数据类型,而Ruby没有。活动记录通过使用Ruby的时间类在标准日期2000-01-01表示时间属性来解决这一差异。所有时间属性都被任意分配相同的日期。虽然属性可以相互比较,但没有问题(日期是相同的),但是当您试图将它们与其他时间实例进行比较时,会出现错误。简单的使用时间。像“10:05”这样的字符串的解析将今天的日期添加到输出。

Lailson Bandeira created a created solution for this problem, the Time_of_Day gem for Rails 3. Unfortunately the gem is no longer maintained. Use Jack Christensen’s ‘tod’ gem instead. It works like a charm.

Lailson Bandeira为这个问题创建了一个解决方案,即Rails 3的Time_of_Day gem。不幸的是,宝石不再被维护。用杰克·克里斯滕森的“tod”宝石来代替。它就像一种魅力。

#4


2  

I would store the starting hour and the duration within the database, using two integer columns.

我将使用两个整数列在数据库中存储开始时间和持续时间。

By retrieving both values, you could convert the starting hour as in (assuming that you know the day already:

通过检索这两个值,您可以将开始时间转换为in(假设您已经知道日期:

# 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

Otherwise, hava a look at Chronic. The gem makes handling time a little bit easier. Note that the changemethod is part of rails, and not available in plain Ruby.

否则,我就看《慢性疲劳综合症》。宝石使处理时间稍微容易一些。注意,changemethod是rails的一部分,在普通Ruby中不可用。

The documentation on DateTime for plain Ruby can be found here.

可以在这里找到纯Ruby的DateTime文档。

Also, whatever you do, don't start storing your dates/time in 12-hour format, you can use I18nin Rails to convert the time:

另外,无论你做什么,不要开始以12小时的格式存储你的日期/时间,你可以使用I18nin Rails来转换时间:

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

You can also get from this notation, that you can store you duration in hours, if you want, you can then convert them rather easily by:

你也可以从这个表示法中得到,你可以将你的持续时间以小时为单位,如果你愿意,你可以很容易地通过:

your_stored_value.hours

if stored as an integer, that is.

如果存储为整数,则为。

#5


2  

This ruby gem converts time of day to seconds since midnight and back. The seconds value is stored in the database and can be used for calculations and validations.

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

Define the time of day attributes:

定义一天的时间属性:

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

Converts time of day to seconds since midnight when a string was set:

将一天中的时间转换为自设置字符串后的秒:

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

To convert back to time of day:

转换回到一天的时间:

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

You could also omit minutes at full hour:

你也可以在整点的时候省略几分钟:

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

#6


1  

Suggestion:

Don’t worry about a specific datatype for that. A simple solution would be:

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

  1. In the database, add an integer type column for start_time and another for end_time. Each will store the number of minutes since midnight.
    Ex: 8:30am would be stored as 510 (8*60+30)

    在数据库中,为start_time添加一个整数类型列,为end_time添加另一个整数类型列。每个人都将存储从午夜开始的分钟数。例:8:30am存储为510 (8*60+30)

  2. In the form, create a select field (dropdown) that displays all available times in time format:
    Ex.: 10am, 10:30am and so on.
    But the actual field values that get saved in the database are their integer equivalents:
    Ex: 600, 630 and so on (following the example above)

    在表单中,创建一个select字段(下拉),该字段以时间格式显示所有可用的时间:例如:上午10点、上午10点30分等等。但是,在数据库中保存的实际字段值是它们的整型值:Ex: 600,630等等(在上面的例子中)

#7


0  

I assume you are using some kind of database for this. If you are using MySQL or Postgresql, you can use the datetime column type, which Ruby/Rails will automatically convert to/from a Time object when reading/writing to the database. I'm not sure if sqlite has something similar, but I imagine it probably does.

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

#8


0  

From the SQLite 3 website,

从SQLite 3网站,

"SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

SQLite没有为存储日期和/或时间预留的存储类。SQLite的内置日期和时间函数可以将日期和时间存储为文本、实值或整数值:

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar. INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC. Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions."

文本为ISO8601字符串(“YYYY-MM-DD:MM:SS.SSS”)。真实的儒略历是儒略历的儒略历,从公元前4714年11月24日的中午算起。整数为Unix时间,从1970-01 00:00 UTC开始的秒数。应用程序可以选择在任何这些格式中存储日期和时间,并且可以使用内置的日期和时间函数*地转换格式。

You can then manipulate the values using the Date and Time functions outlined here.

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