2015-03-01 4 views
0

Кто-то знает математическую формулу для вычисления количества дней в месяц, как это одинУниверсальная формула для вычисления количества дней в месяц с учетом високосных лет

28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x); 

, но который также принимает и високосный год? Следует также учитывать, что григорианский календарь пропускает 3 височных дня каждые 400 лет, что является длительностью его цикла прыжка.

+0

Какой диапазон лет? Сколько из особенностей вашей календарной системы необходимо учитывать? 1584, 1752, 1712, ... любой из важных для вас? (Если вы были в Швеции в 1712 году, то в феврале было 30 дней, должна ли ваша формула учитывать это?) –

+0

Вы правы. Лично мне нужна формула с 1900 по 2100 год. Но было бы неплохо получить что-то более универсальное, не принимая во внимание Швецию (еще очень интересная информация :) –

ответ

1

Не сложно добавить выражение (m == 2) * leapyear(yyyy) в выражение, чтобы определить правильное количество дней в феврале високосного года. Этот код C показывает способ сделать это:

#include <stdio.h> 
#include <stdbool.h> 

static inline bool leapyear(int yy) 
{ 
    if (yy % 4 != 0) return false; 
    if (yy % 100 != 0) return true; 
    if (yy % 400 != 0) return false; 
    return true; 
} 

static inline int old_dim(int mm) 
{ 
    return (28 + (mm + (mm/8)) % 2 + 2 % mm + 2 * (1/mm)); 
} 

static inline int new_dim(int mm, int yyyy) 
{ 
    return (28 + (mm + (mm/8)) % 2 + 2 % mm + 2 * (1/mm) + ((mm == 2) * leapyear(yyyy))); 
} 

int main(void) 
{ 
    /*28 + (x + Math.floor(x/8)) % 2 + 2 % x + 2 * Math.floor(1/x);*/ 
    for (int mm = 1; mm <= 12; mm++) 
     printf("mm = %2d, DIM = %2d\n", mm, old_dim(mm)); 

    for (int yyyy = 1900; yyyy < 2101; yyyy += 5) 
    { 
     for (int mm = 1; mm <= 12; mm++) 
      printf("yyyy = %4d, mm = %2d: DIM = %2d\n", yyyy, mm, new_dim(mm, yyyy)); 
    } 

    return 0; 
} 

Выход для mm = 2 (отфильтрованной от полной мощности) является:

yyyy = 1900, mm = 2: DIM = 28 
yyyy = 1905, mm = 2: DIM = 28 
yyyy = 1910, mm = 2: DIM = 28 
yyyy = 1915, mm = 2: DIM = 28 
yyyy = 1920, mm = 2: DIM = 29 
yyyy = 1925, mm = 2: DIM = 28 
yyyy = 1930, mm = 2: DIM = 28 
yyyy = 1935, mm = 2: DIM = 28 
yyyy = 1940, mm = 2: DIM = 29 
yyyy = 1945, mm = 2: DIM = 28 
yyyy = 1950, mm = 2: DIM = 28 
yyyy = 1955, mm = 2: DIM = 28 
yyyy = 1960, mm = 2: DIM = 29 
yyyy = 1965, mm = 2: DIM = 28 
yyyy = 1970, mm = 2: DIM = 28 
yyyy = 1975, mm = 2: DIM = 28 
yyyy = 1980, mm = 2: DIM = 29 
yyyy = 1985, mm = 2: DIM = 28 
yyyy = 1990, mm = 2: DIM = 28 
yyyy = 1995, mm = 2: DIM = 28 
yyyy = 2000, mm = 2: DIM = 29 
yyyy = 2005, mm = 2: DIM = 28 
yyyy = 2010, mm = 2: DIM = 28 
yyyy = 2015, mm = 2: DIM = 28 
yyyy = 2020, mm = 2: DIM = 29 
yyyy = 2025, mm = 2: DIM = 28 
yyyy = 2030, mm = 2: DIM = 28 
yyyy = 2035, mm = 2: DIM = 28 
yyyy = 2040, mm = 2: DIM = 29 
yyyy = 2045, mm = 2: DIM = 28 
yyyy = 2050, mm = 2: DIM = 28 
yyyy = 2055, mm = 2: DIM = 28 
yyyy = 2060, mm = 2: DIM = 29 
yyyy = 2065, mm = 2: DIM = 28 
yyyy = 2070, mm = 2: DIM = 28 
yyyy = 2075, mm = 2: DIM = 28 
yyyy = 2080, mm = 2: DIM = 29 
yyyy = 2085, mm = 2: DIM = 28 
yyyy = 2090, mm = 2: DIM = 28 
yyyy = 2095, mm = 2: DIM = 28 
yyyy = 2100, mm = 2: DIM = 28 

Это справедливо считает 1900 и 2100 как не високосные годы, но 2000 как високосный год.

yyyy = 1900, mm = 1: DIM = 31 
yyyy = 1900, mm = 2: DIM = 28 
yyyy = 1900, mm = 3: DIM = 31 
yyyy = 1900, mm = 4: DIM = 30 
yyyy = 1900, mm = 5: DIM = 31 
yyyy = 1900, mm = 6: DIM = 30 
yyyy = 1900, mm = 7: DIM = 31 
yyyy = 1900, mm = 8: DIM = 31 
yyyy = 1900, mm = 9: DIM = 30 
yyyy = 1900, mm = 10: DIM = 31 
yyyy = 1900, mm = 11: DIM = 30 
yyyy = 1900, mm = 12: DIM = 31 

… 

yyyy = 2000, mm = 1: DIM = 31 
yyyy = 2000, mm = 2: DIM = 29 
yyyy = 2000, mm = 3: DIM = 31 
yyyy = 2000, mm = 4: DIM = 30 
yyyy = 2000, mm = 5: DIM = 31 
yyyy = 2000, mm = 6: DIM = 30 
yyyy = 2000, mm = 7: DIM = 31 
yyyy = 2000, mm = 8: DIM = 31 
yyyy = 2000, mm = 9: DIM = 30 
yyyy = 2000, mm = 10: DIM = 31 
yyyy = 2000, mm = 11: DIM = 30 
yyyy = 2000, mm = 12: DIM = 31 
Смежные вопросы