PythonでDateTimeオブジェクトの時間を切り捨てる方法は?


251

Python datetimeオブジェクトを切り捨てる上品な方法は何ですか?

この特定のケースでは、当日。したがって、基本的には、時間、分、秒、マイクロ秒を0に設定します。

出力も文字列ではなく、datetimeオブジェクトにする必要があります。

回答:


376

これはあなたが探しているものだと思います...

>>> 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)

しかし、本当に物事の時間的な側面を気にしないのなら、あなたは本当にdateオブジェクトだけを渡すべきです...

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

14
タイムゾーン対応のdtでは、datetime.datetime(dt.year、dt.month、dt.day)はtzinfo情報を破棄します。
ʇsәɹoɈ

1
あなただけの今日を探しているなら、あなたもdatetime.date.today()行うことができます
galarant

4
なお、パイソン2とPython 3 のドキュメントことは、両方の状態replace()メソッドが返す正しい呪文があろうように、DateTimeオブジェクトを:dt = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
ブラッドM

3
OP datetimedateオブジェクトではなくを望んでいます(dt.date()呼び出しを使用して取得できます(明示的なコンストラクターを使用する必要はありません))。.replace()場合、このメソッドは失敗する可能性がありdatetime、ナノ秒のサポートを追加します代わりに使用datetime.combine()できます
jfs 2015年

@chriswなぜそれを一行に書きませんdatetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)か?
2018年

66

時間を気にしdateないdatetime場合はaを使用します。

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

次のように日時を更新できます。

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

9
タイムゾーン対応の日時では、now.date()はtzinfo情報を破棄します。
ʇsәɹoɈ


34

4年後:回避する別の方法 replace

私は4年前から受け入れられた答えが機能することを知っていますが、これは使用するより少し軽いようですreplace

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

ノート

  • datetime時間プロパティをコンストラクタに渡さずにオブジェクトを作成すると、真夜中に取得します。
  • 他の人が指摘したように、これは後でtimedeltaで使用するためにdatetimeオブジェクトが必要であることを想定しています。
  • もちろん、これを最初の行に置き換えることができます。 dt = datetime.datetime.now()

20

日時オブジェクトは不変であるため、切り捨てることはできません。

ただし、以下は、元の日付またはtzinfoを破棄せずに、0時間、分、秒、マイクロ秒のフィールドで新しい日時を作成する1つの方法です。

newdatetime = now.replace(hour=0, minute=0, second=0, microsecond=0)

1
+1:replaceオプションを最初にすると、それはおそらく彼らが望んでいることだからです。
S.Lott、2011年

使用するのは誤りtzinfo=now.tzinfoです。tzinfo深夜にはで異なるオフセット例えば、UTCかもしれ2012-04-01 00:09:00オーストラリア/メルボルンタイムゾーンで(午前9時)であるAEST+10:00が、それはあるAEDT+11:002012-04-01 00:00:00(深夜) -その日の終わりのDST遷移があります。あなたはpytzそれを修正するためにモジュールを使うことができます、私の答えを見てください。
jfs 2015年

13

特定の日時オブジェクトに対応する真夜中を取得するには、datetime.combine()methodを使用できます。

>>> 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)

メソッドと比較し.replace()利点は、モジュールがナノ秒のサポートを導入してdatetime.combine()も、ベースのソリューションが引き続き機能することです。datetime

tzinfo必要に応じて保存できますが、UTCオフセットは真夜中に異なる場合があります。たとえば、DSTの移行が原因で、単純な解決策(tzinfo時間属性の設定)が失敗する場合があります。特定のタイムゾーンの「真夜中」のUTC時刻を取得するにはどうすればよいですかをご覧ください


7

そのためにパンダを使用できます(ただし、そのタスクのオーバーヘッドになる可能性があります)。通常の数値や、offset-aliasesからのパンダの頻度のように、roundfloor、およびceilを使用できます

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
"""

4

datetime.strftimeを使用して、日、月、年を抽出できます...

例:

from datetime import datetime
d = datetime.today()

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

出力(今日):

29-2011

日を取得するだけの場合は、次のようなday属性を使用できます。

from datetime import datetime
d = datetime.today()

# Retrieves the day
print d.day

Ouput(今日):

29

まあ、私はすでにこれを1回実行しているので、datetimeオブジェクトに時分などのフィールドを設定するよりもオーバーヘッドが増える可能性があります。
カイル・ブラント

ふむ、あなたが実際にだけ行うことができ、それを行うには奇妙な方法のthats d.dayなど
ヨッヘンRitzel

3

日付を操作するために使用される素晴らしいライブラリがあります: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')

日付時刻値を取り戻したい場合:

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

DSTの移行などにより、結果の時刻に異なるutcオフセットがある場合、誤った時刻(誤ったutcオフセット)が返されます。特定のタイムゾーンの「真夜中」のUTC時刻を取得するにはどうすればよいですかを
jfs 2015年


1

これを処理するモジュールdatetime_truncateがあります。datetime.replaceを呼び出すだけです。


1

6年後...私はこの投稿を見つけました、そしてもっと派手なアプローチが好きでした:

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]')

乾杯


1
>>> import datetime
>>> dt = datetime.datetime.now()
>>> datetime.datetime.date(dt)
datetime.date(2019, 4, 2)

1

そのまま使えます

datetime.date.today()

それは軽く、あなたが望むものを正確に返します。


同じ答えが以前に出されました、新しいものは何もありません。
slfan

@slfan申し訳ありませんが、ブラウザから「検索」を使用しても、あなたの名前の投稿は見つかりませんでした。
Bordotti

1
私ではなく、zx81による3年前。datetime.date.today()を検索します。答えが正しければ、もう一度答えるのではなく、賛成票を投じるべきです。
slfan


0

DateTimeタイプのSeriesを処理している場合、特にSeriesオブジェクトに多数の行がある場合、それらを切り捨てるより効率的な方法があります。

フロア機能が使えます

たとえば、それを数時間に切り捨てる場合:

日付の範囲を生成する

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

交換機能とフロア機能の実行時間を比較して確認できます。

%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

1行に収まるが、特にエレガントではない別の方法を次に示します。

dt = datetime.datetime.fromordinal(datetime.date.today().toordinal())
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.