Bir time.struct_time nesnesini datetime nesnesine nasıl dönüştürürsünüz?


288

Python time.struct_timenesnesini nesneye nasıl dönüştürürsünüz datetime.datetime?

Birincisini sağlayan bir kütüphane ve ikincisini isteyen ikinci bir kütüphanem var.

Yanıtlar:


384

Epoch'tan bu yana zaman demetini ( yerel saatte ) saniyeye dönüştürmek için time.mktime () öğesini kullanın , ardından datetime nesnesini almak için datetime.fromtimestamp () öğesini kullanın.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
Bunun 1900'den önce başarısız olduğunu unutmayın. Siz modern insanlar bu sınırlamayı asla hatırlamıyorsunuz!
mlissner

3
bu tm_isdstverileri kaybedecek mi? Ben tarih saat nesneyi çıkan dönmek için ölçüde naif kalır öyle düşünüyorum Noneüzerinde .dst()bile struct.tm_isdstolduğunu 1.
n611x007

3
Bu genellikle işe yarar. Bununla birlikte, zaman demetinin mktime tarafından kabul edilen değerlerin ötesinde olması durumunda başarısız olur, örneğin değer (1970, 1, 1, 0, 0, 0, 0, 1, -1). Bu tuple döndüren bir HTTP isteği Tarih üstbilgisini ayrıştırdıktan sonra bu karşılaştım.
user3820547

3
@richvdh: C standardı mktime()dikkate alınması gerektiğini belirtir tm_isdstve Python CPython'da time.mktime()C mktime()işlevini çağırır . mktime()Belirsiz olduğunda yanlış yerel zamanı seçin (örneğin, ( "sonbahar arka") geçiş sonu DST-of sırasında) eğer struct.tm_isdstolduğunu -1ya eğer mktime()verilen platformda yok sayar girişi tm_isdst . Ayrıca, yerel saat dilimi geçmişte farklı utc ofsetine sahipse ve C mktime(), eski utc ofset değerlerini sağlayabilen geçmiş bir tz veritabanı kullanmıyorsa mktime(), yanlış (örneğin, bir saat kadar) bir değer de döndürebilir.
jfs

1
@ naxa: verilen platformda mktime()görmezden gelmezse tm_isdst(benimkinde yapar) o zaman fromtimestamp()kesinlikle bilgileri kaybeder: yerel saati temsil eden iade edilen naif datetime nesne belirsiz olabilir (zaman damgası -> yerel saat belirleyicidir (artık saniyeleri yoksayarsak) ama local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `, tarihsel bir tz veritabanı kullanmıyorsa yanlış bir utc ofseti seçebilir.
jfs

123

Bunun gibi:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)


7
@jhwist - insanların kendi başlarına anlamaya güvenebilecekleri bazı şeyler :)
orip

14
@ sözdizimi *ve **sözdizimi, bağımsız değişkenleri ayırmak için listelenmiş veya zorlayıcı bir nesneyi genişletmenize izin verir - bu benim en sevdiğim Python sevgisi parçalarından biridir. Daha fazla bilgi için docs.python.org/2/tutorial/… adresine bakınız.
OrganicPanda

10
Sadece struct_time bir sıçrama süresi varsa bunun size bir ValueError vereceğini unutmayın, örneğin:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario

7
@berdario: ile uyumlu değerleri döndürmek için datetime: datetime(*t[:5]+(min(t[5], 59),))örneğin, kabul etmek "2015-06-30 16:59:60 PDT".
jfs

37

Bu, sorunuza doğrudan bir cevap değildir (zaten çok iyi cevaplanmıştır). Bununla birlikte, zamanlar birkaç kez beni temel üzerinde ısırmış olsaydı, time.struct_time nesnesinin ne sağladığına, diğer zaman alanlarının ne olabileceğine yakından bakmanız için size yetecek kadar stresli olamam.

Hem bir time.struct_time nesneniz hem de başka bir tarih / saat dizeniz olduğunu varsayarsak, ikisini karşılaştırın ve aksi halde yapabileceğiniz zaman veri kaybetmediğinizden ve yanlışlıkla naif bir datetime nesnesi oluşturmadığınızdan emin olun.

Örneğin, mükemmel feedparser modülü bir "yayınlandı" alanı döndürür ve "yayımlanmış_parsed" alanına bir time.struct_time nesnesi döndürebilir:

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Şimdi "yayınlanmış" alanla gerçekte ne elde ettiğinizi not edin.

Mon, 09 Sep 2013 19:57:42 -0400

by Stallman 'ın Sakalı! Saat dilimi bilgileri!

Bu durumda, tembel adam saat dilimi bilgilerini tutmak için mükemmel dateutil modülünü kullanmak isteyebilir:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

bize şunu verir:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Daha sonra, zaman dilimini UTC veya harika olduğunu düşündüğünüz her zaman normalleştirmek için saat dilimine duyarlı datetime nesnesi kullanılabilir.


7
*_parsedFeedparsed öğesindeki tüm alanlar , tarih ayrıştırma belgelerinde kontrol edilebileceği gibi UTC'ye normalleştirilmiştir, bu nedenle bu gereksizdir.
itorres

1
@itorres: Anlıyorsam, bu cevap UTC'ye normalleştirmekle ilgili değil, saat dilimi bilgilerini ham dize tarihlerini ayrıştırırken datetimekaybolan bir nesnede tutmakla ilgilidir feedparser.
davidag
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.