Месяц в среднем 30 дней

Как известно, в году 12 месяцев с определенным количеством дней. Обычно, это число варьируется: то 30, то 31 и только один месяц числом дней меньше: 28 - 29. Значит, представим два способа, в которых выразим, сколько месяцев имеют по 30 дней.

С точки зрения календарной структуры месяцев

Прибегнем к плану вычисления необходимых нам дней:

  • укажем сколько дней в году.
  • укажем количество дней первого месяца.
  • укажем, когда прекращается чередование количества дней 30 и 31.
  • вынесем итог.

Первый месяц у нас Январь. Январь всегда длится 31 день. Поэтому дальше пойдет чередование. Но чередование на половине гола прерывается. Чтобы узнать, когда 2 раза подряд 31 день, нужно сопоставить два кулачка рук вместе. Косточка - 31 день, ямочка - 30 дней.

Январь - 31. Февраль - 28 (29). Март - 31. Апрель - 30. Май - 31. Июнь - 30. Июль - 31. Август - 31. Сентябрь - 30. Октябрь - 31. Ноябрь - 30. Декабрь - 31. Как видим, на одной руке оканчивается косточкой Июль, и на другой руке начинаем с косточки - Август.

Подводим итог: в году с число по 30 дней всего 4 месяца.

С точки зрения смекалки

Если рассуждать логически, то, практически, в каждом месяце есть по 30 дней, не считая Февраль, поскольку количество его дней не превышает число 29. В остальных по 30 дней есть, просто, иногда это число становится на 1 день больше, поэтому мы приняли не считать, что в них не по 30 дней. Поэтому подводя итог, то в году все месяцы длятся по 30 дней, за исключением месяца Февраль, поскольку количество дней не превышают отметку 29. Поэтому всего месяцев 11.

На вопрос Почему в месяцах разное количество дней? заданный автором Пользователь удален лучший ответ это В древние времена, когда календари только вводились, год, измеряемый по циклу смены сезонов (времен года), разделялся на месяцы. Продолжительность месяцев в разных культурах несколько различалась, но во всех культурах она попадала в базовую продолжительность от 28 до 31 дня. Количество дней в месяце основывалось на цикле Луны, который продолжается примерно 29 с половиной дней, что легко заметить, просто наблюдая за освещенным Луной небом. Но все месяцы не могли иметь одинаковое чис ло дней, так как количество дней в году, примерно 365, не делится ни на одно из чисел 28, 29, 30 или 31.
Во времена римского императора Юлия Цезаря, который в 45 г. до н. э. ввел юлианский календарь, было решено, что все месяцы будут иметь продолжительность 30 или 31 день, за исключением февраля, продолжительность которого в то время составляла 29 дней. Почему число дней в феврале уменьшили? До введения юлианского календаря новый год начинался в марте, и поскольку февраль оказывался последним месяцем в году, такой выбор самого короткого месяца казался логичным.
Одна из версий в истории календарей связана с тем, как февраль стал месяцем с 28 днями. Вот она. После смерти Юлия Цезаря месяц, который в те времена назывался «квин-тилис», переименовали в июль в честь Юлия Цезаря. Во время правления следующего императора, Августа Цезаря, месяц, который в то время назывался «секстилис», был переименован в честь нового императора в август. В июле был 31 день, а в августе всего 30, и для того, чтобы его месяц был таким же длинным (и таким же важным), как и месяц Юлия, император Август взял день от февраля и добавил к августу. С тех пор в августе 31 день, а в феврале 28 (за исключением високосного года, когда в феврале, как и раньше, 29 дней).

Ответ от 22 ответа [гуру]

Привет! Вот подборка тем с ответами на Ваш вопрос: Почему в месяцах разное количество дней?

Ответ от Европейский [гуру]
так задумано.. а не все ли равно?


Ответ от чистосортный [гуру]
Потому что людям у которых есть власть - нечем занятся.
И чтобы увековечить своё имя во веки вечные они дёргают дни в календаре, чтобы спустя 1000 лет нормальные люди задали этот вопрос и в ответ услышали имя правителя.
Судя по всему Юлий Цезарь был очень влиятельным политиком.
Теперь спросите почему у нас так много праздников.


Ответ от Пользователь удален [гуру]
Да?


Ответ от Просиять [гуру]
потому что в году 365 дней и 12 месяцев. На цело не делится. Остаётся 5 ещё суток - вот их и разнесли по месяцем


Ответ от Пользователь удален [новичек]
Чтобы был веселее. Ну, или чисто математически... Потому что в году 365 дней, наверно, не получилось, чтобы во всех месяцах было поровну. Пойду сейчас посчитаю... Где мой калькулятор???.


Ответ от Пользователь удален [гуру]
Да уж.
Могли сделать 5 месяцев по 73 дня в обычном и 6 по 61 в високосном году.
Было бы веселее.


Ответ от Наталья [активный]
чтобы скучно не было.

(Часть I ), а также авторским к нему дополнением (Часть II ). Не следует относиться к материалу серьёзно, а скорее как к разминке для ума, требующей не более чем школьных знаний арифметики и не имеющей практического применения. Всем приятного чтения!

Часть I

Вступление

Недавно, после очередной бессонной ночи, я размышлял о методах запоминания количества дней в каждом месяце года. Для этого есть считалочка, а также способ считать на костяшках пальцев, но ни то, ни другое меня не устроило. Я задумался, а не существует ли какой-нибудь математической формулы для решения такой задачи, и - не обнаружив при беглом изучении таковую - бросил себе вызов её создать.

Формализуя Другими словами, необходимо найти функцию f , такую, что значение f(x) для каждого месяца x , представленного числом от 1 до 12, равняется количеству дней в этом месяце. Таблица значений аргумента и функции :

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 28 31 30 31 30 31 31 30 31 30 31

Если у вас возникло желание попробовать самому до прочтения моего решения, то сейчас самое время. Если же вы предпочитаете немедленно увидеть готовый ответ, то посмотрите под спойлер.

Ответ


Ниже следуют мои шаги по нахождению решения.

Математический аппарат

Сначала бегло освежим в памяти два жизненно необходимых в решении этой задачи оператора: целочисленное деление и остаток от деления.

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

Остаток от деления это оператор, находящий остаток от деления. Во многих языках программирования применяется символ % , я же буду использовать конструкции вида , например:

Замечу, что остаток от деления имеет равный с делением приоритет.

Основы

Итак, применим наш математический аппарат для получения базовой формулы. В обычном месяце 30 или 31 день, так что мы можем использовать для получения поочерёдно 1 или 0, а затем просто прибавить к этому числу константу:

Получаем таблицу, полужирным выделены корректные значения:
x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 30 31 30 31 30 31 30 31 30 31 30

Неплохое начало! Уже есть правильные значения для января и для месяцев с марта по июль включительно. Февраль - особый случай, и с ним мы разберёмся чуть позже. После июля для оставшихся месяцев порядок получения 0 и 1 должен быть изменён на обратный.
Для этого мы может прибавить к делимому 1:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 30 31 30 31 30 31 30 31 30 31 30 31

Теперь правильные значения с августа по декабрь, но, как и предполагалось, значения для прочих месяцев неверны. Давайте посмотрим как мы можем объединить эти формулы.

Наложение маски

Для этого необходима кусочно-заданная функция, но - так как мне это показалось скучным - я задумался о другом пути решения, использующем одну часть функции на одном интервале, другую - на другом.
Полагаю, что проще всего будет найти выражение, равное 1 в одной области применения и 0 - в остальной. Метод, в котором умножая аргумент на выражение мы исключаем его из формулы вне области его применения, я назвал «наложением маски», потому такое поведение подобно некой битовой маске.
Для применения этого метода в последней части нашей функции необходимо найти выражение, равное 1 при , и - так как значения аргумента всегда меньше 16 - для этого прекрасно подходит целочисленное деление на 8.
x 1 2 3 4 5 6 7 8 9 10 11 12
x ⁄ 8 ⌋ 0 0 0 0 0 0 0 1 1 1 1 1

Теперь с помощью этой маски, используя в делимом выражение вместо 1, мы можем заменить порядок получения 0 и 1 формуле на обратный:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 30 31 30 31 30 31 31 30 31 30 31

Эврика! Всё правильно, кроме февраля. Сюрприз-сюрприз.

Февраль

В любом месяце 30 или 31 день, кроме февраля с его 28 (високосный год выходит за рамки этой задачи). На текущий момент по нашей формуле в нём 30 дней, поэтому неплохо бы вычесть выражение, равное 2 при .
Лучшее что мне удалось придумать это , что накладывает маску на все месяцы после февраля:
x 1 2 3 4 5 6 7 8 9 10 11 12
2 mod x 0 0 2 2 2 2 2 2 2 2 2 2

Изменив базовую константу на 28 с добавлением 2 к остальным месяцам получим формулу:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 29 28 31 30 31 30 31 31 30 31 30 31

К сожалению, январь теперь короче на 2 дня. Но, к счастью, получить выражение, которое будет применяться только для первого месяца очень легко: это округлённое вниз обратное к число. Умножив его на 2 получаем окончательную формулу:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 28 31 30 31 30 31 31 30 31 30 31

Послесловие

Вот она - формула для получения количества дней в любом месяце года, использующая простейшую арифметику. В следующий раз когда вы будете вспоминать сколько же дней в сентябре, просто выполните с помощью этой однострочной функции на JavaScript:

Function f(x) { return 28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x); }

Часть II

Вступление

В первой части была получена короткая и даже немного изящная формула, основными достоинствами которой являются простота математического аппарата, отсутствие ветвлений и условных выражений, лаконичность. К недостаткам - кроме того, что вы не будете применять её в вашем проекте - можно отнести отсутствие проверки на вискокосный и не високосный год.
Поэтому я поставил перед собой задачу создать функцию f , такую, что значение f(x, y) для каждого месяца x , представленного числом от 1 до 12 и года y , большего 0, равняется количеству дней в месяце x в году y .
Для нетерпеливых под спойлером находится готовый ответ, остальных же прошу следовать за мной.

Ответ

Остаток от деления: mod и ⌊⌋

Для визуальной наглядности договоримся, что в некоторых формулах оператор деления с остатком заменён нижними скобками, там где это показалось мне необходимым:

Високосный год

В високосный год вводится дополнительный день календаря: 29 февраля. Как известно, високосным является год, кратный 4 и не кратный 100, либо кратный 400. Запишем тождественное этому высказыванию выражение:

Для приведения этого выражения в алгебраическое, необходимо применить к результату выражения инъекцию вида:

Что позволит получить 1 при делении без остатка и 0 при делении с остатком, чтобы использовать её в формуле определения количества дней в месяце.

В качестве функции g" можно использовать 1 минус остаток от деления для :

x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g"(x) Infinity 1 0 0 0 0 0 0 0 0 0 0 0 0 0

Легко заметить, что увеличив делимое и делитель на 1 мы получим правильную формулу при :
x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g"(x) 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Таким образом выражение запишем как:


А выражение запишем как:

Применяя этот подход получим следующую функцию g(y) , значением которой будет 1, если год високосный, или 0 в обратном случае:

y 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
g(y) 0 0 1 0 0 0 1 0 0 0 1
y 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000
g(y) 1 0 0 0 1 0 0 0 1 0 0

Полужирным выделены високосные года.

Напоминаю, что в рамках принятой договорённости оператор получения остатка от деления может быть изображен как mod , так и ⌊⌋.

Наложение маски

В формуле часть является поправкой, прибавляющей 2 дня к январю. Если убрать множитель 2 и в числителе заменить 1 на 2, тогда эта формула будет прибавлять 2 дня к январю и 1 день к февралю, что даёт нам ключ к добавлению дня в високосном году. Для наглядности используем в формуле промежуточное значение g(y) и в качестве y используем 2000 (високосный) и 2001 (не високосный) годы:

Или:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f(x, 2001) 31 28 31 30 31 30 31 31 30 31 30 30

Заключение

В результате получена уже значительно более громоздкая, но более универсальная формула, которую также можно использовать для получения количества дней в месяце определённого года:

Function f(x, y) { return 28 + ((x + Math.floor(x / 8)) % 2) + 2 % x + Math.floor((1 + (1 - (y % 4 + 2) % (y % 4 + 1)) * ((y % 100 + 2) % (y % 100 + 1)) + (1 - (y % 400 + 2) % (y % 400 + 1))) / x) + Math.floor(1/x) - Math.floor(((1 - (y % 4 + 2) % (y % 4 + 1)) * ((y % 100 + 2) % (y % 100 + 1)) + (1 - (y % 400 + 2) % (y % 400 + 1)))/x); }
Пример на C# ideone.com/fANutz .

1 . Я не умею пользоваться подобной мнемоникой, поэтому подсмотрел табличку в интернете.
2 . «Основы», или «Правило С Многими Исключениями», как и большинство правил.
3 . Изначально в римском календаре февраль был последним месяцем года, поэтому есть логика в том, что он короче всех остальных. Также есть логика в добавлении или удалении дня именно в конце года, поэтому его длина является переменной.

Upd. 1:
Альтернативный перевод первой части в

(Часть I ), а также авторским к нему дополнением (Часть II ). Не следует относиться к материалу серьёзно, а скорее как к разминке для ума, требующей не более чем школьных знаний арифметики и не имеющей практического применения. Всем приятного чтения!

Часть I

Вступление

Недавно, после очередной бессонной ночи, я размышлял о методах запоминания количества дней в каждом месяце года. Для этого есть считалочка, а также способ считать на костяшках пальцев, но ни то, ни другое меня не устроило. Я задумался, а не существует ли какой-нибудь математической формулы для решения такой задачи, и - не обнаружив при беглом изучении таковую - бросил себе вызов её создать.

Формализуя Другими словами, необходимо найти функцию f , такую, что значение f(x) для каждого месяца x , представленного числом от 1 до 12, равняется количеству дней в этом месяце. Таблица значений аргумента и функции :

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 28 31 30 31 30 31 31 30 31 30 31

Если у вас возникло желание попробовать самому до прочтения моего решения, то сейчас самое время. Если же вы предпочитаете немедленно увидеть готовый ответ, то посмотрите под спойлер.

Ответ


Ниже следуют мои шаги по нахождению решения.

Математический аппарат

Сначала бегло освежим в памяти два жизненно необходимых в решении этой задачи оператора: целочисленное деление и остаток от деления.

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

Остаток от деления это оператор, находящий остаток от деления. Во многих языках программирования применяется символ % , я же буду использовать конструкции вида , например:

Замечу, что остаток от деления имеет равный с делением приоритет.

Основы

Итак, применим наш математический аппарат для получения базовой формулы. В обычном месяце 30 или 31 день, так что мы можем использовать для получения поочерёдно 1 или 0, а затем просто прибавить к этому числу константу:

Получаем таблицу, полужирным выделены корректные значения:
x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 30 31 30 31 30 31 30 31 30 31 30

Неплохое начало! Уже есть правильные значения для января и для месяцев с марта по июль включительно. Февраль - особый случай, и с ним мы разберёмся чуть позже. После июля для оставшихся месяцев порядок получения 0 и 1 должен быть изменён на обратный.
Для этого мы может прибавить к делимому 1:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 30 31 30 31 30 31 30 31 30 31 30 31

Теперь правильные значения с августа по декабрь, но, как и предполагалось, значения для прочих месяцев неверны. Давайте посмотрим как мы можем объединить эти формулы.

Наложение маски

Для этого необходима кусочно-заданная функция, но - так как мне это показалось скучным - я задумался о другом пути решения, использующем одну часть функции на одном интервале, другую - на другом.
Полагаю, что проще всего будет найти выражение, равное 1 в одной области применения и 0 - в остальной. Метод, в котором умножая аргумент на выражение мы исключаем его из формулы вне области его применения, я назвал «наложением маски», потому такое поведение подобно некой битовой маске.
Для применения этого метода в последней части нашей функции необходимо найти выражение, равное 1 при , и - так как значения аргумента всегда меньше 16 - для этого прекрасно подходит целочисленное деление на 8.
x 1 2 3 4 5 6 7 8 9 10 11 12
x ⁄ 8 ⌋ 0 0 0 0 0 0 0 1 1 1 1 1

Теперь с помощью этой маски, используя в делимом выражение вместо 1, мы можем заменить порядок получения 0 и 1 формуле на обратный:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 30 31 30 31 30 31 31 30 31 30 31

Эврика! Всё правильно, кроме февраля. Сюрприз-сюрприз.

Февраль

В любом месяце 30 или 31 день, кроме февраля с его 28 (високосный год выходит за рамки этой задачи). На текущий момент по нашей формуле в нём 30 дней, поэтому неплохо бы вычесть выражение, равное 2 при .
Лучшее что мне удалось придумать это , что накладывает маску на все месяцы после февраля:
x 1 2 3 4 5 6 7 8 9 10 11 12
2 mod x 0 0 2 2 2 2 2 2 2 2 2 2

Изменив базовую константу на 28 с добавлением 2 к остальным месяцам получим формулу:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 29 28 31 30 31 30 31 31 30 31 30 31

К сожалению, январь теперь короче на 2 дня. Но, к счастью, получить выражение, которое будет применяться только для первого месяца очень легко: это округлённое вниз обратное к число. Умножив его на 2 получаем окончательную формулу:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x) 31 28 31 30 31 30 31 31 30 31 30 31

Послесловие

Вот она - формула для получения количества дней в любом месяце года, использующая простейшую арифметику. В следующий раз когда вы будете вспоминать сколько же дней в сентябре, просто выполните с помощью этой однострочной функции на JavaScript:

Function f(x) { return 28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x); }

Часть II

Вступление

В первой части была получена короткая и даже немного изящная формула, основными достоинствами которой являются простота математического аппарата, отсутствие ветвлений и условных выражений, лаконичность. К недостаткам - кроме того, что вы не будете применять её в вашем проекте - можно отнести отсутствие проверки на вискокосный и не високосный год.
Поэтому я поставил перед собой задачу создать функцию f , такую, что значение f(x, y) для каждого месяца x , представленного числом от 1 до 12 и года y , большего 0, равняется количеству дней в месяце x в году y .
Для нетерпеливых под спойлером находится готовый ответ, остальных же прошу следовать за мной.

Ответ

Остаток от деления: mod и ⌊⌋

Для визуальной наглядности договоримся, что в некоторых формулах оператор деления с остатком заменён нижними скобками, там где это показалось мне необходимым:

Високосный год

В високосный год вводится дополнительный день календаря: 29 февраля. Как известно, високосным является год, кратный 4 и не кратный 100, либо кратный 400. Запишем тождественное этому высказыванию выражение:

Для приведения этого выражения в алгебраическое, необходимо применить к результату выражения инъекцию вида:

Что позволит получить 1 при делении без остатка и 0 при делении с остатком, чтобы использовать её в формуле определения количества дней в месяце.

В качестве функции g" можно использовать 1 минус остаток от деления для :

x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g"(x) Infinity 1 0 0 0 0 0 0 0 0 0 0 0 0 0

Легко заметить, что увеличив делимое и делитель на 1 мы получим правильную формулу при :
x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g"(x) 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Таким образом выражение запишем как:


А выражение запишем как:

Применяя этот подход получим следующую функцию g(y) , значением которой будет 1, если год високосный, или 0 в обратном случае:

y 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
g(y) 0 0 1 0 0 0 1 0 0 0 1
y 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000
g(y) 1 0 0 0 1 0 0 0 1 0 0

Полужирным выделены високосные года.

Напоминаю, что в рамках принятой договорённости оператор получения остатка от деления может быть изображен как mod , так и ⌊⌋.

Наложение маски

В формуле часть является поправкой, прибавляющей 2 дня к январю. Если убрать множитель 2 и в числителе заменить 1 на 2, тогда эта формула будет прибавлять 2 дня к январю и 1 день к февралю, что даёт нам ключ к добавлению дня в високосном году. Для наглядности используем в формуле промежуточное значение g(y) и в качестве y используем 2000 (високосный) и 2001 (не високосный) годы:

Или:

x 1 2 3 4 5 6 7 8 9 10 11 12
f(x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f(x, 2001) 31 28 31 30 31 30 31 31 30 31 30 30

Заключение

В результате получена уже значительно более громоздкая, но более универсальная формула, которую также можно использовать для получения количества дней в месяце определённого года:

Function f(x, y) { return 28 + ((x + Math.floor(x / 8)) % 2) + 2 % x + Math.floor((1 + (1 - (y % 4 + 2) % (y % 4 + 1)) * ((y % 100 + 2) % (y % 100 + 1)) + (1 - (y % 400 + 2) % (y % 400 + 1))) / x) + Math.floor(1/x) - Math.floor(((1 - (y % 4 + 2) % (y % 4 + 1)) * ((y % 100 + 2) % (y % 100 + 1)) + (1 - (y % 400 + 2) % (y % 400 + 1)))/x); }
Пример на C# ideone.com/fANutz .

1 . Я не умею пользоваться подобной мнемоникой, поэтому подсмотрел табличку в интернете.
2 . «Основы», или «Правило С Многими Исключениями», как и большинство правил.
3 . Изначально в римском календаре февраль был последним месяцем года, поэтому есть логика в том, что он короче всех остальных. Также есть логика в добавлении или удалении дня именно в конце года, поэтому его длина является переменной.

Upd. 1:
Альтернативный перевод первой части в