Korzystam z modułu Python z datetime. Chcę obliczyć datę 6 miesięcy od bieżącej daty. Czy ktoś mógłby mi w tym pomóc?
Powodem, dla którego chcę wygenerować datę 6 miesięcy od bieżącej daty, jest wygenerowanie daty przeglądu . Jeśli użytkownik wprowadzi dane do systemu, data przeglądu będzie wynosić 6 miesięcy od daty ich wprowadzenia.
6
go, ze wsparciem dla przechodzenia w ciągu roku (i cofania miesiąca do1
), jeśli przejdziemy do grudnia. Zdarza się to dokładnie tak, jakrelativedelta
robi to i co robi każdy język programowania z obsługą tego rodzaju koncepcji.date(2015, 3, 31) + relativedelta(months = 6)
dajedatetime.date(2015, 9, 30)
. Perl:DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6)
daje2000-10-01T00:00:00
. Php:date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M'))
daje 2000-10-01. Wybierz swoją truciznę.Odpowiedzi:
Uważam, że to rozwiązanie jest dobre. (Używa rozszerzenia Python-dateutil )
Zaletą tego podejścia jest to, że rozwiązuje problemy z 28, 30, 31 dniami itp. Staje się to bardzo przydatne w obsłudze reguł biznesowych i scenariuszy (np. Generowanie faktur itp.)
źródło
relativedelta
funkcja przyjmuje równieżmonth
jako argument, który w zasadzie zastępuje / ustawia / naprawia miesiąc w podanym terminie, co jest zupełnie inne niż dodawanie kolejnych miesięcy. Tylko ostrzeżenie dla ludzi zastanawiających się, czy funkcja jest zepsuta, ponieważ zapomnieli o dodatkowej liczbie za kilka miesięcy .datetime
jest domyślnie zapakowana . Właściwie założyłem, że mogę przekazać „miesiące” na timedelta.To zależy od tego, co masz na myśli przez 6 miesięcy od bieżącej daty.
Używając naturalnych miesięcy:
Stosując definicję bankiera, 6 * 30:
źródło
(day, month, year) = (day, (month+6)%12, year+(month+6)/12)
może się nie udać, ponieważ generuje niepoprawne daty, takie jak(31, 8, 2015)
->(31, 2, 2016)
W Pythonie 3.x możesz to zrobić w następujący sposób:
ale musisz zainstalować moduł python-dateutil :
źródło
pip install ...
from dateutil.relativedelta import relativedelta
. Używanieimport *
nie jest jednoznaczne.Na początku obliczeń z miesiąca na miesiąc:
źródło
Co rozumiesz przez „6 miesięcy”?
Czy 2009-02-13 + 6 miesięcy == 2009-08-13? A może 2009-02-13 + 6 * 30 dni?
Więcej informacji o mx.DateTime
źródło
Oto przykład,
dateutil.relativedelta
który uznałem za przydatny w iteracji przez ostatni rok, pomijając za każdym razem miesiąc do obecnej daty:Podobnie jak w przypadku innych odpowiedzi, musisz dowiedzieć się, co tak naprawdę rozumiesz przez „za 6 miesięcy”. Jeśli masz na myśli „dzisiejszy dzień miesiąca w miesiącu, który ma być sześć lat w przyszłości”, wówczas:
źródło
To rozwiązanie działa poprawnie w grudniu, czego większość odpowiedzi na tej stronie nie. Najpierw musisz przesunąć miesiące z podstawy 1 (tj. Jan = 1) na podstawę 0 (tj. Jan = 0) przed użyciem modułu (%) lub podziału na liczby całkowite (//), w przeciwnym razie listopad (11) plus 1 miesiąc daje 12 , co przy znalezieniu reszty (12% 12) daje 0.
(I nie sugeruj „(miesiąc% 12) + 1” lub październik + 1 = grudzień!)
Jednak ... To nie wyjaśnia problemu takiego jak 31 stycznia + jeden miesiąc. Wracamy więc do PO - co masz na myśli przez dodanie miesiąca? Jednym z rozwiązań jest wycofanie się, aż dojdziesz do ważnego dnia, biorąc pod uwagę, że większość ludzi przypuszcza, że ostatni dzień stycznia, plus jeden miesiąc, równa się ostatniemu lutowi. To też zadziała w przypadku ujemnych liczb miesięcy. Dowód:
źródło
Wiem, że trwało to 6 miesięcy, jednak odpowiedź wyświetla się w Google dla „dodawania miesięcy w pythonie”, jeśli dodajesz jeden miesiąc:
to policzy dni w bieżącym miesiącu i doda je do bieżącej daty, użycie 365/12 spowoduje, że reklama 1/12 roku może powodować problemy z krótkimi / długimi miesiącami, jeśli iteracja w ciągu tej daty.
źródło
Nie ma bezpośredniego sposobu na zrobienie tego z datetime Pythona.
Sprawdź typ relativedelta na python-dateutil . Pozwala określić deltę czasu w miesiącach.
źródło
Wystarczy użyć metody harmonogramu , aby wyodrębnić miesiące, dodać miesiące i zbudować nowy obiekt daty. Jeśli istnieje już taka metoda, nie wiem.
Interfejs API jest nieco niezdarny, ale działa jako przykład. Oczywiście nie zadziała również w przypadku takich przypadków, jak 31.01.2008 + 1 miesiąc. :)
źródło
new_month % 12
powinien być(new_month % 12) or 12
. W przeciwnym razie, jeśli spróbujesz tego w listopadzie, pojawi się błąd. :)Pakiet Dateutil ma implementację takiej funkcjonalności. Pamiętaj jednak, że będzie to naiwne , jak już zauważyli inni.
źródło
Używanie standardowych bibliotek Python, tj. Bez
dateutil
lub innych, i rozwiązywanie problemu „31 lutego”:Testowanie:
źródło
add_months(datetime.date(2018, 11, 30), 1)
zwrotydatetime.date(2019, 12, 30)
(rok powinien być 2018, a nie 2019). Lepiej więc użyj do tego dedykowanej, dobrze przetestowanej biblioteki! Jeśli naprawdę potrzebujesz tylko standardowych modułów bibliotecznych, zobacz moją odpowiedź na podobne pytanie .Mam lepszy sposób na rozwiązanie problemu „31 lutego”:
Myślę, że działa również z liczbami ujemnymi (aby odjąć miesiące), ale nie testowałem tego zbyt wiele.
źródło
Klasa QDate PyQt4 ma funkcję addmonths.
źródło
Co powiesz na to? Nie używasz innej biblioteki (
dateutil
) lubtimedelta
? Opierając się na odpowiedzi firmy Vartec , zrobiłem to i uważam, że to działa:Próbowałem używać
timedelta
, ale ponieważ liczy dni,365/2
lub6*356/12
nie zawsze przekłada się na 6 miesięcy, ale raczej 182 dni. na przykładUważam, że zwykle zakładamy, że 6 miesięcy od pewnego dnia wyląduje tego samego dnia miesiąca, ale 6 miesięcy później (tj.
2015-03-10
->2015-09-10
, Nie2015-09-08
)Mam nadzieję, że uznasz to za pomocne.
źródło
day + datetime.timedelta(6*365/12)
nie zawsze będzie działać, ponieważ niektóre lata mają 365 dni, a inne 366 dni.To nie odpowiada na konkretne pytanie (
datetime
tylko przy użyciu ), ale biorąc pod uwagę, że inni sugerowali użycie różnych modułów, tutaj jest rozwiązanie wykorzystującepandas
.Który działa zgodnie z oczekiwaniami w latach przestępnych
źródło
Zmodyfikowano AddMonths () do użytku w Zope i obsługi niepoprawnych numerów dni:
źródło
źródło
źródło
Zmodyfikowano odpowiedź Johannesa Wei w przypadku 1new_month = 121. To działa idealnie dla mnie. Miesiące mogą być dodatnie lub ujemne.
źródło
Jeszcze inne rozwiązanie - mam nadzieję, że komuś się spodoba:
To rozwiązanie nie działa przez 29, 30, 31 dni we wszystkich przypadkach, dlatego potrzebne jest bardziej niezawodne rozwiązanie (które nie jest już tak miłe :)):
źródło
Z tej odpowiedzi zobacz parsedatetime . Poniższy przykład kodu. Więcej informacji: test jednostkowy z wieloma przykładami konwersji w języku naturalnym -> RRRR-MM-DD i pozorne wyzwania / błędy konwersji w czasie parsowanym .
Powyższy kod generuje następujące dane z komputera MacOSX:
źródło
Oto przykład, który pozwala użytkownikowi zdecydować, jak zwrócić datę, w której dzień jest większy niż liczba dni w miesiącu.
źródło
biorąc pod uwagę, że zmienna data-godzina nazywa się data:
źródło
Ogólna funkcja, aby uzyskać następną datę po / przed x miesiącami.
źródło
Szybką sugestią jest Arrow
strzałka instalacji pip
źródło
Użyj modułu datetime w Pythonie, aby dodać sześciomiesięczną timedelta do datetime.today ().
http://docs.python.org/library/datetime.html
Będziesz oczywiście musiał rozwiązać kwestię podniesioną przez Johannesa Weiß-- co ma na myśli przez 6 miesięcy?
źródło
Właśnie to wymyśliłem. Przenosi prawidłową liczbę miesięcy i lat, ale ignoruje dni (to było to, czego potrzebowałem w mojej sytuacji).
źródło
Używam tej funkcji do zmiany roku i miesiąca, ale zachowuję dzień:
Powinieneś napisać:
źródło
Myślę, że bezpieczniej byłoby zrobić coś takiego zamiast ręcznie dodawać dni:
źródło