Python'da bir DateTime nesnesindeki saati nasıl kısaltabilirim?


251

Bir python datetime nesnesini kısaltmanın şık bir yolu nedir?

Bu özel durumda, güne. Temel olarak saat, dakika, saniye ve mikrosaniyeyi 0'a ayarlayın.

Ben de çıktı bir dize değil bir datetime nesnesi olmasını istiyorum.

Yanıtlar:


376

Bence bu aradığınız şey ...

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

Ama şeylerin zaman yönünü gerçekten umursamıyorsanız, gerçekten sadece datenesnelerin etrafından geçiyor olmalısınız ...

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

14
Saat dilimine duyarlı bir dt ile datetime.datetime (dt.year, dt.month, dt.day) tzinfo bilgilerini atar.
ɈsәɹoɈ

1
sadece bugün arıyorsanız, datetime.date.today ()
galarant

4
Python 2 ve python 3 belgelerinin her ikisinde de replace()yöntemin bir datetime nesnesi döndürdüğünü belirterek , doğru büyütme şöyle olur:dt = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
Brad M

3
OP datetime, datenesne değil ( dt.date()çağrı kullanarak alabileceğinizi (açık kurucuyu kullanmanıza gerek yok) istiyor ). .replace()Eğer yöntem başarısız olabilir datetimenanosaniye destek ekler . Bunun yerine kullanabilirsinizdatetime.combine() .
jfs

@chrisw Neden sadece bir satıra yazmıyorsunuz datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)?
3kstc

66

Eğer zaman umursamıyorum bir datedeğil kullanın datetime.

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

Aşağıdaki gibi bir tarih saatini güncelleyebilirsiniz:

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

9
Saat diliminde farkında olan tarihlerle, now.date () tzinfo bilgisini atar.
ɈsәɹoɈ

1
@ әɹsәɹoɈ: saat diliminde gece
jfs

35

Dört yıl sonra: başka bir yol, kaçınmak replace

Dört yıl önce kabul edilen cevabın işe yaradığını biliyorum, ancak bu kullanmaktan biraz daha hafif görünüyor replace:

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

notlar

  • Bir datetimeYapıcıya zaman özelliklerini iletmeden nesne , gece yarısı alırsınız.
  • Diğerlerinin belirttiği gibi, bu daha sonra timedeltas ile kullanmak için datetime nesnesi istediğinizi varsayar.
  • Tabii ki, bunu ilk satır için değiştirebilirsiniz: dt = datetime.datetime.now()

20

Değişmez olduğu için datetime nesnesini kesemezsiniz .

Bununla birlikte, orijinal tarihi veya tzinfo'yu atmadan, 0 saat, dakika, saniye ve mikrosaniye alanlarıyla yeni bir datetime oluşturmanın bir yolu:

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

1
+1: replaceseçeneği önce koyarsanız, muhtemelen istedikleri şey budur.
S.Lott

Kullanmak yanlış tzinfo=now.tzinfo. tzinfoGece yarısı farklı örneğin olabilir, utc de ofset 2012-04-01 00:09:00Avustralya / Melbourne saat diliminde (9 am) 'dir AEST+10:00ama o AEDT+11:00at 2012-04-01 00:00:00(gece yarısı) - O gün sonu DST geçiş yoktur. pytzDüzeltmek için modülü kullanabilirsiniz , cevabımı görün.
jfs

13

Belirli bir datetime nesnesine karşılık gelen bir gece yarısı almak için datetime.combine()yöntemi kullanabilirsiniz :

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

Kıyasla avantajı yöntemi olmasıdır tabanlı bir çözümdür çalışmaya devam edecektir bile modül tanıtır nanosaniye desteği.replace()datetime.combine()datetime .

tzinfogerekiyorsa korunabilir ancak utc ofseti gece yarısı farklı olabilir, örneğin bir DST geçişinden dolayı ve bu nedenle saf bir çözelti (ayar tzinfosüresi özelliği) başarısız olabilir. Bkz. Belirli bir saat dilimi için “gece yarısı” UTC saatini nasıl alırım?


7

Bunun için pandalar kullanabilirsiniz (bu görev için ek yük olmasına rağmen). Sen kullanabilirsiniz yuvarlak , zemin ve hücrelerinin, normal numaraları ve herhangi pandalar frekansı için gibi offset-takma adları :

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

Gün, ay, yıl ayıklamak için datetime.strftime komutunu kullanabilirsiniz ...

Misal :

from datetime import datetime
d = datetime.today()

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

Çıktı (bugün için):

29-2011

Yalnızca günü almak istiyorsanız, aşağıdaki gün özniteliğini kullanabilirsiniz:

from datetime import datetime
d = datetime.today()

# Retrieves the day
print d.day

Çıkış (bugün için):

29

Şey şey zaten zaten bir kez yapmak, bu yüzden datetime nesnesinde sadece hour min vb alanları ayarladıktan sonra daha fazla yükü olabilir.
Kyle Brandt

Heh, bunu yapmanın garip bir yolu, aslında sadece d.dayvb.
Yapabilirsiniz

3

Tarihleri ​​değiştirmek için kullanılan harika bir kütüphane var: 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')

ve datetime değerini geri almak istiyorsanız:

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

sonuç süresi farklı bir utc ofsetine sahipse yanlış zamanı (yanlış utc ofseti) döndürür, örn. Bkz. Belirli bir saat dilimi için “gece yarısı” UTC saatini nasıl alırım?
jfs


1

Bunu sizin için işleyen bir datetime_truncate modülü vardır. Sadece datetime.replace öğesini çağırır.


1

6 yıl sonra ... Bu yazıyı buldum ve numpy yaklaşımını daha çok sevdim:

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

şerefe


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

1

Sadece kullanabilirsiniz

datetime.date.today()

Hafiftir ve tam olarak istediğinizi döndürür.


Aynı cevap daha önce verilmişti, yeni bir şey yok.
slfan

Üzgünüz @slfan ama ben bile tarayıcıdan "arama" kullanarak, adınızla herhangi bir yazı görmedim.
Bordotti

1
Benim tarafımdan değil, zx81 tarafından 3 yıl önce. datetime.date.today () öğesini arayın. Bir cevap doğruysa, tekrar cevaplamamalısınız.
slfan


0

DateTime türü bir dizi ile uğraşıyorsanız, özellikle Series nesnesinin çok sayıda satırı olduğunda bunları kısaltmanın daha etkili bir yolu vardır.

Kullanabilirsiniz Zemin fonksiyonunu

Örneğin, saatlere kısaltmak istiyorsanız:

Bir dizi tarih oluşturun

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

Değiştirme ve zemin fonksiyonları arasındaki çalışma süresini karşılaştırarak kontrol edebiliriz.

%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

İşte bir hatta uyan ama özellikle zarif olmayan başka bir yol:

dt = datetime.datetime.fromordinal(datetime.date.today().toordinal())
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.