Python:一个月中的第几周

12 投票
9 回答
21767 浏览
提问于 2025-04-16 23:24

当你指定一个日期的时候:

datetime.datetime(2011, 8, 15)

我怎么知道这是这个月的第三周呢?

如果我想要这些日期呢?

datetime.datetime(2011, 2, 28) //should return 4
datetime.datetime(2011, 8, 29) //should return 5

我明白只有在闰年时,二月份才有4周。

9 个回答

2

也许你可以看看这个链接:http://labix.org/python-dateutil,它可能会对你有帮助。

除此之外,这其实就是数学问题。

 from datetime import datetime, timedelta

    def week_of_month(date):
        month = date.month
        week = 0
        while date.month == month:
            week += 1
            date -= timedelta(days=7)

        return week
15

其他回答中提到的取模方法可能会让人感到困惑。想象一下,一年有多少周。每年有52个7天的时间段,剩下1天。所以如果我的第一年,第52周在12月30日结束,而我还有12月31日需要考虑。

我可以选择两种方式来处理这个问题:要么认为这一年有53周,把第53周定为12月31日、1月1日、1月2日、1月3日……要么更常见的做法是认为下一年的第一周实际上是从12月31日开始的。这就是你的日记本是怎么安排的。

当然,这意味着下一年,第52周的结束时间不再是12月30日,而是12月29日。每年都会向前推一天,直到第六年时,我们把第52周的结束时间推回了6天(还多加了一天闰年),这样2017年的第一周就完全包含在2016年里,这样就显得很奇怪了。所以2016年会有53周。

同样的逻辑也适用于月份,不过可能不太容易发现。不幸的是,你选择了2011年8月,这个月的1号正好是星期一。

>>> print calendar.month(2011,8)
    August 2011
Mo Tu We Th Fr Sa Su
 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

>>> print calendar.month(2011,9)
   September 2011
Mo Tu We Th Fr Sa Su
          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

8月29日是8月的第5周,但按照同样的逻辑,9月的1、2、3、4号也会被算作8月的第5周,所以它们不能算作9月的第一周。

因此,9月29日,按照简单的天数除以7的方法,会被算作9月的第5周,但看上面的日历,如果9月的1-4号都在8月,那么9月29日就应该是9月的第4周。

这完全取决于你对一周开始的定义。

import datetime
import calendar

# I am assuming that the first week of a month starts with the first monday of a month...
#I *think* my logic is OK - if Monday (0) is the start of the week, then
#any dayof the month minus its own day of week (0,1,2...) must be positive
#if that day is on or after the first monday of the month

def week_of_month(tgtdate):

    days_this_month = calendar.mdays[tgtdate.month]
    for i in range(1, days_this_month):
        d = datetime.date(tgtdate.year, tgtdate.month, i)
        if d.day - d.weekday() > 0:
            startdate = d
            break
    # now we canuse the modulo 7 appraoch
    return (tgtdate - startdate).days //7 + 1

tgtdates = [datetime.date(2011, 8, 29),
            datetime.date(2011, 8, 1)
            ]

for tgtdate in tgtdates:
    print tgtdate,
    print "is in week %s" % week_of_month(tgtdate)

print calendar.month(tgtdate.year,tgtdate.month)


 # 2011-09-29 is in week 4
 # 2011-09-01 is in week 0
 #    September 2011
 # Mo Tu We Th Fr Sa Su
 #           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

 # 2011-08-29 is in week 5
 # 2011-08-01 is in week 1
 #     August 2011
 # Mo Tu We Th Fr Sa Su
 #  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

上面提到的第0周意味着这一周不算作这个月的一部分。所以9月1日算在8月的第5周。

注意

我想对@unutbu的回答做个评论,但我想我没有足够的积分。

取模7的方法在2011年9月是失效的。

>>> d = datetime.date(2011,9,28)
>>> (d.day-1)//7+1
4
>>> d = datetime.date(2011,9,1)
>>> 
>>> (d.day-1)//7+1
1

从上面的日历来看,9月1日是第一周,但这意味着28日不能在第4周——它必须在第5周,或者1日算在第0周……

13

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在另一个地方使用这些数据。这个过程就像是把水从一个水桶倒到另一个水桶里。

有些时候,我们会遇到一些问题,比如数据的格式不对,或者数据没有按照我们想要的方式排列。这就像是水桶的形状不一样,导致水倒不进去。

为了避免这些问题,我们可以使用一些工具和方法来确保数据能够顺利地从一个地方转移到另一个地方。这样,我们就能更轻松地处理数据,而不必担心出错。

总之,处理数据就像是搬运东西,我们需要确保每一步都做得正确,这样才能顺利完成任务。

In [115]: d = datetime.datetime(2011, 2, 28)

In [116]: (d.day-1)//7+1
Out[116]: 4

In [117]: d = datetime.datetime(2011, 8, 29)

In [118]: (d.day-1)//7+1
Out[118]: 5

撰写回答