Python'da, 'datetime` nesnesini saniyeye nasıl dönüştürürsünüz?


226

Basit soru için özür dilerim ... Python için yeniyim ... Aradım ve hiçbir şey işe yaramıyor.

Bir sürü datetime nesnesi var ve her biri için geçmişte sabit bir zamandan beri geçen saniye sayısını hesaplamak istiyorum (örneğin 1 Ocak 1970'den beri).

import datetime
t = datetime.datetime(2009, 10, 21, 0, 0)

Bu yalnızca farklı günleri olan tarihler arasında ayrım yapıyor gibi görünüyor:

t.toordinal()

Herhangi bir yardım çok takdir edilmektedir.



2
int(t.timestamp())
Dönemin ardından

Yanıtlar:


233

1 Ocak 1970 tarihli özel tarih için birden fazla seçenek vardır.

Diğer başlangıç ​​tarihleri ​​için, iki tarih arasındaki farkı saniye cinsinden almanız gerekir. İki tarihin çıkarılması timedelta, Python 2.7'den itibaren bir total_seconds()işlevi olan bir nesne verir .

>>> (t-datetime.datetime(1970,1,1)).total_seconds()
1256083200.0

Başlangıç ​​tarihi genellikle UTC olarak belirtilir, bu nedenle doğru sonuçlar için datetimebu formüle beslediğiniz UTC de olmalıdır. Eğer senin datetimezaten UTC değil bunu kullanmak ya da eklemek için önce dönüştürmek gerekir tzinfoofset uygun olan sınıf.

Yorumlarda belirtildiği gibi, eğer bir tzinfoekiniz datetimevarsa, başlangıç ​​tarihinde bir taneye ihtiyacınız olacak veya çıkarma başarısız olacaktır; yukarıdaki örnek için tzinfo=pytz.utcPython 2 veya tzinfo=timezone.utcPython 3 kullanıyorsanız ekleyeceğim .


1
Python şimdi beni uyarıyor: "TypeError: ofset-naif ve ofset-farkında tarihler çıkartılamıyor" Bunu düzeltmek için en iyi çözüm nedir?
Aaron Ash

2
@Charybdis, dene datetime.datetime(1970,1,1,tzinfo=pytz.utc).
Mark Ransom

9
Kullanmayı düşünün: datetime.datetime.utcfromtimestamp(0) Bunu 'çağı' kolayca elde etmek için kullandım. Dönemin tüm sistemlerde her zaman aynı olmadığını unutmayın.
DA

3
Buradaki zaman dilimlerine çok dikkat edin. Ben çıkışı o hangi vasıta UTC + 2 de değilim time.time()ve datetime.now() - datetime(1970, 1, 1)7200 saniye farklıdır. Oldukça kullanın (t - datetime.datetime.fromtimestamp(0)).total_seconds(). Do not kullanmak utcfromtimestamp(0)yerel saat diliminde bir datetime dönüştürmek istiyorsanız.
Carl

2
@DA: Python, POSIX dışı çağları desteklemez . Python'un çalıştığı tüm sistemler aynı dönemi kullanır: 1970-01-01 00:00:00 UTC
jfs

130

Unix zamanını almak için (1 Ocak 1970'den bu yana saniye):

>>> import datetime, time
>>> t = datetime.datetime(2011, 10, 21, 0, 0)
>>> time.mktime(t.timetuple())
1319148000.0

22
time.mktime kullanırken yerel saati ifade ettiği ve platforma bağlı olduğu için dikkatli olun
Shih-Wen Su

7
Gerçekten dikkatli olun. Beni kıçımı büyük bir zaman biraz
Arg

bunun tyerel bir saat olduğunu varsayar . Yerel saat dilimi için UTC farkı geçmişte farklı olabilir ve mktime()(C kitaplığı) belirli bir platformda geçmiş bir saat dilimi verilerine başarısız olabileceğinden daha fazla pytzerişemezse (tz veritabanına erişmenin taşınabilir bir yoludur). Ayrıca, yerel saat belirsiz olabilir, örneğin, DST geçişleri sırasında - belirsizleştirmek için ek bilgiye ihtiyacınız vardır , örneğin, bir günlük dosyasında art arda tarih / saat değerlerinin artması gerektiğini biliyorsanız
jfs

1
Bunu saniyenin kesirleri olan zamanlarda kullanırken dikkatli olun. time.mktime(datetime.datetime(2019, 8, 3, 4, 5, 6, 912000).timetuple())Sonuçlar 1564819506.0, sessizce milisaniye bırakarak, ama datetime.datetime(2019, 8, 3, 4, 5, 6, 912000).timestamp()içinde (Andrzej Pronobis' cevabı) sonuçları 1564819506.912, beklenen sonucu.
Alex

128

Python 3.3'ten başlayarak bu datetime.timestamp()yöntemle çok kolaylaşıyor . Bu elbette sadece 1970-01-01 UTC'den saniye sayısına ihtiyacınız varsa yararlı olacaktır.

from datetime import datetime
dt = datetime.today()  # Get timezone naive now
seconds = dt.timestamp()

Dönüş değeri, bir saniyenin kesirlerini temsil eden bir şamandıra olacaktır. Datetime saat dilimi naif ise (yukarıdaki örnekte olduğu gibi), datetime nesnesinin yerel saati temsil ettiği varsayılacaktır, yani bulunduğunuz konumdaki geçerli saatten 1970-01-01 UTC'ye kadar olan saniye sayısı olacaktır.


3
Bunu kim düşürdü, lütfen nedenini açıklayabilir misiniz?
Andrzej Pronobis

5
Sanırım, downvote, sorudaki python-2.7 etiketinden kaynaklanıyor (sadece bir tahmin).
jfs

3
Bu kabul edilen cevap / kabul edilen cevap buna göre güncellenmelidir.
DreamFlasher

11
Sanırım yükseltme zamanı;)
DreamFlasher

başka bir başlangıç ​​tarihinden bu mesafeyi hesaplamak mümkün mü? (
1970-01-01

29

Belki konu dışı: datetime'dan UNIX / POSIX zamanını almak ve geri dönüştürmek için:

>>> import datetime, time
>>> dt = datetime.datetime(2011, 10, 21, 0, 0)
>>> s = time.mktime(dt.timetuple())
>>> s
1319148000.0

# and back
>>> datetime.datetime.fromtimestamp(s)
datetime.datetime(2011, 10, 21, 0, 0)

Farklı zaman dilimlerinin sonuçlar üzerinde etkisi olduğunu unutmayın, örneğin mevcut TZ / DST döndürmelerim:

>>>  time.mktime(datetime.datetime(1970, 1, 1, 0, 0).timetuple())
-3600 # -1h

bu nedenle işlevlerin UTC sürümlerini kullanarak UTC'yi normalleştirmeyi düşünmeliyiz.

Not önceki sonuç UTC hesaplamak için kullanılabileceğini mevcut diliminin ofset. Bu örnekte bu + 1 saattir, yani UTC + 0100.

Referanslar:


mktime()başarısız olabilir . Genel olarak, pytzPOSIX zaman damgasını almak için yerel saati utc'ye dönüştürmeniz gerekir .
jfs

calendar.timegm (), time.mktime () 'in utc sürümü gibi görünüyor
frankster

27

int (t.strftime("%s")) ayrıca çalışır


1
Benim için Python 2.7'de import datetime; t = datetime.datetime(2011, 10, 21, 0, 0)(OP tarafından belirtildiği gibi) çalışır. Ama gerçekten,% s'nin yakın zamanda eklenen bir saat biçimi olduğundan şüpheliyim.
dan3

1
@ dan3: yanlış. %sdesteklenmez (bazı platformlarda çalışabilir iff tyerel saati temsil eden naif bir datetime nesnesidir ve yerel C kütüphanesinin tz veritabanına erişimi varsa, aksi takdirde sonuç yanlış olabilir). Kullanma.
jfs

%shiçbir yerde belgelenmemiştir. Ben gerçek kodda ekmek ve bu ne olduğunu merak ediyordum ve belgelerine bakmak ve böyle bir şey yok %s. Sadece saniyeler boyunca sadece büyük S var.
VStoykov

13

python dokümanlarından:

timedelta.total_seconds()

Süredeki toplam saniye sayısını döndürür. Eşittir

(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6

gerçek bölüm etkin olarak hesaplanır.

Çok büyük zaman aralıkları (çoğu platformda 270 yıldan fazla) için bu yöntemin mikrosaniye doğruluğunu kaybedeceğini unutmayın.

Bu işlevsellik 2.7 sürümünde yenidir.


1
hesaplamada küçük bir sorun var 10 * 6 yerine 10 6 olmalı ... td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 6) / 10 ** 6
sdu

@sdu büyük yakalama - çift yıldız benim cevabımda ama stackoverflow tüketir, sadece metni embolden düzeltmeye çalışır.
Michael

2

UTC'de zamanı temsil eden bir datetime nesnesini POSIX zaman damgasına dönüştürmek için :

from datetime import timezone

seconds_since_epoch = utc_time.replace(tzinfo=timezone.utc).timestamp()

Yerel saat dilimindeki zamanı temsil eden datetime nesnesini POSIX zaman damgasına dönüştürmek için:

import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone()
seconds_since_epoch = local_timezone.localize(local_time, is_dst=None).timestamp()

Bkz Python içinde UTC yerel saati dönüştürmek nasıl? Tz veritabanı belirli bir platformda mevcutsa; sadece stdlib'e uygun bir çözüm işe yarayabilir .

<3.3Python sürümleri için çözümlere ihtiyacınız varsa bağlantıları takip edin .


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.