Почему Date.today - 6.months + 6.months! = Date.today? - PullRequest
31 голосов
/ 31 октября 2011

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

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

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

Ответы [ 3 ]

38 голосов
/ 31 октября 2011

Это происходит, если вы делаете это для любого месяца, у которого нет 31 дня (то есть 3 месяца будут работать нормально, но 1 месяц, или 6, или 8 все это сделает).

Если вы сделаете Date.today - 1.month, похоже, что Rails увидит, что 31.09.2011 не является действительной датой, поэтому он отбрасывает ее на дополнительный день, чтобы сделать ее действительной.Тем не менее, когда вы продвинетесь на месяц вперед с конца сентября, он останется на 30.10.2011, поскольку это действительная дата.По сути, Rails просто пытается увеличить (или уменьшить) поле месяца, и пока оно является действительной датой, оно не будет корректировать поле дня.

Один из способов обойти это - использовать .end_of_month (или .beginning_of_month) метод для Date объекта в Rails, чтобы убедиться, что вы последовательно получаете конец или начало месяца.

11 голосов
/ 31 октября 2011

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

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

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

Что, как вы знаете, = октябрьтридцать первый.

6 голосов
/ 31 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...