Подтвердить что ты не робот

Почему Date.today - 6.months + 6.months!= Date.today?

В Ruby, на Хэллоуин:

Date.today - 6.months + 6.months != Date.today

Нужно ли обновлять реализацию Ruby date? У других языков есть одна и та же проблема?

4b9b3361

Ответ 1

Это происходит, если вы делаете это до любого месяца, у которого нет 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, чтобы убедиться, что вы последовательно получаете конец или начало месяца.

Ответ 2

Нет, это ожидается, и это тоже не уникально для Ruby - попробуйте, например, в SQL.

(Today - 6 months) - последний день (30-е) апреля - потому что нет 31-го. Это только те месяцы, с которыми мы имеем дело, а не точное количество дней.

Добавьте 6 месяцев до 30 апреля, и вы получите 30 октября.

Что, как вы знаете, = 31 октября.

Ответ 3

Это странная особенность расширений времени 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 и откопайте дальше оттуда.