Rails. Как хранить время суток (по расписанию)?
Я пишу приложение, которое отслеживает школьные классы.
Мне нужно сохранить расписание. Например: с понедельника по пятницу с 8: am-11am.
Я думал об использовании простого столбца строки, но мне нужно будет сделать вычисления времени позже.
Например, мне нужно сохранить представление 8am, например start_at: 8am end_at: 11am
Итак как мне хранить время? Какой тип данных следует использовать? Должен ли я хранить время начала и количество секунд или минут, а затем рассчитывать оттуда? или есть более простой способ?
Я использую MySQL для производства и SQLite для разработки.
Ответы
Ответ 1
Недавно я сделал приложение, которое должно было решить эту проблему. Я решил хранить 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)
Любые советы для этого лучше будут оценены =)
Ответ 2
Если вы используете Postgresql, вы можете использовать тип столбца time
, который представляет собой только время суток и дату. Затем вы можете запросить
Event.where("start_time > '10:00:00' and end_time < '12:00:00'")
Возможно, MySQL имеет нечто похожее
Ответ 3
Отметьте драгоценный камень 'tod' для Rails 4 или Time_of_Day для Rails 3. Они оба решают проблему сохранения времени в базе данных при использовании Active Record модель.
SQL имеет тип данных времени, но Ruby этого не делает. Active Record решает эту разницу, представляя атрибуты времени с использованием класса Rubys Time на канонической дате 2000-01-01. Все атрибуты времени произвольно назначаются одинаковыми датами. Хотя атрибуты можно сравнивать друг с другом без проблем (даты совпадают), возникают ошибки при попытке сравнить их с другими экземплярами Time. Просто используя Time.parse на строке, такой как "10:05", добавляет дату до выхода.
Lailson Bandeira создала созданное решение этой проблемы - драгоценный камень Time_of_Day для Rails 3. К сожалению, этот драгоценный камень больше не поддерживается. Вместо этого используйте драгоценный камень Джека Кристенсена. Он работает как шарм.
Ответ 4
Я бы сохранил начальный час и продолжительность в базе данных, используя два целых столбца.
Извлекая оба значения, вы можете преобразовать начальный час как в (при условии, что вы уже знаете этот день:
# 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
является частью рельсов и недоступен в обычном 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
если он хранится как целое число.
Ответ 5
Этот рубиновый жемчуг преобразует время дня в секундах с полуночи и обратно. Значение секунд сохраняется в базе данных и может использоваться для расчетов и валидации.
Определите атрибуты времени суток:
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'
Ответ 6
Предложение:
Не беспокойтесь о конкретном типе данных для этого. Простое решение:
-
В базе данных добавьте столбец типа integer для start_time, а другой для end_time. Каждый будет хранить количество минут с полуночи.
Пример: 8:30 утра будет храниться как 510 (8 * 60 + 30)
-
В форме создайте поле выбора (раскрывающееся меню), которое отображает все доступные времена в формате времени:
Пример: 10 утра, 10:30 и т.д.
Но фактические значения полей, которые сохраняются в базе данных, являются их целыми эквивалентами:
Пример: 600, 630 и т.д. (В соответствии с приведенным выше примером)
Ответ 7
Я предполагаю, что для этого вы используете какую-то базу данных. Если вы используете MySQL или Postgresql, вы можете использовать тип столбца datetime
, который Ruby/Rails автоматически преобразует в/из объекта Time
при чтении/записи в базу данных. Я не уверен, что у sqlite есть что-то подобное, но я думаю, что это возможно.
Ответ 8
На веб-сайте SQLite 3
"SQLite не имеет класса хранения, зарезервированного для хранения дат и/или времени. Вместо этого встроенные функции даты и времени SQLite способны хранить даты и время как значения TEXT, REAL или INTEGER:
ТЕКСТ как строки ISO8601 ( "ГГГГ-ММ-ДД ЧЧ: ММ: SS.SSS" ).
REAL, как число юлианских дней, количество дней с полудня в Гринвиче 24 ноября 4714 г. B.C. согласно пролептическому григорианскому календарю.
INTEGER as Unix Time, количество секунд с 1970-01-01 00:00:00 UTC.
Приложения могут выбирать даты и время в любом из этих форматов и свободно конвертировать между форматами, используя встроенные функции даты и времени ".
Затем вы можете манипулировать значениями с помощью функций даты и времени, обозначенных здесь.