Примечание : данный пост является переводом статьи cmcenroe.me/2014/12/05/days-in-month-formula.html (Часть I ), а также авторским к нему дополнением (Часть II ). Не следует относиться к материалу серьёзно, а скорее как к разминке для ума, требующей не более чем школьных знаний арифметики и не имеющей практического применения. Всем приятного чтения!
Формализуя Другими словами, необходимо найти функцию 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 |
Ответ
Целочисленное деление
это оператор, применяемый во многих языках программирования при делении двух целых чисел и отбрасывающий от частного дробную часть. Я буду изображать его как . Например:
Остаток от деления
это оператор, находящий остаток от деления. Во многих языках программирования применяется символ %
, я же буду использовать конструкции вида , например:
Замечу, что остаток от деления имеет равный с делением приоритет.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Function f(x) { return 28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x); }
Ответ
Для приведения этого выражения в алгебраическое, необходимо применить к результату выражения инъекцию вида:
Что позволит получить 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 |
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 , так и ⌊⌋.
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) | 30 | 28 | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 30 |
Для исправления этого досадного недоразумения добавим к январю 1 день уже известной нам формулой :
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:
Альтернативный перевод первой части в
Примечание : данный пост является переводом статьи cmcenroe.me/2014/12/05/days-in-month-formula.html (Часть I ), а также авторским к нему дополнением (Часть II ). Не следует относиться к материалу серьёзно, а скорее как к разминке для ума, требующей не более чем школьных знаний арифметики и не имеющей практического применения. Всем приятного чтения!
Формализуя Другими словами, необходимо найти функцию 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 |
Ответ
Целочисленное деление
это оператор, применяемый во многих языках программирования при делении двух целых чисел и отбрасывающий от частного дробную часть. Я буду изображать его как . Например:
Остаток от деления
это оператор, находящий остаток от деления. Во многих языках программирования применяется символ %
, я же буду использовать конструкции вида , например:
Замечу, что остаток от деления имеет равный с делением приоритет.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Function f(x) { return 28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x); }
Ответ
Для приведения этого выражения в алгебраическое, необходимо применить к результату выражения инъекцию вида:
Что позволит получить 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 |
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 , так и ⌊⌋.
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) | 30 | 28 | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 30 |
Для исправления этого досадного недоразумения добавим к январю 1 день уже известной нам формулой :
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:
Альтернативный перевод первой части в
Калькулятор дат предназначен для вычисления количества дней между датами, а также для нахождения даты путем прибавления или вычитания определенного количества дней к известной дате.
Для того, чтобы узнать какое число будет через определенное количество дней, воспользуйтесь этой опцией. Введите начальную дату и количество дней, которое нужно к ней прибавить. Для вычитания используйте значение с минусом. В калькуляторе также есть опция для прибавления только рабочих дней.
Этот метод расчета ответит на вопрос "сколько дней прошло с даты". Введите начальную дату и конечную дату и нажмите кнопку "рассчитать". Калькулятор покажет, сколько дней между введенными датами. Отдельно калькулятор покажет количество рабочих дней.
С помощью этой опции можно вычислить сколько дней осталось до определенного события, например до дня рождения или праздника. Для этого в поле начальной даты укажите сегодняшнее число, а в поле конечной даты - дату события.
Калькулятор может вычислять, прибавлять и вычитать как календарные дни, так и рабочие. Официальными нерабочими праздничными днями являются:
Если праздничный день выпал на субботу или воскресенье, его переносят на ближайший рабочий день. Но иногда выходные переносят совсем в другое место календаря. Например, субботу и воскресенье, выпавшие на новогодние праздники, могут перенести на май, чтобы продлить майские праздники.
Калькулятор при расчете дней учитывает как официальные праздничные даты, так и все переносы.
Бесплатный онлайн калькулятор Контур.Бухгалтерии вам поможет и подскажет, какое количество дней прошло между двумя заданными датами. Кроме того, если у вас возникла необходимость, вы можете посчитать сколько календарных, выходных или рабочих дней (часов) содержит указанный период года или нескольких лет.
Вы просто задаете конкретный день начала и конца и через доли секунд получаете расчет. Все данные онлайн-калькулятор считает самостоятельно. Если вы изменяете исходные дни недели, результат автоматически пересчитывается, с учетом високосного года.
Важно: нельзя брать из расчетов за прошлые года показатели рабочих дней/часов за месяц и предоставлять в качестве расчетов — данные будут различаться. Поэтому, лучше воспользуйтесь калькулятором.
Итак, порядок действий:
Вы — бухгалтер. Руководитель попросил вас в ближайшие пару минут предоставить данные по количеству рабочих часов, которые должны отработать все сотрудники компании в феврале. Количество работников вы можете легко определить — у вас перед глазами цифры. А вот количество часов нужно считать....А сколько там в феврале дней? А год-то високосный? А какие дни были выходными? А как определить количество дней праздников?
Решение: просто воспользуйтесь нашим виджетом. Всю информацию вы получите автоматически, вам не нужны настольные календари и калькуляторы.
Хотите вести бухучет, отправлять отчетность и делать расчеты в удобном и простом веб-сервисе? Попробуйте бесплатно 14 дней Контур.Бухгалтерии! Мы быстро вас научим, как сервисом пользоваться и ответим на все вопросы!