2009-09-10 8 views
60

Oczywiście mogę napisać to sam, ale zanim przejdę do odrodzenia koła, czy istnieje funkcja, która już to robi?Czy istnieje funkcja Python do określenia, w którym kwartale roku znajduje się data?

+13

Pytanie BARDZO uzasadniają chociaż wczesne odpowiedzi wydają się odrobinę lekceważąco („tylko kwestia”, „wydaje się dość proste "): dwie z odpowiedzi (w tym jedna z nich!) są strasznie błędne, pokazując, że to wcale nie jest takie proste lub" po prostu "... –

+0

Jestem pewien, że wróci i naprawi to –

Odpowiedz

105

W przypadku instancji z datetime.date, (x.month-1)//3 otrzymasz kwartał (0 za pierwszy kwartał, 1 za drugi kwartał, itd. - dodaj 1, jeśli musisz liczyć od 1 zamiast ;-).


Początkowo dwie odpowiedzi, należy pomnożyć upvoted a nawet pierwotnie zaakceptowanych (zarówno obecnie usunięte) były buggy - nie robi -1 przed podziałem, a następnie dzieląc przez 4 zamiast 3. Ponieważ .month idzie 1 do 12, jest to łatwe do sprawdzenia na własne oczy jak formuła ma rację:

for m in range(1, 13): 
    print m//4 + 1, 
print 

daje 1 1 1 2 2 2 2 3 3 3 3 4 - dwa na cztery ćwiartki miesiąc i jeden-jeden miesiąc (EEP).

for m in range(1, 13): 
    print (m-1)//3 + 1, 
print 

daje 1 1 1 2 2 2 3 3 3 4 4 4 - teraz nie wygląda to bardzo korzystne dla ciebie? -)

Dowodzi to, że pytanie jest dobrze uzasadnione, myślę ;-).

Nie sądzę, że moduł datetime powinien koniecznie mieć wszystkie możliwe funkcje kalendarza, ale wiem, że utrzymuję (dobrze przetestowany ;-) datetools moduł do korzystania z moich (i innych) projektów w pracy , który ma wiele małych funkcji do wykonywania wszystkich obliczeń obliczeniowych - niektóre są złożone, niektóre proste, ale nie ma powodu, aby wykonywać pracę w kółko (nawet prosta praca) lub ryzyko błędów w takich obliczeniach ;-).

+1

Dzięki Alex. Dlatego powinna istnieć funkcja. Zobacz, ilu ludzi popełniło błąd. –

+0

Myślę, że udowodniłeś swoją rację. Nie trzeba zanieczyszczać całej strony powtarzającymi się komentarzami. –

+1

@Jason, tak, dokładnie - dlatego wznowiłem twoje pytanie po tym, jak zobaczyłem inne błędne odpowiedzi (obecnie usunięte), mimo że ktoś inny zdawał się odrzucać, aby policzyć mój upstream, no cóż. –

0

hmmm więc obliczenia mogą się nie udać, tutaj jest lepsza wersja (tylko przez wzgląd na niego)

first, second, third, fourth=1,2,3,4# you can make strings if you wish :) 

quarterMap = {} 
quarterMap.update(dict(zip((1,2,3),(first,)*3))) 
quarterMap.update(dict(zip((4,5,6),(second,)*3))) 
quarterMap.update(dict(zip((7,8,9),(third,)*3))) 
quarterMap.update(dict(zip((10,11,12),(fourth,)*3))) 

print quarterMap[6] 
+2

obliczenia mogą pójść źle, jeśli matematyka jest błędna. –

+0

@RussBradberry w tym przypadku może masz rację, ale czasami czytelność i jawność zlicza i prowadzi do mniej błędów, zamiast krótkich obliczeń –

+1

@RussBradberry również zobaczyć usunięte odpowiedzi i komentarze na ten temat, zobacz proste obliczenia mogą być trudne na dobre programiści też i trudno jest zobaczyć poprawność, z wyjątkiem testowania jej, w moim rozwiązaniu można zobaczyć i być pewnym, że zadziała –

16

chciałbym zaproponować inną prawdopodobnie czystsze rozwiązanie. Jeśli X jest instancją datetime.datetime.now(), wtedy czwarta jest:

import math 
Q=math.ceil(X.month/3.) 

ceil musi być importowane z modułu matematyki, gdyż nie mogą być dostępne bezpośrednio.

+1

Najlepszy jak dotąd. Dzięki za tonę! – curlyreggie

+3

Prawdopodobnie powinien zawijać to w int() – Pablojim

+0

Jak sugeruje @garbanzio odpowiedź. Musiałem umieścić argument miesiąca za pomocą funkcji float, aby uruchomić to działanie '' 'math.ceil (float (4)/3) = 2.0''' podczas gdy' '' math.ceil (4/3) = 1.0' '' –

1

To stare pytanie, ale wciąż warte dyskusji.

Oto moje rozwiązanie, korzystając z doskonałego modułu dateutil.

from dateutil import rrule,relativedelta 

    year = this_date.year 
    quarters = rrule.rrule(rrule.MONTHLY, 
         bymonth=(1,4,7,10), 
         bysetpos=-1, 
         dtstart=datetime.datetime(year,1,1), 
         count=8) 

    first_day = quarters.before(this_date) 
    last_day = (quarters.after(this_date) 
       -relativedelta.relativedelta(days=1) 

Więc first_day to pierwszy dzień kwartału, a last_day jest ostatni dzień kwartału (obliczone poprzez znalezienie pierwszego dnia następnego kwartału, minus jeden dzień).

1

jeśli m jest liczba miesięcy ...

import math 
math.ceil(float(m)/3) 
17

IF już używasz pandas, to całkiem proste.

import datetime as dt 
import pandas as pd 

quarter = pd.Timestamp(dt.date(2016, 2, 29)).quarter 
assert quarter == 1 

Jeśli masz kolumny w dataframe date, można łatwo utworzyć nowy quarter kolumna:

df['quarter'] = df['date'].dt.quarter 
3

Dla każdego, kto próbuje uzyskać kwartał fiskalny roku , które mogą się różnić od kalendarz rok, napisałem moduł Python, aby to zrobić.

Instalacja jest prosta. Wystarczy uruchomić:

$ pip install fiscalyear 

nie ma żadnych zależności, a fiscalyear powinien pracować zarówno Python 2 i 3.

Jest to w zasadzie owinięcie wokół wbudowany moduł datetime, więc wszelkie datetime poleceń jesteś już zaznajomiony z będzie działać. Oto demo:

>>> from fiscalyear import * 
>>> a = FiscalDate.today() 
>>> a 
FiscalDate(2017, 5, 6) 
>>> a.fiscal_year 
2017 
>>> a.quarter 
3 
>>> b = FiscalYear(2017) 
>>> b.start 
FiscalDateTime(2016, 10, 1, 0, 0) 
>>> b.end 
FiscalDateTime(2017, 9, 30, 23, 59, 59) 
>>> b.q3 
FiscalQuarter(2017, 3) 
>>> b.q3.start 
FiscalDateTime(2017, 4, 1, 0, 0) 
>>> b.q3.end 
FiscalDateTime(2017, 6, 30, 23, 59, 59) 

fiscalyear jest utrzymywana na GitHub i PyPI. Dokumentację można znaleźć pod adresem Read the Docs. Jeśli szukasz funkcji, których jeszcze nie ma, daj mi znać!

0

Oto gadatliwy, ale również czytelne rozwiązanie, które będzie pracować dla datetime i data przypadkach

def get_quarter(date): 
    for months, quarter in [ 
     ([1, 2, 3], 1), 
     ([4, 5, 6], 2), 
     ([7, 8, 9], 3), 
     ([10, 11, 12], 4) 
    ]: 
     if date.month in months: 
      return quarter 
Powiązane problemy