web-dev-qa-db-fra.com

Existe-t-il une fonction Python permettant de déterminer le trimestre de l'année dans lequel se trouve une date?

Bien sûr, je pourrais écrire cela moi-même, mais avant de réinventer la roue, existe-t-il une fonction qui le fait déjà?

72
Jason Christa

Avec une instance x de datetime.date , (x.month-1)//3 vous donnera le trimestre (0 pour le premier trimestre, 1 pour le deuxième trimestre, etc. - ajoutez 1 si vous devez compter à partir de 1 à la place ;-).


À l’origine, deux réponses, multipliées par vote positif et même acceptées à l’origine (les deux actuellement supprimées), posaient problème, ne faisant pas le -1 avant la division, et divisant par 4 au lieu de 3. Étant donné que .month passe de 1 à 12, il est facile de vérifier par vous-même. la formule est juste:

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

donne 1 1 1 2 2 2 2 3 3 3 3 4 - deux trimestres de quatre mois et un trimestre unique (eep).

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

donne 1 1 1 2 2 2 3 3 3 4 4 4 - cela ne vous semble-t-il pas vraiment préférable? -)

Cela prouve que la question est bien justifiée, je pense ;-).

Je ne pense pas que le module datetime devrait nécessairement avoir toutes les fonctions utiles du calendrier, mais je sais que je maintiens un module (bien testé ;-) datetools pour l'utilisation de mes projets (et des autres) au travail, qui comporte de nombreuses petites fonctions pour effectuer tous ces calculs de calendriers - certaines sont complexes, d'autres simples, mais il n'y a aucune raison d'effectuer le travail encore et encore (même un travail simple) ou de risquer des erreurs dans de tels calculs ;-).

125
Alex Martelli

SIvous utilisez déjà pandas, c'est assez simple.

import datetime as dt
import pandas as pd

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

Si vous avez une colonne date dans une structure de données, vous pouvez facilement créer une nouvelle colonne quarter:

df['quarter'] = df['date'].dt.quarter
27
chishaku

Je suggérerais une autre solution sans doute plus propre. Si X est une instance datetime.datetime.now(), alors le trimestre est:

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

ceil doit être importé du module mathématique car il est impossible d'y accéder directement. 

22
Jonathan Rocher

Pour ceux qui essaient d'obtenir le trimestre de l'année fiscale, qui peut être différent de l'année calendar, j'ai écrit un module Python dans ce but.

L'installation est simple. Il suffit de courir:

$ pip install fiscalyear

Il n'y a pas de dépendances et fiscalyear devrait fonctionner à la fois pour Python 2 et 3.

Il s'agit essentiellement d'un wrapper autour du module datetime intégré, afin que toutes les commandes datetime que vous connaissez déjà fonctionnent. Voici une démo:

>>> 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 est hébergé sur GitHub et PyPI . La documentation peut être trouvée à Lisez la documentation . Si vous recherchez des fonctionnalités dont il ne dispose pas actuellement, faites le moi savoir!

5
Adam Stewart

si m est le numéro du mois ...

import math
math.ceil(float(m) / 3)
2
garbanzio

C’est une vieille question qui mérite d’être discutée.

Voici ma solution, en utilisant l'excellent module 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)

Donc, first_day est le premier jour du trimestre et last_day est le dernier jour du trimestre (calculé en recherchant le premier jour du trimestre suivant, moins un jour).

1
MikeHoss

Pour ceux qui recherchent des données trimestrielles d’année financière, En utilisant des pandas,

import datetime
today_date = datetime.date.today()
quarter = pd.PeriodIndex(today_date, freq='Q-MAR').strftime('Q%q')

référence: indice de période pandas

1
Siddaram H

en utilisant des dictionnaires, vous pouvez retirer ceci en

def get_quarter(month):
    quarter_dictionary = {
        "Q1" : [1,2,3],
        "Q2" : [4,5,6],
        "Q3" : [7,8,9],
        "Q4" : [10,11,12]
    }

    for key,values in quarter_dictionary.items():
        for value in values:
            if value == month:
                return key

print(get_quarter(3))
0
Led

hmmm donc les calculs peuvent mal tourner, voici une meilleure version (juste pour le plaisir de le voir)

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]
0
Anurag Uniyal

Voici une solution commentée, mais également lisible, qui fonctionnera pour les instances de date/heure

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
0
igniteflow

Voici un exemple de fonction qui obtient un objet datetime.datetime et renvoie une chaîne unique pour chaque trimestre:

from datetime import datetime, timedelta

def get_quarter(d):
    return "Q%d_%d" % (math.ceil(d.month/3), d.year)

d = datetime.now()
print(d.strftime("%Y-%m-%d"), get_q(d))

d2 = d - timedelta(90)
print(d2.strftime("%Y-%m-%d"), get_q(d2))

d3 = d - timedelta(180 + 365)
print(d3.strftime("%Y-%m-%d"), get_q(d3))

Et le résultat est:

2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017
0
Roei Bahumi

Cette méthode fonctionne pour tout mappage:

month2quarter = {
        1:1,2:1,3:1,
        4:2,5:2,6:2,
        7:3,8:3,9:3,
        10:4,11:4,12:4,
    }.get

Nous venons de générer une fonction int->int

month2quarter(9) # returns 3

Cette méthode est également infaillible

month2quarter(-1) # returns None
month2quarter('July') # returns None
0
Uri Goren