Suchen Sie das Datum für den ersten Montag nach einem bestimmten Datum

Antworten:

129
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)
Phihag
quelle
8
Sie könnten auch tun ((day - today) + 7) % 7, um den Tag diff
jstaab
2
@jstaab Oder vereinfachen zu (day - today) % 7. Negative Ergebnisse bei der Subtraktion werden wie erwartet behandelt. Zum Beispiel -1 % 7gibt 6.
Code-Apprentice
52

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)
user1034533
quelle
Diese Antwort kam zu spät, um Stimmen zu sammeln, aber es ist mein Favorit.
ASalazar
2
Sauber, braucht aber zwei Erinnerungen. 1. Dies gibt das gleiche Datum zurück, wenn die Wochentage für Tag und Datum übereinstimmen. Wochentag () 2. Tag sollte im Format Wochentag () sein, nicht isoweekday ()
bhtabor
7
Funktioniert, aber das +7ist unnötig, wenn Sie nehmen %7. Ändern Sie es zu:onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday())%7)
Zach Siegel
1
Da Pythons datetimePaket eine dateKlasse enthält (die ich persönlich häufig importiere), behandle ich sie dateals 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.dateVariable ist. (Auch in Javascript dateist ein Standardtyp, und Sie sollten keine Variablen benennen date.)
Zach Siegel
1
So beheben Sie die Probleme von bhtabor: 1. Um sicherzustellen, dass der Montag der nächsten Woche zurückgegeben wird, auch wenn es datesich 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 dayein Wert 1..7 statt 0..6 für Monday..Sunday sein sollte.
ElRudi
26

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 datetimeTyp Montag als 0, ..., Sonntag als meldet 6.

Dolch
quelle
Interessant, dass - wenn ich versuche, den kommenden Sonntag nach datetime (2013, 1, 1) mit "datetime (2013, 1, 1) + timedelta (days = (7 - datetime (2013, 1, 1) .weekday () zu finden. )) ", Ich erhalte" datetime.datetime (2013, 1, 7, 0, 0) ", was ein Montag ist.
Fixxxer
2
@fixxxer - Wie es in der Antwort heißt: Der Code verwendet einige Eigenschaften der datetimeAPI auf eine Weise, die nur funktioniert, wenn Sie nach Montag suchen. Der von bereitgestellte Code phihagist allgemeiner und kann jeden kommenden Wochentag finden.
Dirk
Denken Sie, dass die Verwendung von 6 anstelle von 7 in timedelta hilfreich ist?
Fixxxer
@fixxxer: Warum verwenden Sie nicht einfach den von bereitgestellten Code 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- datetimeAPI "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.
Dirk
@fixxxer: um den nächsten Sonntag mit "süßem" Code zu finden: d + timedelta(6 - d.weekday() or 13 - d.weekday())(entspricht dem Code von Phihag, wenn Sunday == 6es der letzte Tag der Woche ist)
jfs
6

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-15ein 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 ;-)

Rasereikryger
quelle
5

Sie können mit dem Hinzufügen eines Tagesobjekts beginnen und am Montag aufhören.

>>> d = datetime.date(2011, 7, 2)
>>> while d.weekday() != 0: #0 for monday
...     d += datetime.timedelta(days=1)
... 
>>> d
datetime.date(2011, 7, 4)
utdemir
quelle
4

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)
Edan Shalom
quelle
3

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

Christopher Johnson
quelle
2
import datetime

d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
    d += datetime.timedelta(1)
Jonathan
quelle
0
weekday = 0 ## Monday
dt = datetime.datetime.now().replace(hour=0, minute=0, second=0) ## or any specific date
days_remaining = (weekday - dt.weekday() - 1) % 7 + 1
next_dt = dt + datetime.timedelta(days_remaining)
saeedgnu
quelle
-1

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

rabin utam
quelle
-1

über Listenverständnis?

from datetime import *
[datetime.today()+timedelta(days=x) for x in range(0,7) if (datetime.today()+timedelta(days=x)).weekday() % 7 == 0]

(0 at the end is for next monday, returns current date when run on monday)
jose
quelle