一个月有多少个星期日(包括周一等)?

编程语言 2026-07-09

给定一个(公历)月,我如何找出该月中有多少个星期二(或星期三,或……)?这个月要么有4个,要么有5个,但到底是哪个?

一种简单的解决办法是遍历从29日开始直到该月的天数。如果其中有哪一天是所请求的星期几,就返回5,否则返回4。但我确定并不需要通过遍历来计算这个……?

我们可以假设这个月是用它的第一天表示的,即2026-05-01表示2026年 5月。

我尝试了很多,但大多数解法都很复杂:要写大量代码/运算,或在算法上让人难以理解。

解决方案

其实,由于一个月只有28到 31天,这可以通过一个基础的分情况判断来解决,随后又可以简化为一个简洁的算术表达式。

让我们在isolation1中逐一查看每种情况:
  • 28天:显然这个月恰好有四个完整的周,因此答案是4。
  • 29天:无论月初是哪一天,都会在四周后再次出现。因此如果第一天就是我们关心的那一天,答案就是5,否则为4。
  • 30天:在四周后,月的前两天也会再次出现。因此如果这前两天中有一天是我们关心的那一天,答案为5,否则为4。
  • 31天:类似的,只不过前三天中必须有一天是我们关心的那一天。

因此,如果计算“我们关心的那一天”与月初第一天之间的距离:29天的月份距离必须为0;30天的月份最多为1;31天的月份最多为2。

因此,我们得到如下代码:
static int CountDayOfWeekInMonth(DateTime firstDayOfMonth, DayOfWeek day)
{
    int daysInMonth = DateTime.DaysInMonth(firstDayOfMonth.Year, firstDayOfMonth.Month);
    if(daysInMonth == 28)
        return 4;

    // Wrap around if the distance is negative
    int distance = (7 + (int)day - (int)firstDayOfMonth.DayOfWeek) % 7;
    return distance <= daysInMonth - 29 ? 5 : 4;

    /*
    Equivalent to:

    if(daysInMonth == 29 && distance == 0)
        return 5;
    if(daysInMonth == 30 && distance <= 1)
        return 5;
    if(daysInMonth == 31 && distance <= 2)
        return 5;
    return 4;
    */
}

1我认为这个规律可以通过查阅日历快速理解,例如这张2026年 5月的日历(31天):

+-----+-----+-----+-----+-----+-----+-----+
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |   1 |   2 |   3 |
|   4 |   5 |   6 |   7 |   8 |   9 |  10 |
|  11 |  12 |  13 |  14 |  15 |  16 |  17 |
|  18 |  19 |  20 |  21 |  22 |  23 |  24 |
|  25 |  26 |  27 |  28 |  29 |  30 |  31 |
+-----+-----+-----+-----+-----+-----+-----+

周五、周六和周日是月初的三天,它们也是唯一会出现五次的日期。如果假设周日是我们关心的那一天,那么到第一天(周五)的距离是2。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章