web-dev-qa-db-fra.com

Comment tronquer l'heure d'un objet DateTime en Python?

Qu'est-ce qu'une méthode classique pour tronquer un objet datetime python?

Dans ce cas particulier, à la journée. Donc, régler les heures, les minutes, les secondes et les microsecondes sur 0.

Je voudrais que la sortie soit aussi un objet datetime, pas une chaîne.

210
Kyle Brandt

Je pense que c'est ce que vous cherchez ...

>>> import datetime
>>> dt = datetime.datetime.now()
>>> dt = dt.replace(hour=0, minute=0, second=0, microsecond=0) # Returns a copy
>>> dt
datetime.datetime(2011, 3, 29, 0, 0)

Mais si vous ne vous souciez pas vraiment de l'aspect temporel des choses, alors vous ne devriez vraiment faire que passer _ objets date ...

>>> d_truncated = datetime.date(dt.year, dt.month, dt.day)
>>> d_truncated
datetime.date(2011, 3, 29)
322
Chris W.

Utilisez un date pas un datetime si vous ne vous souciez pas de l'heure.

>>> now = datetime.now()
>>> now.date()
datetime.date(2011, 3, 29)

Vous pouvez mettre à jour un datetime comme ceci:

>>> now.replace(minute=0, hour=0, second=0, microsecond=0)
datetime.datetime(2011, 3, 29, 0, 0)
54
Jochen Ritzel

Quatre ans plus tard: une autre façon d'éviter replace

Je connais la réponse acceptée d'il y a quatre ans, mais cela semble un peu plus léger que d'utiliser replace:

dt = datetime.date.today()
dt = datetime.datetime(dt.year, dt.month, dt.day)

Notes

  • Lorsque vous créez un objet datetime sans transmettre de propriétés temporelles au constructeur, vous obtenez minuit.
  • Comme d'autres l'ont noté, cela suppose que vous souhaitiez un objet datetime pour une utilisation ultérieure avec timedeltas.
  • Vous pouvez bien entendu substituer ceci à la première ligne: dt = datetime.datetime.now()
26
zx81

Vous ne pouvez pas tronquer un objet datetime car il est immuable .

Cependant, il existe un moyen de construire une nouvelle date-heure avec des champs de 0 heure, minute, seconde et microsecondes, sans perdre la date ou tzinfo d'origine:

newdatetime = now.replace(hour=0, minute=0, second=0, microsecond=0)
20
ʇsәɹoɈ

Pour obtenir une valeur de minuit correspondant à un objet datetime donné, vous pouvez utiliser la méthode datetime.combine() :

>>> from datetime import datetime, time
>>> dt = datetime.utcnow()
>>> dt.date()
datetime.date(2015, 2, 3)
>>> datetime.combine(dt, time.min)
datetime.datetime(2015, 2, 3, 0, 0)

L'avantage par rapport à la méthode .replace() est que la solution basée sur datetime.combine() continuera à fonctionner même si le module datetime présente le support nanosecondes .

tzinfo peut être conservé si nécessaire, mais le décalage utc peut être différent à minuit, par exemple en raison d'une transition DST et, par conséquent, une solution naïve (définition de l'attribut tzinfo time) peut échouer. Voir Comment puis-je obtenir l'heure UTC "minuit" pour un fuseau horaire donné?

12
jfs

Vous pouvez utiliser pandas pour cela (bien que cela puisse être une surcharge pour cette tâche). Vous pouvez utiliser round , floor et ceil comme pour les nombres habituels et toute pandas fréquence de offset- alias :

import pandas as pd
import datetime as dt

now = dt.datetime.now()
pd_now = pd.Timestamp(now)

freq = '1d'
pd_round = pd_now.round(freq)
dt_round = pd_round.to_pydatetime()

print(now)
print(dt_round)

"""
2018-06-15 09:33:44.102292
2018-06-15 00:00:00
"""
7
Anton Protopopov

Vous pouvez utiliser datetime.strftime pour extraire le jour, le mois, l'année ...

Exemple :

from datetime import datetime
d = datetime.today()

# Retrieves the day and the year
print d.strftime("%d-%Y")

Sortie (pour aujourd'hui):

29-2011

Si vous voulez seulement récupérer le jour, vous pouvez utiliser un attribut de jour comme:

from datetime import datetime
d = datetime.today()

# Retrieves the day
print d.day

Ouput (pour aujourd'hui):

29
4
Sandro Munda

Il existe une grande bibliothèque utilisée pour manipuler les dates: Delorean

import datetime
from delorean import Delorean
now = datetime.datetime.now()
d = Delorean(now, timezone='US/Pacific)

>>> now    
datetime.datetime(2015, 3, 26, 19, 46, 40, 525703)

>>> d.truncate('second')
Delorean(datetime=2015-03-26 19:46:40-07:00, timezone=US/Pacific)

>>> d.truncate('minute')
Delorean(datetime=2015-03-26 19:46:00-07:00, timezone=US/Pacific)

>>> d.truncate('hour')
Delorean(datetime=2015-03-26 19:00:00-07:00, timezone=US/Pacific)

>>> d.truncate('day')
Delorean(datetime=2015-03-26 00:00:00-07:00, timezone=US/Pacific)

>>> d.truncate('month')
Delorean(datetime=2015-03-01 00:00:00-07:00, timezone=US/Pacific)

>>> d.truncate('year')
Delorean(datetime=2015-01-01 00:00:00-07:00, timezone=US/Pacific)

et si vous voulez récupérer la valeur datetime:

>>> d.truncate('year').datetime
datetime.datetime(2015, 1, 1, 0, 0, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)
3
DmitrySemenov

Vous pouvez utiliser uniquement datetime.date.today (), il est léger et renvoyer exactement ce que vous voulez

1
Bordotti

Il existe un module datetime_truncate qui gère cela pour vous. Il appelle simplement datetime.replace.

1
kyrre

6 ans plus tard ... J'ai trouvé ce post et j'ai aimé plus l'aprépa numpy:

import numpy as np
dates_array = np.array(['2013-01-01', '2013-01-15', '2013-01-30']).astype('datetime64[ns]')
truncated_dates = dates_array.astype('datetime64[D]')

à votre santé

0
Matias Thayer
>>> import datetime
>>> dt = datetime.datetime.now()
>>> datetime.datetime.date(dt)
datetime.date(2019, 4, 2)
0
markling

Si vous traitez avec une série du type DateTime, il existe un moyen plus efficace de les tronquer, notamment lorsque l'objet Series comporte beaucoup de lignes.

Vous pouvez utiliser la fonction floor

Par exemple, si vous voulez le tronquer en heures:

Générer une plage de dates

times = pd.Series(pd.date_range(start='1/1/2018 04:00:00', end='1/1/2018 22:00:00', freq='s'))

Nous pouvons le vérifier en comparant le temps d'exécution entre les fonctions de remplacement et d'étage.

%timeit times.apply(lambda x : x.replace(minute=0, second=0, microsecond=0))
>>> 341 ms ± 18.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit times.dt.floor('h')
>>>>2.26 ms ± 451 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
0
Abraham Simpson