如何在Python中获得周数?

如何用Python找出今年6月16日(wk24)的周数?

509374 次浏览

datetime.date有一个isocalendar()方法,它返回一个包含日历周的元组:

>>> import datetime
>>> datetime.date(2010, 6, 16).isocalendar()[1]
24

datetime.date.isocalendar ()是一个实例方法,返回一个元组,其中包含给定日期实例的年份、周号和星期。

在Python 3.9+ isocalendar()中返回带有字段yearweekweekdaynamedtuple,这意味着您可以使用命名属性显式访问星期:

>>> import datetime
>>> datetime.date(2010, 6, 16).isocalendar().week
24

我相信date.isocalendar()将是答案。这篇文章解释了ISO 8601日历背后的数学。查看Python文档的datetime页面中的date. iscalendar()部分。

>>> dt = datetime.date(2010, 6, 16)
>>> wk = dt.isocalendar()[1]
24

. iscalendar()返回一个三元组,包含(年,星期数,星期天数)。dt.isocalendar()[0]返回年份,dt.isocalendar()[1]返回周数,dt.isocalendar()[2]返回周数。尽可能的简单。

这是另一个选择:

import time
from time import gmtime, strftime
d = time.strptime("16 Jun 2010", "%d %b %Y")
print(strftime(d, '%U'))

它打印24

看:http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior

别人建议的ISO周是很好的,但可能不适合你的需求。它假设每周从星期一开始,这导致了年初和年底的一些有趣的异常情况。

如果你宁愿使用一个定义,说第一周总是1月1日到1月7日,而不管星期几,可以使用这样的推导:

>>> testdate=datetime.datetime(2010,6,16)
>>> print(((testdate - datetime.datetime(testdate.year,1,1)).days // 7) + 1)
24

一般要获取当前周数(从周日开始):

from datetime import *
today = datetime.today()
print today.strftime("%U")

iscalendar()对于某些日期返回错误的年和周数值:

Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime as dt
>>> myDateTime = dt.datetime.strptime("20141229T000000.000Z",'%Y%m%dT%H%M%S.%fZ')
>>> yr,weekNumber,weekDay = myDateTime.isocalendar()
>>> print "Year is " + str(yr) + ", weekNumber is " + str(weekNumber)
Year is 2015, weekNumber is 1

与Mark Ransom的方法相比:

>>> yr = myDateTime.year
>>> weekNumber = ((myDateTime - dt.datetime(yr,1,1)).days/7) + 1
>>> print "Year is " + str(yr) + ", weekNumber is " + str(weekNumber)
Year is 2014, weekNumber is 52

您可以直接从datetime作为字符串获取周数。

>>> import datetime
>>> datetime.date(2010, 6, 16).strftime("%V")
'24'

你也可以通过改变strftime形参来获得不同类型的年份的周数:

%U - 一年中第几周(星期日为每周的第一天)作为一个零填充的十进制数。新年中第一个星期日之前的所有日子都被认为是第0周。示例:00, 01,…,53

%W -以十进制数表示的一年的周数(周一作为一周的第一天)。新年中第一个星期一之前的所有日子都被认为是第0周。示例:00, 01,…,53

[…]

(在Python 3.6中添加,反向移植到一些发行版的Python 2.7)为了方便起见,包含了C89标准不需要的几个附加指令。这些参数都对应于ISO 8601日期值。当与strftime()方法一起使用时,这些可能不是在所有平台上都可用。

[…]

%V - ISO 8601周作为一个十进制数,星期一作为一周的第一天。第01周包含1月4日。示例:01, 02,…,53

来自:datetime本;基本日期时间类型—Python 3.7.3文档

我从在这里中找到了它。它在Python 2.7.6中对我有效

对于一年中的瞬时周的整数值,尝试:

import datetime
datetime.datetime.utcnow().isocalendar()[1]

如果你只使用等历法周数,那么以下内容就足够了:

import datetime
week = date(year=2014, month=1, day=1).isocalendar()[1]

这将检索由iscalendar为周数返回的元组的第二个成员。

但是,如果您打算使用处理公历的日期函数,那么单独使用iscalendar是行不通的!举个例子:

import datetime
date = datetime.datetime.strptime("2014-1-1", "%Y-%W-%w")
week = date.isocalendar()[1]

这里的字符串表示返回2014年第一周的星期一作为日期。当我们使用iscalendar在这里检索周数时,我们希望得到相同的周数,但我们没有。相反,我们得到的周数是2。为什么?

公历的第一周是包含星期一的第一周。等日历中的第1周是包含星期四的第一周。2014年初的部分周包含一个星期四,所以这是等历的第一周,而date则是第2周。

如果我们想要得到公历周,我们将需要从等历法转换为公历。下面是一个简单的函数。

import datetime


def gregorian_week(date):
# The isocalendar week for this date
iso_week = date.isocalendar()[1]


# The baseline Gregorian date for the beginning of our date's year
base_greg = datetime.datetime.strptime('%d-1-1' % date.year, "%Y-%W-%w")


# If the isocalendar week for this date is not 1, we need to
# decrement the iso_week by 1 to get the Gregorian week number
return iso_week if base_greg.isocalendar()[1] == 1 else iso_week - 1
userInput = input ("Please enter project deadline date (dd/mm/yyyy/): ")


import datetime


currentDate = datetime.datetime.today()


testVar = datetime.datetime.strptime(userInput ,"%d/%b/%Y").date()


remainDays = testVar - currentDate.date()


remainWeeks = (remainDays.days / 7.0) + 1




print ("Please pay attention for deadline of project X in days and weeks are  : " ,(remainDays) , "and" ,(remainWeeks) , "Weeks ,\nSo  hurryup.............!!!")

你可以尝试%W指令,如下所示:

d = datetime.datetime.strptime('2016-06-16','%Y-%m-%d')
print(datetime.datetime.strftime(d,'%W'))

'%W':以十进制数表示的一年中的周数(星期一作为一周的第一天)。新年中第一个星期一之前的所有日子都被认为是第0周。(00, 01,…53)

我将讨论总结为两个步骤:

  1. 将原始格式转换为datetime对象。
  2. 使用datetime对象或date对象的函数来计算周数。

热身

from datetime import datetime, date, time
d = date(2005, 7, 14)
t = time(12, 30)
dt = datetime.combine(d, t)
print(dt)

第一步

要手动生成datetime对象,可以使用datetime.datetime(2017,5,3)datetime.datetime.now()

但实际上,我们通常需要解析一个现有的字符串。我们可以使用strptime函数,例如datetime.strptime('2017-5-3','%Y-%m-%d'),其中你必须指定格式。不同格式代码的详细信息可以在官方文档中找到。

或者,更方便的方法是使用dateparse模块。例如dateparser.parse('16 Jun 2010')dateparser.parse('12/2/12')dateparser.parse('2017-5-3')

上述两种方法将返回datetime对象。

第二步

使用获得的datetime对象调用strptime(format)。例如,

python

dt = datetime.strptime('2017-01-1','%Y-%m-%d') # return a datetime object. This day is Sunday
print(dt.strftime("%W")) # '00' Monday as the 1st day of the week. All days in a new year preceding the 1st Monday are considered to be in week 0.
print(dt.strftime("%U")) # '01' Sunday as the 1st day of the week. All days in a new year preceding the 1st Sunday are considered to be in week 0.
print(dt.strftime("%V")) # '52' Monday as the 1st day of the week. Week 01 is the week containing Jan 4.

决定使用哪种格式是很棘手的。更好的方法是获取date对象来调用isocalendar()。例如,

python

dt = datetime.strptime('2017-01-1','%Y-%m-%d') # return a datetime object
d = dt.date() # convert to a date object. equivalent to d = date(2017,1,1), but date.strptime() don't have the parse function
year, week, weekday = d.isocalendar()
print(year, week, weekday) # (2016,52,7) in the ISO standard

实际上,你更可能使用date.isocalendar() 来准备一份周报,尤其是在Christmas-New Year购物季。

许多周编号系统。下面是最常见的系统代码示例:

  • ISO:第一周从星期一开始,必须包含1月4日(或一年的第一个星期四)。ISO日历已经在Python中实现:

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
    
  • 北美:第一周从星期天开始,必须包含1月1日。以下代码是我针对北美系统的Python ISO日历实现的修改版本:

    from datetime import date
    
    
    def week_from_date(date_object):
    date_ordinal = date_object.toordinal()
    year = date_object.year
    week = ((date_ordinal - _week1_start_ordinal(year)) // 7) + 1
    if week >= 52:
    if date_ordinal >= _week1_start_ordinal(year + 1):
    year += 1
    week = 1
    return year, week
    
    
    def _week1_start_ordinal(year):
    jan1 = date(year, 1, 1)
    jan1_ordinal = jan1.toordinal()
    jan1_weekday = jan1.weekday()
    week1_start_ordinal = jan1_ordinal - ((jan1_weekday + 1) % 7)
    return week1_start_ordinal
    
    >>> from datetime import date
    >>> week_from_date(date(2014, 12, 29))
    (2015, 1)
    
  • MMWR (CDC):第一周从星期天开始,必须包含1月4日(或一年中的第一个星期三)。我专门为这个编号系统创建了epiweeks包(也支持ISO系统)。这里有一个例子:

    >>> from datetime import date
    >>> from epiweeks import Week
    >>> Week.fromdate(date(2014, 12, 29))
    (2014, 53)
    

已经给出了很多答案,但我想补充一下。

如果您需要将周显示为年/周样式(例如,1953 - 2019年第53周,2001 - 2020年第1周等),您可以这样做:

import datetime


year = datetime.datetime.now()
week_num = datetime.date(year.year, year.month, year.day).strftime("%V")
long_week_num = str(year.year)[0:2] + str(week_num)

它将使用当前的年份和周,写这篇文章当天的long_week_num将是:

>>> 2006

如果你想改变一周的第一天,你可以使用日历模块

import calendar
import datetime


calendar.setfirstweekday(calendar.WEDNESDAY)
isodate = datetime.datetime.strptime(sweek,"%Y-%m-%d").isocalendar()
week_of_year = isodate[1]

例如,计算从周三开始的一周的冲刺数:

def calculate_sprint(sweek):
calendar.setfirstweekday(calendar.WEDNESDAY)
isodate=datetime.datetime.strptime(sweek,"%Y-%m-%d").isocalendar()
return "{year}-{month}".format(year=isodate[0], month=isodate[1])


calculate_sprint('2021-01-01')
>>>'2020-53'
我们也有类似的问题,我们想出了这个逻辑 我已经测试了一年的测试用例&所有通过< / p >
import datetime




def week_of_month(dt):


first_day = dt.replace(day=1)
dom = dt.day
if first_day.weekday() == 6:
adjusted_dom = dom
else:
adjusted_dom = dom + first_day.weekday()
if adjusted_dom % 7 == 0 and first_day.weekday() != 6:
value = adjusted_dom / 7.0 + 1
elif first_day.weekday() == 6 and adjusted_dom % 7 == 0 and adjusted_dom == 7:
value = 1
else:
value = int(ceil(adjusted_dom / 7.0))


return int(value)




year = 2020
month = 01
date = 01


date_value = datetime.datetime(year, month, date).date()
no = week_of_month(date_value)

我发现这是获得周数的最快方法;所有的变体。

from datetime import datetime




dt = datetime(2021, 1, 3)  # Date is January 3rd (sunday), 2021, year starts with Friday


dt.strftime("%W")  # '00'; Monday is considered first day of week, Sunday is the last day of the week which started in the previous year
dt.strftime("%U")  # '01'; Sunday is considered first day of week
dt.strftime("%V")  # '53'; ISO week number; result is '53' since there is no Thursday in this year's part of the week

%V的进一步说明可以在Python文档中找到:

国际标准化组织的一年包括52或53个完整的星期,其中一周从星期一开始,到星期日结束。ISO年的第一周是包含星期四的一年的第一个(公历)周。这被称为第1周,星期四的ISO年份与公历年份相同。

https://docs.python.org/3/library/datetime.html#datetime.date.isocalendar

注意:请记住返回值是一个字符串,所以如果你需要一个数字,将结果传递给int构造函数。

假设您需要将一周与当天的年份组合为字符串。

import datetime
year,week = datetime.date.today().isocalendar()[:2]
week_of_the_year = f"{year}-{week}"
print(week_of_the_year)

你可能会得到类似2021 - 28的东西

对于pandas用户,如果你想获得一列周数:

df['weekofyear'] = df['Date'].dt.week