【问题标题】:Universal formula to calculate the number of days in a month taking into account leap years考虑闰年计算一个月天数的通用公式
【发布时间】:2017-11-08 14:31:59
【问题描述】:

有人知道像这样计算一个月天数的数学公式吗

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

但哪个也考虑到闰年?还应考虑到公历每 400 年省略 3 个闰日,这是其闰周期的长度。

【问题讨论】:

  • 年份范围是多少?您需要考虑世界历法系统的多少特性? 1584, 1752, 1712, ... 对你来说有什么意义吗? (如果你在 1712 年在瑞典,那么 2 月有 30 天;你的公式需要考虑到这一点吗?)
  • 你是对的。就我个人而言,我需要从 1900 年到 2100 年的公式。但是如果不考虑瑞典,获得更通用的东西会很好(仍然是非常有趣的信息:)

标签: calendar


【解决方案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

【讨论】:

    猜你喜欢
    • 2017-01-13
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多