其他答案中显示的模数方法可能会产生误导。想象一下一年中的几个星期。在任何 365 天的一年中有 52 个 7 天,还剩下一天。因此,如果我第一年的第 52 周在 12 月 30 日结束,那么我还有 12 月 31 日需要担心。
我可以或者考虑一年中有 53 周,并且第 53 周是 12 月 31 日、1 月 1 日、1 月 2 日、1 月 3 日......或者,更传统地,我认为明年的第一周实际上是从 12 月 31 日开始的。这就是你的日记本。
当然,这意味着明年的第 52 周现在不是在 12 月 30 日结束,而是在 12 月 29 日结束。
每年它一次一天地往回爬,直到第 6 年,我们将第 52 周结束后移了 6 天(并且为了更好的衡量标准,在闰日抛出),所以 2017 年的整个第一周将是包含在 2016 年,那将是愚蠢的。所以 2016 年将有 53 周。
完全相同的逻辑适用于几个月,但可能更难发现。不幸的是,您选择了 2011 年 8 月,该日期安排得很整齐,从星期一开始。
>>> 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 月的第 1 周。
因此,通过简单的天数除以 7 方法,9 月 29 日是 9 月的第 5 周,但查看上面的日历,如果 9 月 1-4 日是在 8 月,那么 9 月 29 日是第 4 周9 月。
这完全取决于您对一周开始时间的定义。
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 周...