How to get week number in Python?

Python

Python Problem Overview


How to find out what week number is current year on June 16th (wk24) with Python?

Python Solutions


Solution 1 - Python

datetime.date has a isocalendar() method, which returns a tuple containing the calendar week:

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

datetime.date.isocalendar() is an instance-method returning a tuple containing year, weeknumber and weekday in respective order for the given date instance.

In Python 3.9+ isocalendar() returns a namedtuple with the fields year, week and weekday which means you can access the week explicitly using a named attribute:

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

Solution 2 - Python

You can get the week number directly from datetime as string.

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

Also you can get different "types" of the week number of the year changing the strftime parameter for:

> %U - Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0. Examples: 00, 01, …, 53

> %W - Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0. Examples: 00, 01, …, 53

> [...]

> (Added in Python 3.6, backported to some distribution's Python 2.7's) Several additional directives not required by the C89 standard are included for convenience. These parameters all correspond to ISO 8601 date values. These may not be available on all platforms when used with the strftime() method.

> [...]

> %V - ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4. Examples: 01, 02, …, 53

> from: datetime — Basic date and time types — Python 3.7.3 documentation

I've found out about it from here. It worked for me in Python 2.7.6

Solution 3 - Python

I believe date.isocalendar() is going to be the answer. This article explains the math behind ISO 8601 Calendar. Check out the date.isocalendar() portion of the datetime page of the Python documentation.

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

.isocalendar() return a 3-tuple with (year, wk num, wk day). dt.isocalendar()[0] returns the year,dt.isocalendar()[1] returns the week number, dt.isocalendar()[2] returns the week day. Simple as can be.

Solution 4 - Python

Here's another option:

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

which prints 24.

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

Solution 5 - Python

There are many systems for week numbering. The following are the most common systems simply put with code examples:

  • ISO: First week starts with Monday and must contain the January 4th (or first Thursday of the year). The ISO calendar is already implemented in Python:

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
    
  • North American: First week starts with Sunday and must contain the January 1st. The following code is my modified version of Python's ISO calendar implementation for the North American system:

    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): First week starts with Sunday and must contain the January 4th (or first Wednesday of the year). I created the epiweeks package specifically for this numbering system (also has support for the ISO system). Here is an example:

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

Solution 6 - Python

The ISO week suggested by others is a good one, but it might not fit your needs. It assumes each week begins with a Monday, which leads to some interesting anomalies at the beginning and end of the year.

If you'd rather use a definition that says week 1 is always January 1 through January 7, regardless of the day of the week, use a derivation like this:

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

Solution 7 - Python

Generally to get the current week number (starts from Sunday):

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

Solution 8 - Python

For the integer value of the instantaneous week of the year try:

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

Solution 9 - Python

If you are only using the isocalendar week number across the board the following should be sufficient:

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

This retrieves the second member of the tuple returned by isocalendar for our week number.

However, if you are going to be using date functions that deal in the Gregorian calendar, isocalendar alone will not work! Take the following example:

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

The string here says to return the Monday of the first week in 2014 as our date. When we use isocalendar to retrieve the week number here, we would expect to get the same week number back, but we don't. Instead we get a week number of 2. Why?

Week 1 in the Gregorian calendar is the first week containing a Monday. Week 1 in the isocalendar is the first week containing a Thursday. The partial week at the beginning of 2014 contains a Thursday, so this is week 1 by the isocalendar, and making date week 2.

If we want to get the Gregorian week, we will need to convert from the isocalendar to the Gregorian. Here is a simple function that does the trick.

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


    

    

Solution 10 - Python

I summarize the discussion to two steps:

  1. Convert the raw format to a datetime object.
  2. Use the function of a datetime object or a date object to calculate the week number.

Warm up

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

1st step

To manually generate a datetime object, we can use datetime.datetime(2017,5,3) or datetime.datetime.now().

But in reality, we usually need to parse an existing string. we can use strptime function, such as datetime.strptime('2017-5-3','%Y-%m-%d') in which you have to specific the format. Detail of different format code can be found in the official documentation.

Alternatively, a more convenient way is to use dateparse module. Examples are dateparser.parse('16 Jun 2010'), dateparser.parse('12/2/12') or dateparser.parse('2017-5-3')

The above two approaches will return a datetime object.

2nd step

Use the obtained datetime object to call strptime(format). For example,

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.

It's very tricky to decide which format to use. A better way is to get a date object to call isocalendar(). For example,

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

In reality, you will be more likely to use date.isocalendar() to prepare a weekly report, especially in the Christmas-New Year shopping season.

Solution 11 - Python

You can try %W directive as below:

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

'%W': Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0. (00, 01, ..., 53)

Solution 12 - Python

I found these to be the quickest way to get the week number; all of the variants.

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

Further clarification for %V can be found in the Python doc:

> The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first (Gregorian) calendar week of a year containing a Thursday. This is called week number 1, and the ISO year of that Thursday is the same as its Gregorian year.

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

NOTE: Bear in mind the return value is a string, so pass the result to a int constructor if you need a number.

Solution 13 - Python

For pandas users, if you want to get a column of week number:

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

Solution 14 - Python

isocalendar() returns incorrect year and weeknumber values for some dates:

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

Compare with Mark Ransom's approach:

>>> 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

Solution 15 - Python

Let's say you need to have a week combined with the year of the current day as a string.

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

You might get something like 2021-28

Solution 16 - Python

If you want to change the first day of the week you can make use of the calendar module.

import calendar
import datetime

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

For example, calculate the sprint number for a week starting on WEDNESDAY:

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'

Solution 17 - Python

We have a similar issue and we came up with this logic I have tested for 1year test cases & all passed

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)

Solution 18 - Python

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.............!!!") 

Solution 19 - Python

A lot of answers have been given, but id like to add to them.

If you need the week to display as a year/week style (ex. 1953 - week 53 of 2019, 2001 - week 1 of 2020 etc.), you can do this:

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)

It will take the current year and week, and long_week_num in the day of writing this will be:

>>> 2006

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGerryView Question on Stackoverflow
Solution 1 - PythonHorst GutmannView Answer on Stackoverflow
Solution 2 - PythonjotacorView Answer on Stackoverflow
Solution 3 - PythonByron SommardahlView Answer on Stackoverflow
Solution 4 - PythonBart KiersView Answer on Stackoverflow
Solution 5 - PythonmhalshehriView Answer on Stackoverflow
Solution 6 - PythonMark RansomView Answer on Stackoverflow
Solution 7 - PythonChaggsterView Answer on Stackoverflow
Solution 8 - Pythonuser2099484View Answer on Stackoverflow
Solution 9 - PythonmeesterguypersonView Answer on Stackoverflow
Solution 10 - PythonYuchao JiangView Answer on Stackoverflow
Solution 11 - PythonTung NguyenView Answer on Stackoverflow
Solution 12 - PythonJakovView Answer on Stackoverflow
Solution 13 - PythonSonghua HuView Answer on Stackoverflow
Solution 14 - PythonKevinView Answer on Stackoverflow
Solution 15 - PythonEgidiusView Answer on Stackoverflow
Solution 16 - PythonEcho9kView Answer on Stackoverflow
Solution 17 - PythonT DView Answer on Stackoverflow
Solution 18 - PythonWael Abo ElhassanView Answer on Stackoverflow
Solution 19 - PythonSimo TodorovView Answer on Stackoverflow