Python tarih saatini strftime ile çağa dönüştürme


209

UTC'de zamanımdan bu yana geçen saniye sayısını istediğim bir zamanım var.

Saniyeye dönüştürmek için strftime kullanıyorum. Örnek olarak 1 Nisan 2012'yi ele alalım.

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

1 Nisan 2012 UTC dönemi UTC 1333238400 ama bu yukarıdaki 1333234800 döndürür, bu 1 saat farklıdır.

Görünüşe göre strftime sistem zamanımı hesaba katıyor ve bir yere bir saat dilimi kayması uyguluyor. Tarih saatinin tamamen saf olduğunu mu sanıyordum?

Bunu nasıl başarabilirim? Mümkünse standart olmadığı sürece diğer kütüphaneleri içe aktarmaktan kaçının. (Taşınabilirlikle ilgili endişelerim var).



11
Rakamlarda sekizli değişmezleri kullandığınızı gösteren tek kişi ben miyim?
Balık Monitörü


3
Daha yeni Python 3.3+ vardırdatetime.datetime.timestamp(datetime.datetime.utcnow())
MarkHu

Yanıtlar:


389

Dönemden beri bir python tarih saatini saniyeye dönüştürmek istiyorsanız, bunu açıkça yapabilirsiniz:

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

Python 3.3+ sürümünde şunları kullanabilirsiniz timestamp():

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

Neden kullanmamalısın datetime.strftime('%s')

Python aslında% s'yi strftime için bir argüman olarak desteklemiyor (eğer listede yoksa http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior adresine bakarsanız ), çalışmasının nedeni, Python'un bilgileri yerel saat diliminizi kullanan sisteminizin iş süresine geçirmesidir.

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

7
Neden strftime ("% s") çok fazla görüyorum anlamaya çalışıyorum, ama bu dokümanlar değil. Bu hiçbir şey için teşekkür ederim!
Jonathan Vanasco

54
kullanmayın .strftime("%s"): desteklenmez, taşınabilir değildir, bilinçli bir datetime nesnesi için sessizce yanlış bir sonuç verebilir, giriş UTC'de ise (soruda olduğu gibi) başarısız olur, ancak yerel saat dilimi UTC değil
jfs

2
@earthmeLon Basamaklama yanlış. Timedeltas (iki dat zaman çıkarılarak yapılır) toplam_seconds vardır, ancak dattime yoktur.
jleahy

2
Bu benim için çalışmıyor:AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'
Michael

3
@Michael Bu işlev Python 2.7'de yeni, daha eski bir sürüm kullanıyor olmalısınız. 2.7'den önceki sürümler için bunu yapabilirsiniz td.seconds + td.days*24*3600. Bu mikrosaniye kısmını atar.
jleahy

100

Timezonlar ve benzeri konularda ciddi sorunlar yaşadım. Python'un (bana göre) oldukça kafa karıştırıcı olan her şeyi ele alma şekli. Takvim modülünü kullanarak işler düzgün çalışıyor gibi görünüyor (bkz. 1 , 2 , 3 ve 4 bağlantıları ).

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

7
+1 çünkü sorudaki girdi için çalışan tek cevap budur.
jfs

bu taşınabilir mi?
benjaminz

1
Bu, doğru cevap olarak işaretlenmelidir, çünkü söz konusu endişeye cevap verir. vnice kudos
Leo Prince

2
Bu 'çalışıyor', ancak şu soruya dikkat edin: "UTC'de bir zamanım var" Bu yöntem her zaman sistemin yerel saat dilimini kullanacaktır. Bir saat dilimi belirtmenin bir yolu yoktur. Eğer aprilFirstbu örnekte bir 'farkında' örneği ve sistemin saat dilimine bir zaman dilimi diğerlerinden farkı kullanılan, sonuç (saat dilimi içinde kaybolursa doğru olmaz timetuple()çağrı). En awaredt.timestamp()son Python 3'te kullanabileceğiniz 'farkında' bir tarih için doğru cevabı almak için Python 2 için daha zor; bir yolu arrowkütüphaneyi kullanmaktır . arrow.get(awaredt).timestampdoğru olacak.
Adam Williamson

1
İyi bir nokta, @AdamWilliamson, ancak örnekteki kod datetimenesneyi yerelleştirmiyor , bu yüzden "UTC'de bir zamanım var" , OP'nin istediği UTC'de datetimeolduğu varsayılan bir habersiz nesneye sahip olduğu anlamına geliyordu. bir almak için epoch(eğer datetime, gerçekten, bu kudreti TZ-farkında olmak şeyleri değiştirmek oldu). Ayrıca, bu cevabın neredeyse 8 yaşında olduğunu ve o zamandan beri birçok şeyin gerçekleştiğini unutmayın ( arrowörneğin 2013'te piyasaya sürüldü)
BorrajaX

35
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())

1
yazmak yanlış bir yoldur time.time()( çalışmaya devam mktime()ederken DST geçişleri sırasında başarısız olabilir time.time()). Ve yerel saat dilimi UTC değilse (sorudaki giriş UTC'dir) soruyu cevaplamaz. Girdi yerel bir saati temsil etse bile mktime(), tz veritabanını kullanmıyorsa ve yerel saat dilimi yıllar içinde farklı utc ofsetleri içeriyorsa, örneğin, 2010-2015'te Avrupa / Moskova - - bunun yerine UTC saatini (soruda olduğu gibi) veya saat dilimine duyarlı datetime nesnelerini kullanın.
jfs

here're bir yerel saat (örneğin tarafından döndürülen dönüştürme ile daha fazla sorun .now()(dönen dönem zaman damgası) mktime()) . Eğer okursanız; UTC girişinin (soruda kullanılan) yerel saati temsil eden naif datetime nesnesinden neden daha fazla tercih edildiğini anlıyorsunuz
jfs

14
import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(Üzgünüm, mevcut cevap hakkında yorum yapmama izin vermedi)


Çünkü time.mktime mikrosaniye bölümünü dikkate almıyor, değil mi?
Eduardo

1
Doğru. Zaman tuple yapısı (C strut'a dayalı olarak) mikrosaniye için bir boşluğa sahip olmadığından, datetime nesnesinden bilgileri almamız ve sonuna eklememiz gerekir.
Charles Plager


Makinelerimde, saat dilimim ET olmasına rağmen bu doğru çalışıyor.
Charles Plager

1
Bu, sistemin yerel saatine bağlı olarak farklı sistemlerde farklı zaman damgaları verecektir.
Yousaf

6

sadece unix / epoch zamanında bir zaman damgasına ihtiyacınız varsa, bu tek satır çalışır:

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

ve yalnızca datetime python2 ve python3'teki çalışmalara bağlıdır


2

Bu Python 2 ve 3'te çalışır:

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

Resmi dokümanları takip etmek ... https://docs.python.org/2/library/time.html#module-time


1) Bu, rastgele bir datetime nesnesi değil, şimdi dönüştürmek istediğinizi varsayar. 2) Takvime ihtiyacınız yok. time.mktime (randomDateTime.timetuple ()) + randomDateTime.microsecond * 1e-6
Charles Plager

@CharlesPlager time.mktime yanlış; argümanı yerel saat diliminde yorumlar, OP ise UTC'de yorumlanan zamanı ister (calendar.timegm gibi).
stewbasic

Bu benim için en doğru cevap, eğer GMT'de zamanınızı dönüştürmek istiyorsanız ve bunu zaman damgası dönüşümüne dönüştürmek istiyorsanız.
Yousaf

Sadece cevabınızı takip ederek calendar.timegm (datetime.strptime ("2019-05-03T05: 40: 09.770494 + 00: 00" [: 16], '% Y-% m-% dT% H:% M'). timetuple ()) utc içinde zaman damgası var ve hangi sistemde çalıştırırsanız çalışın bana doğru zaman damgası verir, hile strptime.timetumple kullanmaktır
Yousaf

2

Açık bir saat diliminden bağımsız çözüm için pytz kitaplığını kullanın.

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

Çıktı (şamandıra): 1333238400.0


stackoverflow.com/a/21145908/4355695 adresinde benzer bir cevap gördüm , ancak bu tek katmanlı olarak, gelen verilerin UTC olduğu ve sadece .timestamp () 'nın yerel saatte olduğunu varsaydığı kullanım durumum için harika .
Nikhil VJ

Bu, 1970'den daha küçük tarihler için geçerlidir. Kabul edilen cevap 1970'den küçük tarihler için geçerli değildir. (Python 3.7.3 64-bit Anaconda3)
canbax

-1

Python 3.7 içinde

Date.isoformat () ve datetime.isoformat () tarafından yayınlanan biçimlerden birinde date_string öğesine karşılık gelen bir datetime döndürün. Özellikle, bu işlev YYYY-AA-GG [* HH [: MM [: SS [.fff [fff]]]]] [+ HH: MM [: SS [.ffffff]]]] biçimindeki dizeleri destekler , burada * herhangi bir karakterle eşleşebilir.

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat


1
Bunun Python 3.7'de tanıtıldığını unutmayın.
keithpjolley
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.