Datum von Wochennummer abrufen


87

Bitte was ist los mit meinem Code:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)

Anzeige "2013-01-01 00:00:00", Danke.

Antworten:


175

Eine Wochennummer reicht nicht aus, um ein Datum zu generieren. Sie brauchen auch einen Wochentag. Standard hinzufügen:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)

Das Muster -1und -%wweist den Parser an, den Montag in dieser Woche auszuwählen. Dies gibt aus:

2013-07-01 00:00:00

%Wverwendet Montag als ersten Tag der Woche. Während Sie Ihren eigenen Wochentag auswählen können, können Sie unerwartete Ergebnisse erhalten, wenn Sie davon abweichen.

Siehe Abschnitt strftime()und strptime()Verhalten in der Dokumentation, Fußnote 4:

Bei Verwendung mit der strptime()Methode %Uund %Wnur bei Berechnungen, wenn der Wochentag und das Jahr angegeben sind.

Hinweis: Wenn Ihre Wochennummer ein ISO-Wochendatum ist , möchten Sie %G-W%V-%ustattdessen verwenden! Diese Anweisungen erfordern Python 3.6 oder neuer.


Ich wünschte, ich könnte dir mehr als eine Stimme geben ... Ich habe meinen Kopf herumgeschlagen, um herauszufinden, warum es nicht funktioniert hat.
Islam Q.

2
Funktioniert nicht. datetime.datetime.strptime ("2018-W0-0", "% YW% W-% w") == datetime.datetime.strptime ("2018-W1-0", "% YW% W-% w") -> "2018-01-07 00:00:00". 1. und 2. Woche 2018 haben das gleiche Startdatum.
ozw1z5rd

2
@ ozw1z5rd: Das liegt daran, dass es 2018 keine Woche 0 gibt. Woche 0 ist die Teilwoche vor dem ersten Montag des Jahres. 2018 ist der erste Montag der 1. Januar. Mit anderen Worten, Ihre Eingabezeichenfolge ist hier das Problem, nicht die Technik, und Python hat Fehler korrigiert, um W0 so zu interpretieren, dass es stattdessen W1 bedeutet.
Martijn Pieters

@ ozw1z5rd: Wenn dies ein Problem für Ihre App ist, müssen Sie solche Jahre in Sonderfällen behandeln. if d.endswith('-W0') and r.day == 7: raise ValueError('Invalid date string, No week 0 in {}'.format(r.year))
Martijn Pieters

1
@darda: Python 3.6 unterstützt bereits ISO 8601-Wochendefinitionen, Verwendung %G(Jahr für den größten Teil der Woche) und %Vin diesem Fall.
Martijn Pieters

26

Um die anderen Antworten zu vervollständigen: Wenn Sie ISO- Wochennummern verwenden, ist diese Zeichenfolge geeignet (um den Montag einer bestimmten ISO-Wochennummer abzurufen):

import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)

%G, %V, %uSind ISO Äquivalenten %Y, %W, %w, so dass diese Ausgänge:

2013-06-24 00:00:00

Verfügbar in Python 3.6+; aus docs .


13

In Python 3.8 gibt es das Praktische datetime.date.fromisocalendar:

>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1)  # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)

In älteren Python-Versionen (3.7-) kann die Berechnung die Informationen aus verwenden datetime.date.isocalendar, um die ISO8601-kompatiblen Wochenwochen zu ermitteln:

from datetime import date, timedelta

def monday_of_calenderweek(year, week):
    first = date(year, 1, 1)
    base = 1 if first.isocalendar()[1] == 1 else 8
    return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))

Beides funktioniert auch mit datetime.datetime.


6
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res

Das Hinzufügen von 1 als Wochentag ergibt den genauen aktuellen Wochenstart. Durch Hinzufügen von timedelta (Tage = 6) erhalten Sie das Wochenende.

datetime.datetime(2018, 7, 23)

@Senthikumar C, das wie unten sein sollteres = datetime.datetime.strptime("2018 W30 w1", "%Y W%W w%w")
MD Alauddin Al-Amin

1

Wenn Sie die jährliche Anzahl von Wochen haben, addieren Sie einfach die Anzahl von Wochen zum ersten Tag des Jahres.

>>> import datetime
>>> from dateutil.relativedelta import relativedelta

>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)

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.