ActiveRecord возвращает «аргумент вне диапазона» для времени 26:12 - PullRequest
3 голосов
/ 23 ноября 2011

Похоже, что объект ActiveRecord и Ruby's Time не очень хорошо играют со временем, превышающим 24:00. Однако в моей базе данных их много, так как они представляют время после полуночи, но считаются в тот же день. Это проектное решение моего поставщика данных :

Примечание. Для поездок, охватывающих несколько дат, время остановок будет больше 24:00:00. Например, если поездка начинается в 10:30:00 вечера. и заканчивается в 2:15:00 утра следующего дня, время остановки будет 22:30:00 и 26:15:00 Ввод этих остановок, как 22:30:00 и 02:15:00 будет не дает желаемых результатов.

Как мне деактивировать эту «проверку» моих объектов Времени? предложил , чтобы я написал свое поле времени как varchar в запросе MySQL, но я ищу решение, которое не позволяет базе данных вмешиваться.

ОБНОВЛЕНИЕ: Относительно актуальности сохранения формата> 24:00, запроса и asc при заказе всех stop_times для остановки с использованием этого формата будет возвращаться что-то вроде: 23:45, 23:54, 24 : 35, 24:55, 25:15, то есть фактический порядок следования следующих автобусов.

Принимая во внимание, что другой путь вернется: 0:35, 0:55, 1:15, 23:45, 23:54 (это неправильно, первые 3 stop_times должны быть отсортированы после последние 3).

Ответы [ 2 ]

2 голосов
/ 23 ноября 2011

примечание в вашем вопросе говорит о TimeDifference, а не об объекте Time.

Я думаю, вам следует смоделировать TimeDifference как десятичное или плавающее поле в БД, со значением, равным разнице во времени в секундах ... и затем, когда вы распечатываете, вы можете переформатировать его как Дни , Часы, минуты.

Обратите внимание, что вот как вычитание объектов Time работает в Ruby:

> t1 = Time.now
 => 2011-11-22 20:54:54 -0800 
> t2 = Time.now.tomorrow
 => 2011-11-23 20:54:59 -0800 
> t2 - t1
 => 86404.928009862    # these are seconds!  just store this in a float or decimal field
> (t2 - t1).class
 => Float              # NOT a Time object

Попытка сохранить разницу во времени в объекте Time или поле DB времени кажется неправильной.

Если вы получаете странные входные значения из внешнего источника, такие как «26:12» , лучше преобразовать их в секунды:

hours,minutes = "26:12".split(/:/).map(&:to_i)
seconds = hours * 3600 + minutes * 60

... и затем сохранить разницу во времени в секундах


Ух ты, это из Google API ?? YIKES !!!

Тем не менее, не храните его в объекте Time.

вы можете использовать divmod () для очистки:

 tomorrow,real_hour = hour.divmod(24)

где «завтра» хранит количество дней в будущем, а «реальный час» является допустимым значением для 24-часовых часов.

Как насчет создания отдельного класса "TripTime" для тех времен запуска и остановки, которые имеют свои собственные атрибуты: часы, минуты, дни? Авиакомпании обычно показывают время прилета как «03:12 +1», что означает +1 день в будущем.

... или сохраните только эти странные значения в виде строки , которая сохраняет порядок сортировки, и для вычисления разницы в часах / минутах / секундах вы можете затем преобразовать их по мере необходимости, как показано выше с split и map

0 голосов
/ 19 декабря 2011

Хотя @Tilo и прав, что это, вероятно, не лучший формат времени, мне пришлось придерживаться их, и в итоге я использовал необработанный SQL для преобразования столбца времени в строку:

sql = "SELECT CONVERT(stop_time, CHAR) as stop_time from stop_times"
stop_times = ActiveRecord::Base.connection.select_all sql
time = stop_times[0]['stop_time'] # => returned as a string
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...