В Ruby, на Хэллоуин:
Date.today - 6.months + 6.months != Date.today
Нужно ли обновлять реализацию Ruby date? У других языков есть одна и та же проблема?
В Ruby, на Хэллоуин:
Date.today - 6.months + 6.months != Date.today
Нужно ли обновлять реализацию Ruby date? У других языков есть одна и та же проблема?
Это происходит, если вы делаете это до любого месяца, у которого нет 31 дня (т.е. 3 месяца будут работать нормально, но 1 месяц или 6 или 8 все это произойдет).
Если вы выполняете Date.today - 1.month
, похоже, что Rails видит, что 9/31/2011 не является допустимой датой, поэтому он возвращает дополнительный день, чтобы сделать его действительной датой. Однако, когда вы идете на один месяц вперед с конца сентября, он оставит его в 30/30/2011, так как это действительная дата. В основном, Rails просто пытается увеличить (или уменьшить) поле месяца и до тех пор, пока это действительная дата, он не будет корректировать поле дня.
Один из способов обойти это - использовать метод .end_of_month
(или .beginning_of_month
) для объекта Date
в Rails, чтобы убедиться, что вы последовательно получаете конец или начало месяца.
Нет, это ожидается, и это тоже не уникально для Ruby - попробуйте, например, в SQL.
(Today - 6 months)
- последний день (30-е) апреля - потому что нет 31-го. Это только те месяцы, с которыми мы имеем дело, а не точное количество дней.
Добавьте 6 месяцев до 30 апреля, и вы получите 30 октября.
Что, как вы знаете, = 31 октября.
Это странная особенность расширений времени ActiveSupport.
> 6.months == 180.days
=> true
но когда вы делаете математику с месяцами, они считаются календарными месяцами, а не 30-дневными периодами. Проверьте это:
> Date.today - 180.days + 180.days
=> Mon, 31 Oct 2011
Смотрите https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/calculations.rb#L277 и откопайте дальше оттуда.