Wie kann ich bei einem bestimmten Datum, z. B. dem 02.07.2011, das Datum des nächsten Montags (oder eines beliebigen Wochentags) nach diesem Datum ermitteln?
Antworten:
import datetime
def next_weekday(d, weekday):
days_ahead = weekday - d.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
return d + datetime.timedelta(days_ahead)
d = datetime.date(2011, 7, 2)
next_monday = next_weekday(d, 0) # 0 = Monday, 1=Tuesday, 2=Wednesday...
print(next_monday)
((day - today) + 7) % 7
, um den Tag diff
(day - today) % 7
. Negative Ergebnisse bei der Subtraktion werden wie erwartet behandelt. Zum Beispiel -1 % 7
gibt 6
.
Hier ist eine prägnante und generische Alternative zu den oben genannten leicht gewichtigen Antworten.
# Returns the date of the next given weekday after
# the given date. For example, the date of next Monday.
# NB: if it IS the day we're looking for, this returns 0.
# consider then doing onDay(foo, day + 1).
onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday()+7)%7)
+7
ist unnötig, wenn Sie nehmen %7
. Ändern Sie es zu:onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday())%7)
datetime
Paket eine date
Klasse enthält (die ich persönlich häufig importiere), behandle ich sie date
als Schlüsselwort und benenne keine Variablen date
. Ich würde dies ändern in: onDay = lambda dt, day: dt + datetime.timedelta(days=(day-dt.weekday())%7)
um mich daran zu erinnern, dass das Format der Eingabe eine Python- datetime.date
Variable ist. (Auch in Javascript date
ist ein Standardtyp, und Sie sollten keine Variablen benennen date
.)
date
sich um einen Montag handelt, wechseln Sie zu onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday()-1)%7+1)
. Weniger wichtig: 2. Änderung date.weekday()
zu , date.isoweekday()
wenn day
ein Wert 1..7 statt 0..6 für Monday..Sunday sein sollte.
Versuchen
>>> dt = datetime(2011, 7, 2)
>>> dt + timedelta(days=(7 - dt.weekday()))
datetime.datetime(2011, 7, 4, 0, 0)
Verwenden Sie, dass der nächste Montag 7 Tage nach dem Montag, 6 Tage nach dem Dienstag usw. ist, und verwenden Sie auch, dass Pythons datetime
Typ Montag als 0
, ..., Sonntag als meldet 6
.
datetime
API auf eine Weise, die nur funktioniert, wenn Sie nach Montag suchen. Der von bereitgestellte Code phihag
ist allgemeiner und kann jeden kommenden Wochentag finden.
phihag
? Es kann tun, was Sie wollen: next_weekday(datetime.date(2013,1,1), 6)
ist datetime.date(2013, 1, 6)
, ein Sonntag. Mein Code ist in (ab) unter Verwendung bestimmter Eigenschaften der Python- datetime
API "niedlich" und beantwortet nur den Teil "Finde den nächsten Montag " der Frage, aber nicht allgemein genug, um die Frage "Finde den nächsten xxx Tag" zu beantworten.
d + timedelta(6 - d.weekday() or 13 - d.weekday())
(entspricht dem Code von Phihag, wenn Sunday == 6
es der letzte Tag der Woche ist)
Dies ist ein Beispiel für Berechnungen innerhalb des Rings mod 7
.
import datetime
def next_day(given_date, weekday):
day_shift = (weekday - given_date.weekday()) % 7
return given_date + datetime.timedelta(days=day_shift)
now = datetime.date(2018, 4, 15) # sunday
names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday',
'saturday', 'sunday']
for weekday in range(7):
print(names[weekday], next_day(now, weekday))
wird drucken:
monday 2018-04-16
tuesday 2018-04-17
wednesday 2018-04-18
thursday 2018-04-19
friday 2018-04-20
saturday 2018-04-21
sunday 2018-04-15
Wie Sie sehen, gibt es Ihnen am nächsten Montag, Dienstag, Mittwoch, Donnerstag, Freitag und Samstag richtig. Und es wurde auch verstanden, dass dies 2018-04-15
ein Sonntag ist und der aktuelle Sonntag anstelle des nächsten zurückgegeben wird.
Ich bin mir sicher, dass Sie diese Antwort nach 7 Jahren sehr hilfreich finden werden ;-)
Eine andere einfache, elegante Lösung ist die Verwendung von Pandas-Offsets.
Ich finde es sehr hilfreich und robust, wenn ich mit Datteln spiele.
- Wenn Sie den ersten Sonntag möchten, ändern Sie einfach die Frequenz auf freq = 'W-SUN'.
- Wenn Sie ein paar nächste Sonntage möchten, ändern Sie die Offsets. Tag (Tage).
- Mit Pandas-Offsets können Sie Feiertage ignorieren, nur mit Geschäftstagen arbeiten und vieles mehr.
Sie können diese Methode auch einfach mit der Methode apply auf einen gesamten DataFrame anwenden.
# Getting the closest monday from a given date
closest_monday = pd.date_range(start=date, end=date + offsets.Day(6), freq='W-MON')[0]
# Adding a 'ClosestMonday' column with the closest monday for each row in a pandas df using apply
# Require you to have a 'Date' column in your df
def get_closest_monday(row):
return pd.date_range(start=row.Date, end=row.Date + offsets.Day(6), freq='W-MON')[0]
df['ClosestMonday'] = df.apply(lambda row: get_closest_monday(row), axis=1)
Eine andere Alternative verwendet Regel
from dateutil.rrule import rrule, WEEKLY, MO
from datetime import date
next_monday = rrule(freq=WEEKLY, dtstart=date.today(), byweekday=MO, count=1)[0]
Regel Dokumente: https://dateutil.readthedocs.io/en/stable/rrule.html
Dies wird den ersten nächsten Montag nach dem angegebenen Datum geben:
import datetime
def get_next_monday(year, month, day):
date0 = datetime.date(year, month, day)
next_monday = date0 + datetime.timedelta(7 - date0.weekday() or 7)
return next_monday
print get_next_monday(2011, 7, 2)
print get_next_monday(2015, 8, 31)
print get_next_monday(2015, 9, 1)
2011-07-04
2015-09-07
2015-09-07