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

В Ruby, 12.months!= 1.год

Помощники даты/времени Ruby полезны, но я нашел несоответствие. Кажется, что 12.months не равно 1.Year. Проверьте 1.month, и вы найдете его равным 30.days и, конечно, 12 * 30.days = 360.дней, 5,25 дней меньше фактической длины года.

Мне это показалось, когда я установил доступ к определенным компонентам нашего веб-сайта в зависимости от количества предоставленных месяцев, как указано клиентом. Я обнаружил, что срок действия 36.месяца истекает на пару недель раньше, когда я запускаю свои тесты. Решение было примерно таким:

def months_to_seconds(number_of_months)
  ( (number_of_months.to_f / 12) * 1.year).to_i.seconds
end

Это возвращает количество секунд в любой части года, представленной number_of_months.

Так как 1.год равен в секундах до 365,25 дней, почему вы думаете, что у них не было 1.month, чтобы вернуть секунды на 1/12 года вместо 30 дней?

Кто-нибудь сталкивался с этим раньше? У кого-нибудь есть лучшее решение?

4b9b3361

Ответ 1

Календарь и время вообще являются такой произвольной вещью и пронизаны такими несоответствиями. Стандартной длины "месяца" нет, так как разница составляет от 28 до 31 дня, так же как стандартная длина "дня", которая может составлять от 23 до 25 часов, и даже минута может иметь место от От 59 до 62 секунд, когда учитываются "прыжки секунд". Точно так же год может составлять 365 или 366 дней или даже 351, как в случае с 1582 годом.

Если вы не выполняете вычисления, относящиеся к определенному интервалу, например, количество секунд между 3 января 2010 года и 19 октября 2011 года, вы не сможете узнать, как долго этот интервал использует абстрактные месяцы, дни или года. Эти вещи зависят от огромного количества факторов.

Ваше решение подходит для вашего приложения, но в терминах Rails "месяц" составляет просто 30 дней для простоты, так же как "день" составляет 24 часа.

Ответ 2

Да и нет:

12 months совпадают с 1 year, когда вы используете их как относительные интервалы, потому что они не преобразуются в секунды, а затем:

t = Time.now
#=> 2010-11-12 22:34:57 0100
t - 1.year == t - 12.months
#=> true

Внутри эти интервалы хранятся в виде массивов с количеством лет, месяцев и дней, поэтому, если вы скажете, например:

1.year - 12.months
#=> 1 year and -12 months

это означает, что вычитание приводит к интервалу, состоящему из "одного года и минус 12 месяцев".

Но если вы to_i их, они должны быть преобразованы в точное количество секунд, и кто-то решил, что "месяц" означает "30 дней", что является хорошим приближением, как и любое другое, в то время как вы придерживаетесь его.

Это указано в документах:

Хотя эти методы обеспечивают точное расчет при использовании в примеры выше, следует соблюдать осторожность отметить, что это неверно, если результат "месяцев", "лет" и т.д. преобразован перед использованием

Я думаю, что эти интервалы можно рассматривать как "ленивые оценки" в некотором роде.

Ответ 3

1 год состоит из 12 отдельных месяцев, но несколько из этих месяцев имеют разные размеры. Учитывая, что в течение месяца может быть 28, 29, 30 или 31 календарных дней, разумно ожидать, что любое заданное определение длины месяца может быть не таким, каким хочет.

Лично я использую 4 недели как определение месяца в большинстве случаев. В этом случае, когда вы предоставляете доступ к "месяцу", я был бы склонен хранить день доступа к месяцу. Затем возьмите номер месяца и поместите его в тот же день месяца N месяцев.

Ответ 4

require 'date'

expire_date = Date.today >> 36
puts expire_date #=> 2013-11-12

Если вы хотите вычесть месяцы, используйте < <.