Как получить номер недели в Python?
Как узнать, какой номер недели является текущим годом 16 июня (wk24) с Python?
20 ответов
datetime.date
имеет isocalendar()
метод, который возвращает кортеж, содержащий календарную неделю:
>>> import datetime
>>> datetime.date(2010, 6, 16).isocalendar()[1]
24
datetime.date.isocalendar () - это метод экземпляра, возвращающий кортеж, содержащий год, номер недели и день недели в соответствующем порядке для данного экземпляра даты.
Вы можете получить номер недели непосредственно из datetime в виде строки.
>>> import datetime
>>> datetime.date(2010, 6, 16).strftime("%V")
'24'
Также вы можете получить различные "типы" номера недели в году, изменяя параметр strftime для:
% U - номер недели текущего года, начиная с первого воскресенья как первого дня первой недели.
% V - номер недели по ISO 8601 текущего года (от 01 до 53), где неделя 1 - это первая неделя, в которой по крайней мере 4 дня в текущем году, а понедельник - первый день недели.
% W - номер недели текущего года, начиная с первого понедельника в качестве первого дня первой недели.
Я получил это отсюда. У меня это работало в Python 2.7.6
Я верю date.isocalendar()
будет ответом. Эта статья объясняет математику календаря ISO 8601. Проверьте часть date.isocalendar() страницы datetime документации Python.
>>> dt = datetime.date(2010, 6, 16)
>>> wk = dt.isocalendar()[1]
24
.isocalendar () возвращает 3-кортеж с (год, недельный номер, недельный день). dt.isocalendar()[0]
возвращает год,dt.isocalendar()[1]
возвращает номер недели, dt.isocalendar()[2]
возвращает день недели. Просто, как может быть.
Есть много систем для недельной нумерации. Ниже приведены наиболее распространенные системы, которые просто приведены с примерами кода:
ISO: первая неделя начинается с понедельника и должна содержать 4 января. Календарь ISO уже реализован на Python:
>>> from datetime import date >>> date(2014, 12, 29).isocalendar()[:2] (2015, 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): первая неделя начинается с воскресенья и должна содержать 4 января. Я создал пакет epiweeks специально для этой системы нумерации. Вот пример:
>>> from datetime import date >>> from epiweeks import Week >>> Week.fromdate(date(2014, 12, 29)) (2014, 53)
Вот еще один вариант:
import time
from time import gmtime, strftime
d = time.strptime("16 Jun 2010", "%d %b %Y")
print(strftime("%U", d))
который печатает 24
,
Неделя ISO, предложенная другими, - хорошая, но она может не соответствовать вашим потребностям. Предполагается, что каждая неделя начинается с понедельника, что приводит к некоторым интересным аномалиям в начале и конце года.
Если вы предпочитаете использовать определение, которое гласит, что неделя 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")
Для целочисленного значения текущей недели года попробуйте:
import datetime
datetime.datetime.utcnow().isocalendar()[1]
Я обнаружил, что это самый быстрый способ узнать номер недели; все варианты.
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.stftime("%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:
Год ISO состоит из 52 или 53 полных недель, причем неделя начинается в понедельник и заканчивается в воскресенье. Первая неделя года по ISO - это первая (по григорианскому) календарная неделя года, содержащая четверг. Это называется неделей номер 1, и год этого четверга по ISO совпадает с его годом по григорианскому календарю.
https://docs.python.org/3/library/datetime.html#datetime.date.isocalendar
ПРИМЕЧАНИЕ. Имейте в виду, что возвращаемое значение является строкой, поэтому передайте результат в
int
конструктор, если вам нужен номер.
Если вы используете только номер недели isocalendar через доску, этого должно быть достаточно:
import datetime
week = date(year=2014, month=1, day=1).isocalendar()[1]
Это возвращает второго члена кортежа, возвращенного isocalendar для нашего номера недели.
Однако, если вы собираетесь использовать функции даты, которые имеют дело с григорианским календарем, isocalendar один не будет работать! Возьмите следующий пример:
import datetime
date = datetime.datetime.strptime("2014-1-1", "%Y-%W-%w")
week = date.isocalendar()[1]
Строка здесь говорит, что мы должны вернуть понедельник первой недели 2014 года в качестве нашей даты. Когда мы используем isocalendar для получения номера недели здесь, мы ожидаем получить тот же номер недели назад, но мы этого не делаем. Вместо этого мы получаем номер недели 2. Почему?
1-я неделя в григорианском календаре - это первая неделя с понедельником. Неделя 1 в isocalendar - это первая неделя, содержащая четверг. Неполная неделя в начале 2014 года содержит четверг, так что isocalendar это неделя 1, и date
неделя 2
Если мы хотим получить григорианскую неделю, нам нужно будет перейти с isocalendar на григорианский. Вот простая функция, которая делает свое дело.
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
Я суммирую обсуждение в два этапа:
- Преобразовать необработанный формат в
datetime
объект. - Используйте функцию
datetime
объект илиdate
Объект для расчета номера недели.
Разогреть
`` `` Питон
from datetime import datetime, date, time
d = date(2005, 7, 14)
t = time(12, 30)
dt = datetime.combine(d, t)
print(dt)
`` `
1-й шаг
Чтобы вручную создать 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
объект.
2-й шаг
Используйте полученные datetime
объект для вызова strptime(format)
, Например,
`` `` Питон
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()
, Например,
`` `` Питон
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()
подготовить еженедельный отчет, особенно в сезон покупок "Рождество-Новый год".
Вы можете попробовать директиву%W, как показано ниже:
d = datetime.datetime.strptime('2016-06-16','%Y-%m-%d')
print(datetime.datetime.strftime(d,'%W'))
"%W": номер недели в году (понедельник - первый день недели) в виде десятичного числа. Все дни в новом году, предшествующем первому понедельнику, считаются неделей 0. (00, 01, ..., 53)
Для пользователей pandas, если вы хотите получить столбец с номером недели:
df['weekofyear'] = df['Date'].dt.week
Допустим, вам нужно объединить неделю с годом текущего дня в виде строки.
import datetime
year,week = datetime.date.today().isocalendar()[:2]
week_of_the_year = f"{year}-{week}"
print(week_of_the_year)
Вы можете получить что-то вроде 2021-28
isocalendar() возвращает неправильные значения года и номера недели для некоторых дат:
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
Сравните с подходом Марка Рэнсома:
>>> 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
У нас есть аналогичная проблема, и мы придумали эту логику, которую я тестировал на тестовых примерах 1 год, и все прошли
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)
Если вы хотите изменить первый день недели, вы можете использовать модуль календаря .
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'
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.............!!!")
Было дано много ответов, но я хотел бы добавить к ним.
Если вам нужно, чтобы неделя отображалась как год / неделя (например, 1953 г. - 53-я неделя 2019 г., 2001 г. - 1-я неделя 2020 г. и т. Д.), Вы можете сделать это:
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