วิธีรับหมายเลขสัปดาห์ใน Python อย่างไร


339

จะทราบได้อย่างไรว่าหมายเลขสัปดาห์ใดคือปีปัจจุบันในวันที่ 16 มิถุนายน (wk24) ด้วย Python


1
@ Donal: หนึ่งมองไปที่ 16 มิถุนายนอื่น ๆ ที่ 26 มิถุนายน
ระหว่าง

5
กำหนดสัปดาห์ 1. isocalendar () ไม่ใช่วิธีเดียวที่จะทำ
ทำเครื่องหมาย Tolonen

3
โปรดทราบว่าการส่งออกของอาจแตกต่างจากstrftime("%U", d) isocalendar()ตัวอย่างเช่นถ้าคุณเปลี่ยนปี 2004 คุณจะได้รับ 24 สัปดาห์โดยใช้strftime()และในสัปดาห์ที่ 25 isocalendar()โดยใช้
moooeeeep

คำตอบ:


409

datetime.dateมีisocalendar()วิธีการซึ่งจะส่งกลับ tuple ที่มีสัปดาห์ปฏิทิน:

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

datetime.date.isocalendar ()เป็นอินสแตนซ์เมธอดที่ส่งคืนทูเปิลที่มีปี, สัปดาห์และหมายเลขวันตามลำดับสำหรับอินสแตนซ์วันที่ที่กำหนด


7
มันจะช่วยถ้าคุณอธิบาย ' [1]' หรือให้ตัวชี้ที่จะหาข้อมูล
Jonathan Leffler

5
ฉันเดาได้ง่ายที่สุดคือการแยกหมายเลขสัปดาห์โดยใช้ strftime นำเข้า datetime ที่ดีที่สุดในวันนี้ = datetime.now () สัปดาห์ = today.strftime ("% W")
bipsa

7
นี่สายไปหน่อย แต่ในเครื่องของฉันผลตอบแทนdate(2010, 1, 1).isocalendar()[1] 53จากเอกสาร: "ตัวอย่างเช่น 2004 เริ่มในวันพฤหัสบดีดังนั้นสัปดาห์แรกของ ISO ปี 2004 เริ่มต้นในวันจันทร์ที่ 29 ธันวาคม 2546 และสิ้นสุดในวันอาทิตย์ที่ 4 มกราคม 2547 เป็นต้นไปdate(2003, 12, 29).isocalendar() == (2004, 1, 1)และdate(2004, 1, 4).isocalendar() == (2004, 1, 7)"
jclancy

17
isocalendar()ดีมาก แต่ต้องแน่ใจว่าเป็นสิ่งที่คุณต้องการ วันนี้เป็นตัวอย่างที่สมบูรณ์แบบ 2016/01/01 (2015, 53, 5)เท่ากับ now.strftime("%W")และnow.strftime("%U")เท่ากับ00ซึ่งมักเป็นสิ่งที่ต้องการ ตัวอย่าง STRFTIME
DaveL17

เป็นคนดีฉันเพิ่งเพิ่มวันนี้ฉันคิดว่ามันจะเป็นประโยชน์มันเป็นสิ่งที่ฉันกำลังเสาะหา: D
Vitaliy Terziev

124

คุณสามารถรับหมายเลขสัปดาห์ได้โดยตรงจาก 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, backported ไปยัง Python 2.7 ของการแจกจ่าย ) คำสั่งเพิ่มเติมหลายอย่างที่ไม่จำเป็นในมาตรฐาน C89 นั้นรวมอยู่ด้วยเพื่อความสะดวก พารามิเตอร์เหล่านี้ทั้งหมดสอดคล้องกับค่าวันที่ ISO 8601 สิ่งเหล่านี้อาจไม่สามารถใช้ได้ในทุกแพลตฟอร์มเมื่อใช้กับstrftime()วิธีการ

[ ... ]

%V- ISO 8601 สัปดาห์เป็นตัวเลขทศนิยมโดยให้วันจันทร์เป็นวันแรกของสัปดาห์ Week 01 คือสัปดาห์ที่มี Jan 4 ตัวอย่าง: 01 , 02, …, 53

จาก: วันที่และเวลา - ประเภทวันที่และเวลาพื้นฐาน - เอกสาร Python 3.7.3

ฉันพบจากที่นี่แล้ว มันใช้งานได้สำหรับฉันใน Python 2.7.6


คุณอ้างถึงอะไรคู่มือ Linux บางอย่าง? Python 2.7.5 และ 3.3.2 พูดInvalid format stringกับรูปแบบนี้ เอกสารของพวกเขาไม่ได้พูดถึง%Vเช่นกัน
Vsevolod Golovanov

3
ขอโทษฉันไม่ได้พูดถึงเรื่องนี้ผมได้จากที่นี่ มันใช้งานได้สำหรับฉันใน Python 2.7.6
jotacor

2
คำตอบที่ดี! ผมอยากจะเพิ่มว่าถ้าคุณมีความสนใจใน '<ปี> - <ISOWEEK>' ตัวแทนของวันที่ที่คุณใช้แทน%G-%V เท่ากับปี ISO ของ%Y-%V%G%Y
KenHBS

ฉันต้องเขียนแบบนี้เพื่อให้มันทำงานได้: datetime.datetime (2010, 6, 16) .strftime ("% V") หรือชอบ datetime.datetime นี้ (2010, 6, 16) .date () ("% V")
Einar

77

ฉันเชื่อว่าdate.isocalendar()จะเป็นคำตอบ บทความนี้จะอธิบายคณิตศาสตร์ที่อยู่เบื้องหลังปฏิทิน ISO 8601 ตรวจสอบส่วน date.isocalendar () ของหน้าวันที่และเวลาของเอกสาร Python

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

.isocalendar () ส่งคืน 3-tuple ด้วย (ปี, wk num, วัน wk) dt.isocalendar()[0]ส่งคืนปีdt.isocalendar()[1]ส่งคืนหมายเลขสัปดาห์dt.isocalendar()[2]ส่งคืนวันในสัปดาห์ เรียบง่ายเท่าที่จะเป็นไปได้


4
+1 สำหรับลิงก์ที่อธิบายถึงลักษณะที่ไม่ได้ใช้งานง่ายของสัปดาห์ ISO
Mark Ransom

27

นี่คือตัวเลือกอื่น:

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

24ซึ่งพิมพ์

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


9
หรือ% W หากสัปดาห์ของคุณเริ่มต้นในวันจันทร์
ZeWaren

1
วิธีนี้ดีกว่าในกรณีที่คุณไม่ต้องการแยกหรือแปลงวันที่ซึ่งมาเป็นสตริง ... เพียงแค่ส่งสตริงในรูปแบบ strptime ในรูปแบบสตริงตามที่เป็นอยู่และระบุรูปแบบในอาร์กิวเมนต์ที่สอง ทางออกที่ดี โปรดจำไว้ว่า:% W หากสัปดาห์เริ่มในวันจันทร์
TheCuriousOne

22

สัปดาห์ ISO ที่คนอื่นแนะนำเป็นคนดี แต่มันอาจไม่ตรงกับความต้องการของคุณ มันจะถือว่าในแต่ละสัปดาห์เริ่มต้นด้วยวันจันทร์ซึ่งจะนำไปสู่ความผิดปกติบางอย่างที่น่าสนใจในช่วงต้นและปลายปี

หากคุณต้องการใช้คำจำกัดความที่กล่าวว่าสัปดาห์ที่ 1 เป็นวันที่ 1 มกราคมถึง 7 มกราคมเสมอโดยไม่คำนึงถึงวันในสัปดาห์ให้ใช้คำที่มาเช่นนี้

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

3
การบอกว่า isocalendar มี "ความผิดปกติบางอย่างที่น่าสนใจ" ในตอนต้นและปลายปีดูเหมือนจะเป็นการพูดน้อย ผลลัพธ์ของ isocalendar นั้นทำให้เข้าใจผิดมาก (แม้ว่าจะไม่ถูกต้องจริงภายใต้ข้อกำหนด ISO) สำหรับค่าวันที่และเวลาบางอย่างเช่น 29 ธันวาคม 2014, 00:00:00 ซึ่งตาม isocalendar มีค่าปี 2015 และหนึ่งสัปดาห์จำนวน 1 (ดู รายการของฉันด้านล่าง)
เควิน

3
@ เควินมันไม่ผิดหรอกมันเป็นแค่คำจำกัดความของพวกเขาไม่ตรงกับคุณ ISO ตัดสินใจสองสิ่ง: สิ่งแรกที่ทั้งสัปดาห์วันจันทร์ถึงวันอาทิตย์จะเป็นในปีเดียวกันอันดับที่สองซึ่งปีที่มีวันส่วนใหญ่จะเป็นวันที่ได้รับมอบหมาย สิ่งนี้นำไปสู่วันของสัปดาห์ในช่วงต้นและปลายปีที่ย้ายเข้าสู่ปีที่อยู่ติดกัน
Mark Ransom

6
ตกลง แต่ตามคำจำกัดความของคนส่วนใหญ่วันที่ 29 ธันวาคม 2014 จะไม่ใช่สัปดาห์ที่ 1 ของปี 2558 แน่นอนที่สุดฉันแค่ต้องการดึงความสนใจไปยังแหล่งที่มาของความสับสนนี้
เควิน

นี่คือสิ่งที่ฉันกำลังมองหา ไม่เกี่ยวกับวิธีการทำเช่นนี้ แต่ข้อมูลเกี่ยวกับ ISO และเริ่มต้นด้วยสิ่งจันทร์
Amit Amola

19

โดยทั่วไปเพื่อรับหมายเลขสัปดาห์ปัจจุบัน (เริ่มจากวันอาทิตย์):

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

4
จากเอกสารของ strftime ('% U'): "หมายเลขสัปดาห์ของปี (วันอาทิตย์เป็นวันแรกของสัปดาห์) เป็นเลขทศนิยม [00,53] ทุกวันในปีใหม่ก่อนวันอาทิตย์แรกจะได้รับการพิจารณา จะอยู่ในสัปดาห์ที่ 0 "
Dolan Antenucci

14

สำหรับค่าจำนวนเต็มของสัปดาห์ในทันทีของปีลอง:

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

10

มีหลายระบบสำหรับสัปดาห์หมายเลข ต่อไปนี้เป็นระบบที่พบบ่อยที่สุดที่ใส่ตัวอย่างโค้ดไว้:

  • ISO : สัปดาห์แรกเริ่มต้นด้วยวันจันทร์และต้องมีวันที่ 4 มกราคม ปฏิทิน ISO ถูกใช้งานใน Python แล้ว:

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
  • อเมริกาเหนือ : สัปดาห์แรกเริ่มต้นด้วยวันอาทิตย์และต้องมีวันที่ 1 มกราคม รหัสต่อไปนี้คือการปรับใช้ปฏิทิน ISO ของ Python สำหรับระบบอเมริกาเหนือ:

    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โดยเฉพาะสำหรับระบบหมายเลขนี้ (ยังรองรับระบบ ISO) นี่คือตัวอย่าง:
    >>> from datetime import date
    >>> from epiweeks import Week
    >>> Week.fromdate(date(2014, 12, 29))
    (2014, 53)

8

หากคุณใช้หมายเลขสัปดาห์ของ isocalendar ทั่วกระดานสิ่งต่อไปนี้น่าจะเพียงพอ:

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

สิ่งนี้จะดึงสมาชิกที่สองของ tuple ที่ส่งกลับโดย isocalendar สำหรับหมายเลขสัปดาห์ของเรา

อย่างไรก็ตามหากคุณกำลังจะใช้ฟังก์ชั่นวันที่ที่จัดการในปฏิทิน Gregorian, isocalendar เพียงอย่างเดียวจะไม่ทำงาน! นำตัวอย่างต่อไปนี้:

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

สตริงที่นี่บอกว่าจะกลับวันจันทร์ของสัปดาห์แรกในปี 2014 เป็นวันที่ของเรา เมื่อเราใช้ isocalendar เพื่อดึงหมายเลขสัปดาห์ที่นี่เราคาดว่าจะได้หมายเลขสัปดาห์เดิมกลับมา แต่เราไม่ทำ แต่เรากลับได้เลข 2 สัปดาห์ทำไม

สัปดาห์ที่ 1 ในปฏิทิน Gregorian เป็นสัปดาห์แรกที่มีวันจันทร์ สัปดาห์ที่ 1 ใน isocalendar เป็นสัปดาห์แรกที่มีวันพฤหัสบดี สัปดาห์บางส่วนในช่วงต้นปี 2014 มีวันพฤหัสบดีดังนั้นนี่คือสัปดาห์ที่ 1 โดย isocalendar และทำให้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

6

คุณสามารถลองใช้คำสั่ง% W ดังต่อไปนี้:

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

'% W': หมายเลขสัปดาห์ของปี (วันจันทร์เป็นวันแรกของสัปดาห์) เป็นตัวเลขทศนิยม ทุกวันในปีใหม่ก่อนวันจันทร์แรกถือเป็นสัปดาห์ที่ 0 (00, 01, ... , 53)


2

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

เปรียบเทียบกับวิธีของ 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

3
เมื่อมองไปที่ลิงก์บางอย่างเกี่ยวกับปฏิทิน iso8601 (เช่นstaff.science.uu.nl/~gent0113/calendar/isocalendar.htm ) ฉันเห็นว่าค่าปีและสัปดาห์ที่ส่งกลับโดย isocalendar () ไม่ใช่ "ไม่ถูกต้อง" เช่นนี้ ตัวอย่างเช่นภายใต้ ISO8601 ปี 2004 เริ่มต้นเมื่อวันที่ 29 ธันวาคม 2546 ดังนั้น isocalendar () อาจถูกต้องในการส่งคืนปี 2558 สำหรับ Dec.29 2014 ในปี 2015 แต่สำหรับจุดประสงค์ของผู้คนจำนวนมากสิ่งนี้จะทำให้เข้าใจผิด .
เควิน

2

ฉันสรุปการอภิปรายสองขั้นตอน:

  1. แปลงรูปแบบ raw เป็น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)

`` `

ขั้นตอนที่ 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()ในการจัดทำรายงานรายสัปดาห์โดยเฉพาะอย่างยิ่งในฤดูการช็อปปิ้ง "คริสต์มาส - ปีใหม่"


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

-1

ได้รับคำตอบจำนวนมาก แต่ ID ต้องการเพิ่มให้กับพวกเขา

หากคุณต้องการให้สัปดาห์แสดงเป็นปี / สัปดาห์ (เช่น 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

ทำไมต้องสร้างdate()ตั้งแต่เริ่มต้น datetime.datetime()อินสแตนซ์มี.date()วิธีการสำหรับงานนั้น
Martijn Pieters

อย่างไรก็ตามสิ่งที่น่ากังวลก็คือคำตอบของคุณเลือก ศตวรรษไม่ใช่ปีปัจจุบัน และถ้าคุณจะใช้การจัดรูปแบบสตริงสำหรับหมายเลขสัปดาห์ทำไมไม่ใช้สิ่งนั้นเพื่อรวมปีด้วย
Martijn Pieters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.