37

python 是否提供了一种轻松获取当月当前周(1:4)的方法?

4

17 回答 17

43

为了使用直除,您正在查看的日期的月份日期需要根据该月第一天的位置(一周内)进行调整。因此,如果您的月份恰好从星期一(一周的第一天)开始,您可以按照上面的建议进行除法。但是,如果该月从星期三开始,您将需要添加 2,然后进行除法。这一切都封装在下面的函数中。

from math import ceil

def week_of_month(dt):
    """ Returns the week of the month for the specified date.
    """

    first_day = dt.replace(day=1)

    dom = dt.day
    adjusted_dom = dom + first_day.weekday()

    return int(ceil(adjusted_dom/7.0))
于 2013-05-29T02:30:30.830 回答
24

我知道这已经有好几年了,但我花了很多时间试图找到这个答案。我做了自己的方法,并认为我应该分享。

calendar 模块有一个monthcalendar 方法,该方法返回一个二维数组,其中每一行代表一周。例如:

import calendar
calendar.monthcalendar(2015,9)

结果:

[[0,0,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,0,0,0]]

所以 numpy 你的朋友在哪里。我在美国,所以我希望一周从星期日开始,第一周标记为 1:

import calendar
import numpy as np
calendar.setfirstweekday(6)

def get_week_of_month(year, month, day):
    x = np.array(calendar.monthcalendar(year, month))
    week_of_month = np.where(x==day)[0][0] + 1
    return(week_of_month)

get_week_of_month(2015,9,14)

返回

3
于 2015-09-15T19:27:56.940 回答
16

如果您的第一周从每月的第一天开始,您可以使用整数除法:

导入日期时间
day_of_month = datetime.datetime.now().day
week_number = (day_of_month - 1) // 7 + 1
于 2010-09-27T18:02:46.487 回答
14

查看包Pendulum

>>> dt = pendulum.parse('2018-09-30')
>>> dt.week_of_month
5
于 2018-11-16T10:50:49.060 回答
5

这个版本可以改进,但作为 python 模块(日期时间和日历)的第一次看,我提出了这个解决方案,我希望能有用:

from datetime import datetime
n = datetime.now()
#from django.utils.timezone import now
#n = now() #if you use django with timezone

from calendar import Calendar
cal = Calendar() # week starts Monday
#cal = Calendar(6) # week stars Sunday

weeks = cal.monthdayscalendar(n.year, n.month)
for x in range(len(weeks)):
    if n.day in weeks[x]:
        print x+1
于 2014-10-30T19:50:58.123 回答
3

查看 python日历模块

于 2010-09-27T18:03:09.123 回答
3

乔希的答案必须稍微调整以适应星期天的第一天。

def get_week_of_month(date):
   first_day = date.replace(day=1)

   day_of_month = date.day

   if(first_day.weekday() == 6):
       adjusted_dom = (1 + first_day.weekday()) / 7
   else:
       adjusted_dom = day_of_month + first_day.weekday()

   return int(ceil(adjusted_dom/7.0))
于 2015-12-15T19:40:59.493 回答
1

我找到了一个非常简单的方法:

import datetime
def week(year, month, day):
    first_week_month = datetime.datetime(year, month, 1).isocalendar()[1]
    if month == 1 and first_week_month > 10:
        first_week_month = 0
    user_date = datetime.datetime(year, month, day).isocalendar()[1]
    if month == 1 and user_date > 10:
        user_date = 0
    return user_date - first_week_month

如果第一周返回 0

于 2010-12-06T22:54:44.713 回答
1

乔希的回答似乎是最好的,但我认为我们应该考虑一个事实,即只有当周四属于该月时,一周才属于一个月。至少iso是这么说的。

按照这个标准,一个月最多可以有5周。一天可能属于一个月,但可能不属于一周

我已经考虑到只需添加一个简单的

if (first_day.weekday()>3) :
        return ret_val-1
    else:
        return ret_val

其中 ret_val 正是 Josh 的计算值。在 2017 年 6 月(有 5 周)和 2017 年 9 月测试。通过“2017-09-01”返回 0,因为那一天属于不属于 9 月的一周。

最正确的方法是让该方法返回输入日期所属的周数和月份名称。

于 2017-09-22T12:46:48.693 回答
1
def week_of_month(date_value):
 return (date_value.isocalendar()[1] - date_value.replace(day=1).isocalendar()[1] + 1)

date_value 应该是时间戳格式这将在所有情况下给出完美的答案

于 2020-03-11T10:43:51.537 回答
1

@Manuel Solorzano 回答的一个变体:

from calendar import monthcalendar
def get_week_of_month(year, month, day):
    return next(
        (
            week_number
            for week_number, days_of_week in enumerate(monthcalendar(year, month), start=1)
            if day in days_of_week
        ),
        None,
    )

例如:

>>> get_week_of_month(2020, 9, 1)
1
>>> get_week_of_month(2020, 9, 30)
5
>>> get_week_of_month(2020, 5, 35)
None
于 2020-09-01T17:52:39.653 回答
1

假设我们有一个月的日历如下:

Mon Tue Wed Thur Fri Sat Sun
                 1   2   3 
4   5   6   7    8   9   10

我们说第 1 ~ 3 天属于第 1 周,第 4 ~ 10 天属于第 2 周,依此类推

在这种情况下,我认为特定日期的 week_of_month 应按如下方式计算:

import datetime
def week_of_month(year, month, day):
    weekday_of_day_one = datetime.date(year, month, 1).weekday()
    weekday_of_day = datetime.date(year, month, day)
    return (day - 1)//7 + 1 + (weekday_of_day < weekday_of_day_one)

但是,如果我们想要获取该日期所在工作日的第 n 个,例如第 1 天是第一个星期五,第 8 天是第二个星期五,第 6 天是第一个星期三,那么我们可以简单地返回(day - 1 )//7 + 1

于 2020-09-18T18:57:09.060 回答
1

您正在寻找的答案是(dm-dw+(dw-dm)%7)/7+1在哪里dm是一个月dw中的哪一天,是一周中的哪一天,并且%是正余数。

这来自于将月份偏移量 ( mo) 和月份的周数( ) 关联起来wm,其中月份偏移量是第一天开始到一周的距离。如果我们考虑所有这些变量都从 0 开始,我们有

wm*7+dw = dm+mo

您可以解决这个模 7mo因为这会导致wm变量丢失,因为它仅显示为 7 的倍数

dw = dm+mo   (%7)
mo = dw-dm   (%7)
mo = (dw-dm)%7  (since the month offset is 0-6)

然后你只需将月份偏移量代入原始方程并求解wm

wm*7+dw = dm+mo
wm*7 = dm-dw + mo
wm*7 = dm-dw + (dw-dm)%7
wm = (dm-dw + (dw-dm)%7) / 7

由于dmdw总是成对的,它们可以偏移任意数量,因此,将所有内容切换为从 1 开始只会将等式更改为(dm-dw + (dw-dm)%7)/7 + 1

当然pythondatetime库从dm1和dw0开始。所以,假设date是一个datatime.date对象,你可以去

(date.day-1-date.dayofweek() + (date.dayofweek()-date.day+1)%7) / 7 + 1

由于内部位始终是 7 的倍数(字面意思是dw*7),您可以看到第一个-date.dayofweek()简单地将值向后调整为最接近 7 的倍数。整数除法也是如此,因此可以进一步简化为

(date.day-1 + (date.dayofweek()-date.day+1)%7) // 7 + 1

请注意,这dayofweek()会将星期日放在周末。

于 2021-02-12T18:10:22.577 回答
0

这应该这样做。

#! /usr/bin/env python2

import calendar, datetime

#FUNCTIONS
def week_of_month(date):
    """Determines the week (number) of the month"""

    #Calendar object. 6 = Start on Sunday, 0 = Start on Monday
    cal_object = calendar.Calendar(6)
    month_calendar_dates = cal_object.itermonthdates(date.year,date.month)

    day_of_week = 1
    week_number = 1

    for day in month_calendar_dates:
        #add a week and reset day of week
        if day_of_week > 7:
            week_number += 1
            day_of_week = 1

        if date == day:
            break
        else:
            day_of_week += 1

    return week_number


#MAIN
example_date = datetime.date(2015,9,21)

print "Week",str(week_of_month(example_date))
#Returns 'Week 4'
于 2015-09-22T04:05:12.827 回答
0

移动到一个月的最后一天并除以 7

from math import ceil

def week_of_month(dt):
    """ Returns the week of the month for the specified date.
    """
    # weekday from monday == 0 ---> sunday == 6
    last_day_of_week_of_month = dt.day + (7 - (1 + dt.weekday()))
    return int(ceil(last_day_of_week_of_month/7.0))
于 2019-03-27T04:38:58.150 回答
0
  import datetime
    
  def week_number_of_month(date_value):
            week_number = (date_value.isocalendar()[1] - date_value.replace(day=1).isocalendar()[1] + 1)
            if week_number == -46:
                week_number = 6
           return week_number
                
 date_given = datetime.datetime(year=2018, month=12, day=31).date()
                
 week_number_of_month(date_given)
于 2020-12-24T14:37:04.213 回答
0

您可以简单地执行以下操作:

  1. 首先提取年份数字的月份和星期
df['month'] = df['Date'].dt.month
df['week'] = df['Date'].dt.week 
  1. 然后按月分组并排列周数
df['weekOfMonth'] = df.groupby('month')["week"].rank("dense", ascending=False)
于 2021-11-03T13:05:36.920 回答