Wie bekomme ich die Wochennummer in Python?


337

Wie kann man mit Python herausfinden, welche Wochennummer das aktuelle Jahr am 16. Juni (wk24) ist?


1
@Donal: Einer schaut auf den 16. Juni, der andere auf den 26. Juni.
Zwischenjagd

5
Woche 1 definieren. Isocalendar () ist nicht die einzige Möglichkeit, dies zu tun.
Mark Tolonen

3
Beachten Sie, dass die Ausgabe von strftime("%U", d)von der abweichen kann isocalendar(). Wenn Sie beispielsweise das Jahr auf 2004 ändern, erhalten Sie Woche 24 mit strftime()und Woche 25 mit isocalendar().
Moooeeeep

Antworten:


408

datetime.datehat eine isocalendar()Methode, die ein Tupel zurückgibt, das die Kalenderwoche enthält:

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

datetime.date.isocalendar () ist eine Instanzmethode, die ein Tupel zurückgibt, das Jahr, Wochennummer und Wochentag in der jeweiligen Reihenfolge für die angegebene Datumsinstanz enthält.


7
Es wäre hilfreich, wenn Sie das ' [1]' erklären oder einen Zeiger geben würden, wo Sie nach Informationen suchen sollen.
Jonathan Leffler

5
Ich denke, am einfachsten ist es, die Wochennummer mit strftime zu extrahieren. Am besten importieren Sie datetime today = datetime.now () week = today.strftime ("% W")
bipsa

7
Das ist etwas spät. Aber auf meiner Maschine date(2010, 1, 1).isocalendar()[1]kehrt zurück 53. Aus den Dokumenten: "Zum Beispiel beginnt 2004 an einem Donnerstag, also beginnt die erste Woche des ISO-Jahres 2004 am Montag, dem 29. Dezember 2003 und endet am Sonntag, dem 4. Januar 2004, so dass date(2003, 12, 29).isocalendar() == (2004, 1, 1)und date(2004, 1, 4).isocalendar() == (2004, 1, 7)."
Jclancy

17
isocalendar()ist großartig, aber sei sicher, dass es das ist, was du willst. Heute ist ein perfektes Beispiel. 01/01/2016 ist gleich (2015, 53, 5). now.strftime("%W")und now.strftime("%U")sind gleich, 00was oft gewünscht wird. STRFTIME Beispiele
DaveL17

Schön, ich habe gerade den heutigen Tag hinzugefügt, an dem ich denke, dass es hilfreich sein wird. Es war das, wonach ich gesucht habe: D
Vitaliy Terziev

123

Sie können die Wochennummer direkt von datetime als Zeichenfolge abrufen.

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

Sie können auch verschiedene "Typen" der Wochennummer des Jahres erhalten, indem Sie den strftimeParameter ändern für:

%U- Wochennummer des Jahres (Sonntag als erster Wochentag) als null aufgefüllte Dezimalzahl. Alle Tage in einem neuen Jahr vor dem ersten Sonntag gelten als Woche 0. Beispiele: 00 , 01,…, 53

%W- Wochennummer des Jahres ( Montag als erster Wochentag) als Dezimalzahl. Alle Tage in einem neuen Jahr vor dem ersten Montag gelten als Woche 0. Beispiele: 00 , 01,…, 53

[...]

( Hinzugefügt in Python 3.6, zurückportiert auf Python 2.7 einiger Distributionen ) Einige zusätzliche Anweisungen, die vom C89-Standard nicht benötigt werden, sind der Einfachheit halber enthalten. Diese Parameter entsprechen alle Datumswerten nach ISO 8601. Diese sind möglicherweise nicht auf allen Plattformen verfügbar, wenn sie mit der strftime()Methode verwendet werden.

[...]

%V- ISO 8601 Woche als Dezimalzahl mit Montag als erstem Wochentag. Woche 01 ist die Woche mit dem 4. Januar. Beispiele: 01 , 02,…, 53

von: datetime - Grundlegende Datums- und Uhrzeittypen - Python 3.7.3-Dokumentation

Ich habe es von hier herausgefunden . Es hat bei mir in Python 2.7.6 funktioniert


Was zitierst du, ein Linux-Handbuch? Python 2.7.5 und 3.3.2 sagen Invalid format stringzu diesem Muster. Ihre Dokumente erwähnen auch %Vnicht.
Vsevolod Golovanov

3
Entschuldigung, ich habe es nicht erwähnt, ich bin von hier . Es hat bei mir in Python 2.7.6 funktioniert.
Jotacor

2
Gute Antwort! Ich möchte hinzufügen, dass Sie %G-%Vanstelle von "<JAHR> - <ISOWEEK>" - Darstellung Ihrer Daten verwenden, anstatt %Y-%V. %Gist das ISO- %Y
Jahresäquivalent

Ich musste es so schreiben, damit es funktioniert: datetime.datetime (2010, 6, 16) .strftime ("% V") oder wie dieses datetime.datetime (2010, 6, 16) .date (). Strftime ("% V")
Einar

77

Ich glaube date.isocalendar(), das wird die Antwort sein. Dieser Artikel erklärt die Mathematik hinter dem ISO 8601-Kalender. Überprüfen Sie den Abschnitt date.isocalendar () auf der datetime-Seite der Python-Dokumentation.

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

.isocalendar () gibt ein 3-Tupel mit (Jahr, Woche, Woche) zurück. dt.isocalendar()[0]Gibt das Jahr zurück, dt.isocalendar()[1]gibt die Wochennummer zurück, dt.isocalendar()[2]gibt den Wochentag zurück. So einfach wie möglich.


4
+1 für den Link, der die nicht intuitive Natur von ISO-Wochen erklärt.
Mark Ransom

27

Hier ist eine weitere Option:

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

welche druckt 24.

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


9
oder% W, wenn Ihre Wochen montags beginnen.
ZeWaren

1
Dieser Ansatz ist besser in Fällen, in denen Sie ein Datum, das als Zeichenfolge geliefert wird, nicht teilen oder konvertieren möchten. Übergeben Sie die Zeichenfolge einfach in strptime im Zeichenfolgenformat und geben Sie das Format im zweiten Argument an. Gute Lösung. Denken Sie daran:% W, wenn die Woche montags beginnt.
TheCuriousOne

22

Die von anderen vorgeschlagene ISO-Woche ist gut, entspricht aber möglicherweise nicht Ihren Anforderungen. Es wird davon ausgegangen, dass jede Woche mit einem Montag beginnt, was zu Beginn und Ende des Jahres zu einigen interessanten Anomalien führt.

Wenn Sie lieber eine Definition verwenden möchten, die besagt, dass Woche 1 unabhängig vom Wochentag immer der 1. bis 7. Januar ist, verwenden Sie eine Ableitung wie folgt:

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

3
Zu sagen, dass der Isokalender zu Beginn und am Ende des Jahres "einige interessante Anomalien" aufweist, scheint etwas untertrieben zu sein. Die Ergebnisse von isocalendar sind für einige Datums- / Uhrzeitwerte wie den 29. Dezember 2014, 00:00:00, die laut isocalendar einen Jahreswert von 2015 und eine Wochennummer von 1 haben, sehr irreführend (auch wenn sie gemäß der ISO-Spezifikation nicht falsch sind) (siehe mein Eintrag unten).
Kevin

3
@ Kevin, es ist nicht falsch, es ist nur so, dass ihre Definitionen nicht mit Ihren übereinstimmen. ISO entschied zwei Dinge: Erstens, dass die gesamte Woche von Montag bis Sonntag im selben Jahr sein würde, zweitens, dass das Jahr, das die meisten Tage enthält, das zugewiesene sein würde. Dies führt zu Wochentagen um den Anfang und das Ende des Jahres, die in das angrenzende Jahr übergehen.
Mark Ransom

6
Einverstanden. Aber nach der Definition der meisten Menschen wird der 29. Dezember 2014 definitiv nicht die erste Woche des Jahres 2015 sein. Ich wollte nur auf diese potenzielle Quelle der Verwirrung aufmerksam machen.
Kevin

Genau das habe ich gesucht. Nicht darüber, wie das geht, sondern die Informationen bezüglich der ISO und beginnend mit der Sache am Montag.
Amit Amola

19

Im Allgemeinen, um die aktuelle Wochennummer zu erhalten (ab Sonntag):

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

4
Aus der Dokumentation der Strftime ('% U'): "Wochennummer des Jahres (Sonntag als erster Wochentag) als Dezimalzahl [00,53]. Alle Tage in einem neuen Jahr vor dem ersten Sonntag werden berücksichtigt in Woche 0 sein. "
Dolan Antenucci

14

Für den ganzzahligen Wert der momentanen Woche des Jahres versuchen Sie:

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

10

Es gibt viele Systeme zur Wochennummerierung . Die folgenden Systeme werden am häufigsten mit Codebeispielen verwendet:

  • ISO : Die erste Woche beginnt mit Montag und muss den 4. Januar enthalten. Der ISO-Kalender ist bereits in Python implementiert:

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
  • Nordamerika : Die erste Woche beginnt mit dem Sonntag und muss den 1. Januar enthalten. Der folgende Code ist meine modifizierte Version der ISO-Kalenderimplementierung von Python für das nordamerikanische 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) : Die erste Woche beginnt mit dem Sonntag und muss den 4. Januar enthalten. Ich habe das epiweeks- Paket speziell für dieses Nummerierungssystem erstellt (unterstützt auch das ISO-System). Hier ist ein Beispiel:
    >>> from datetime import date
    >>> from epiweeks import Week
    >>> Week.fromdate(date(2014, 12, 29))
    (2014, 53)

8

Wenn Sie nur die Isocalendar-Wochennummer auf der ganzen Linie verwenden, sollte Folgendes ausreichen:

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

Dadurch wird das zweite Mitglied des von isocalendar zurückgegebenen Tupels für unsere Wochennummer abgerufen.

Wenn Sie jedoch Datumsfunktionen verwenden, die im Gregorianischen Kalender behandelt werden, funktioniert der Isokalender allein nicht! Nehmen Sie das folgende Beispiel:

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

Die Zeichenfolge hier sagt, dass der Montag der ersten Woche im Jahr 2014 als unser Datum zurückgegeben werden soll. Wenn wir hier isocalendar verwenden, um die Wochennummer abzurufen, würden wir erwarten, dass wir dieselbe Wochennummer zurückerhalten, aber wir tun es nicht. Stattdessen erhalten wir eine Wochennummer von 2. Warum?

Woche 1 im Gregorianischen Kalender ist die erste Woche mit einem Montag. Woche 1 im Isokalender ist die erste Woche mit einem Donnerstag. Die Teilwoche zu Beginn des Jahres 2014 enthält einen Donnerstag. Dies ist also Woche 1 im Isokalender und dateWoche 2.

Wenn wir die Gregorianische Woche haben wollen, müssen wir vom Isokalender zum Gregorianischen konvertieren. Hier ist eine einfache Funktion, die den Trick macht.

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

Sie können die% W-Direktive wie folgt ausprobieren:

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

'% W': Wochennummer des Jahres (Montag als erster Wochentag) als Dezimalzahl. Alle Tage in einem neuen Jahr vor dem ersten Montag gelten als Woche 0. (00, 01, ..., 53)


2

isocalendar () gibt für einige Daten falsche Jahres- und Wochennummernwerte zurück:

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

Vergleichen Sie mit Mark Ransoms Ansatz:

>>> 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
Wenn ich mir einige Links zum iso8601-Kalender ansehe (z. B. staff.science.uu.nl/~gent0113/calendar/isocalendar.htm ), sehe ich, dass die von isocalendar () zurückgegebenen Jahres- und Wochennummernwerte als solche nicht "falsch" sind. Unter ISO8601 begann beispielsweise das Jahr 2004 am 29. Dezember 2003. Daher kann isocalendar () ein Jahr 2015 für den 29. Dezember 2014 korrekt zurückgeben, aber für viele Zwecke wird dies ziemlich irreführend sein .
Kevin

2

Ich fasse die Diskussion in zwei Schritten zusammen:

  1. Konvertieren Sie das Rohformat in ein datetimeObjekt.
  2. Verwenden Sie die Funktion eines datetimeObjekts oder eines dateObjekts, um die Wochennummer zu berechnen.

Sich warm laufen

`` `Python

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

`` `

1. Schritt

Um ein datetimeObjekt manuell zu generieren , können wir datetime.datetime(2017,5,3)oder verwenden datetime.datetime.now().

In der Realität müssen wir jedoch normalerweise eine vorhandene Zeichenfolge analysieren. Wir können strptimeFunktionen verwenden, datetime.strptime('2017-5-3','%Y-%m-%d')in denen Sie das Format angeben müssen. Einzelheiten zu verschiedenen Formatcodes finden Sie in der offiziellen Dokumentation .

Alternativ ist es bequemer, das Dateparse- Modul zu verwenden. Beispiele sind dateparser.parse('16 Jun 2010'), dateparser.parse('12/2/12')oderdateparser.parse('2017-5-3')

Die beiden oben genannten Ansätze geben ein datetimeObjekt zurück.

2. Schritt

Verwenden Sie das erhaltene datetimeObjekt zum Aufrufen strptime(format). Zum Beispiel,

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

`` `

Es ist sehr schwierig zu entscheiden, welches Format verwendet werden soll. Ein besserer Weg ist es, ein dateObjekt zum Aufrufen zu bringen isocalendar(). Zum Beispiel,

`` `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 der Realität werden Sie eher date.isocalendar()einen wöchentlichen Bericht erstellen, insbesondere in der Einkaufssaison "Weihnachten-Neujahr".


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

Es wurden viele Antworten gegeben, aber ich würde sie gerne ergänzen.

Wenn Sie die Woche als Jahr / Woche-Stil anzeigen möchten (z. B. 1953 - Woche 53 von 2019, 2001 - Woche 1 von 2020 usw.), können Sie dies tun:

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)

Es wird das aktuelle Jahr und die aktuelle Woche dauern, und long_week_num am Tag des Schreibens wird dies sein:

>>> 2006

Warum ein date()von Grund auf neu erstellen ? datetime.datetime()Instanzen haben eine .date()Methode für diesen Job.
Martijn Pieters

Besorgniserregender ist jedoch, dass Ihre Antwort das Jahrhundert und nicht das aktuelle Jahr auswählt. Und wenn Sie die Zeichenfolgenformatierung für die Wochennummer verwenden möchten, warum verwenden Sie diese dann nicht auch, um das Jahr einzuschließen?
Martijn Pieters
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.