Hallo zusammen,
irgendwie kommt ich an folgendem Punkt nicht weiter:
Ich habe ein Datum (z.B. 15.06.2018) und davon muss ich jetzt z.B. 36 oder 40 Monate zurück gehen.
Hat jemand einen Vorschlag, wie man das am einfachsten in Python realisieren kann?
Vielen Dank im Voraus.
Datumsberechnung
-
- User
- Beiträge: 168
- Registriert: Montag 9. Mai 2016, 09:14
- Wohnort: Berlin
Hallo,
ich würde obige Aufgabe so erledigen:
Die Lösung fühlt sich aber nicht gut an.
Darf man Funktionen in Funktionen definieren?
ich würde obige Aufgabe so erledigen:
Die Lösung fühlt sich aber nicht gut an.
Darf man Funktionen in Funktionen definieren?
Code: Alles auswählen
from datetime import datetime, timedelta
from itertools import count
def subtract_month(date, months=1):
def february(year):
return 29 if year%4==0 and not year%400==0 else 28
def days_per_month(date):
return {"1":31, "2":february(date.year), "3":31, "4":30, "5":31,
"6":30, "7":31, "8":31, "9":30, "10":31, "11":30, "12":31}
for i in count(1):
if i > months:
break
period = days_per_month(date)[str(date.month)]
date = date - timedelta(days=period)
return date
if __name__ == '__main__':
date = datetime(2020,3,29,6,30)
for i in range(1,13):
print subtract_month(date, i)
'''
2020-02-27 06:30:00
2020-01-29 06:30:00
2019-12-29 06:30:00
2019-11-28 06:30:00
2019-10-29 06:30:00
2019-09-28 06:30:00
2019-08-29 06:30:00
2019-07-29 06:30:00
2019-06-28 06:30:00
2019-05-29 06:30:00
2019-04-28 06:30:00
2019-03-29 06:30:00
'''
@sebastian0202: Deine Schaltjahrberechnung ist falsch. Ansonsten gibt es das alles schon im calendar-Modul. Ein `count` mit einem break, falls der Wert größer als eine bestimmte Grenze wird, ist eigentlich ein `range`. Warum benutzt Du für die Monatsnummer einen String? Wäre es nicht einfacher, Monat und Jahr separat auszurechnen und den Tag aus dem ursprünglichen Datum zu nehmen?
Code: Alles auswählen
>>> import datetime
>>> date = datetime.datetime.now()
>>> y, m = divmod(date.year*12+date.month - 21, 12)
>>> date.replace(year=y, month=m)
datetime.datetime(2016, 6, 19, 11, 11, 48, 413895)
@Sirius3: Man kann den Tag nicht aus dem ursprünglichen Datum nehmen, weil nicht alle Tage in allen Monaten existieren:
@reneschmidt: Ob man jetzt mit `replace` die Jahre und Monate ändert oder `timedelta`s (bzw. Tage) aufsummiert, hängt so ein bisschen davon ab, was „ein Monat“ für dich ist. Was ist ein Monat vor dem 29. März? Der 28./29. Februar? 31 Tage früher? Vier Wochen früher? Was ist mit Sommer- und Winterzeit? Schaltsekunden? Diese Fragen müsstest du (für dich) beantworten.
Code: Alles auswählen
In [18]: date = datetime.datetime(2018, 3, 31)
In [19]: date.replace(month=2)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-19-6ef8040186bb> in <module>()
----> 1 date.replace(month=2)
ValueError: day is out of range for month
-
- User
- Beiträge: 168
- Registriert: Montag 9. Mai 2016, 09:14
- Wohnort: Berlin
Ja, die Schaltjahrberechnung ist falsch. Habe die Sache mit den 100 Jahren unter den Tisch fallen lassen.
Hab jetzt mit 'Calendar' einen kürzeren Code. Der wird aber für viele Durchläufe sicher uneffizient sein.
Hab jetzt mit 'Calendar' einen kürzeren Code. Der wird aber für viele Durchläufe sicher uneffizient sein.
Code: Alles auswählen
from calendar import monthrange
from datetime import datetime, timedelta
...
def schaltjahr(jahr):
return 28 if jahr%100==0 and not jahr%400==0 else (29 if jahr%4==0 else 28)
...
def subtract_month(date, months=1):
for _ in range(months):
date -= timedelta (days=monthrange(date.year,date.month)[1])
return date
if __name__ == '__main__':
date = datetime(2018,03,31)
print subtract_month(date, 37)
'''
2015-02-28 00:00:00
'''