Python'da tarihlerle uğraşıyorum ve bunları kullanılmak üzere UTC zaman damgalarına dönüştürmem gerekiyor Javascript'in içinde. Aşağıdaki kod çalışmıyor:
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
Tarih nesnesini önce datetime'a dönüştürmek de yardımcı olmaz. Bu link'deki örneği denedim, ancak:
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
ve şimdi de:
mktime(utc.localize(input_date).utctimetuple())
veya
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
işe yarıyor.
Yani genel soru: UTC'ye göre bir tarihi çağdan bu yana saniyeye nasıl dönüştürebilirim?
Eğer d = date(2011, 1, 1)
UTC'de ise:
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
Eğer d
yerel saat dilimindeyse:
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
Yerel saat dilimindeki gece yarısı UTC'deki gece yarısı ile aynı zaman örneği değilse timestamp1
ve timestamp2
farklı olabilir.
mktime(),
d[belirsiz bir yerel saate (örneğin, DST geçişi sırasında)](https://stackoverflow.com/questions/12165691/python-datetime-with-timezone-to-epoch/12166400#comment39565270_12166400) karşılık geliyorsa veya
dutc ofsetinin farklı olabileceği geçmiş (gelecek) bir tarih ise * ve * C
mktime(), verilen platformda [tz veritabanına](http://www.iana.org/time-zones/repository/tz-link.html) erişemiyorsa yanlış bir sonuç döndürebilir. Tüm platformlardaki tz veritabanına erişmek için
pytzmodülünü (örneğin,
tzlocal.get_localzone()aracılığıyla) kullanabilirsiniz](https://stackoverflow.com/a/17365806/4279). Ayrıca, [
"right"zaman dilimi kullanılırsa
utcfromtimestamp()başarısız olabilir ve
mktime()` POSIX olmayan zaman damgası döndürebilir](https://stackoverflow.com/questions/28949623/python-datetime-and-utc-offset-conversion-ignoring-timezone-daylight-savings/28950133#comment46155743_28950133).
Tarihi UTC cinsinden temsil eden datetime.date
nesnesini calendar.timegm()
olmadan dönüştürmek için:
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
UTC'de zamanı zaten temsil eden datetime.datetime
(datetime.date
değil) nesnesini karşılık gelen POSIX zaman damgasına (bir float
) dönüştürmek için.
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Not: timezone.utc
ifadesini açıkça belirtmeniz gerekir, aksi takdirde .timestamp()
naive datetime nesnenizin yerel zaman diliminde olduğunu varsayar.
datetime.utcfromtimestamp()
dokümanlarından:
Bir datetime örneğinden zaman damgasını elde etmek için bir yöntem yoktur, ancak bir datetime örneği dt'ye karşılık gelen POSIX zaman damgası aşağıdaki gibi kolayca hesaplanabilir. Saf bir dt için:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
Ve bilinçli bir dt için:
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
İlginç bir okuma: Epoch time vs. time of day Saat kaç? " ile Kaç saniye geçti? " arasındaki fark üzerine
Ayrıca bakınız: datetime bir "epoch" yöntemine ihtiyaç duyar
Yukarıdaki kodu Python 2 için uyarlamak için:
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
burada timedelta.total_seconds()
, (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) değerine eşdeğerdir. / 10**6
gerçek bölme etkinleştirilmiş olarak hesaplanır.
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, epoch=datetime(1970,1,1)):
td = dt - epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
Kayan nokta sorunlarına dikkat edin](http://bugs.python.org/issue8644).
2012-01-08 15:34:10.022403
1326036850.02
datetime
nesnesi POSIX zaman damgasına nasıl dönüştürülürassert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
Python 3'te:
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)
Python 2'de:
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
Varsayım 1:** Bir tarihi zaman damgasına dönüştürmeye çalışıyorsunuz, ancak bir tarih 24 saatlik bir süreyi kapsadığından, o tarihi temsil eden tek bir zaman damgası yoktur. Bu tarihin zaman damgasını gece yarısında (00:00:00.000) temsil etmek istediğinizi varsayacağım.
Varsayım 2:** Sunduğunuz tarih belirli bir saat dilimiyle ilişkili değildir, ancak belirli bir saat diliminden (UTC) uzaklığı belirlemek istiyorsunuz. Tarihin hangi saat diliminde olduğunu bilmeden, belirli bir saat dilimi için zaman damgası hesaplamak mümkün değildir. Tarihi yerel sistem saat dilimindeymiş gibi ele almak istediğinizi varsayacağım.
İlk olarak, timetuple()
üyesini kullanarak tarih örneğini çeşitli zaman bileşenlerini temsil eden bir tuple'a dönüştürebilirsiniz:
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
Daha sonra bunu time.mktime
kullanarak bir zaman damgasına dönüştürebilirsiniz:
ts = time.mktime(dtt) # 1293868800.0
Bu yöntemi epoch zamanının kendisiyle (1970-01-01) test ederek doğrulayabilirsiniz; bu durumda fonksiyon o tarihteki yerel saat dilimi için saat dilimi ofsetini döndürmelidir:
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0' 8 saattir, bu da Pasifik saat dilimi (benim bulunduğum yer) için doğru olacaktır.
Tam bir zaman dizisi şunları içerir:
[+HHMM veya -HHMM]
Örneğin:
1970-01-01 06:00:00 +0500
== 1970-01-01 01:00:00 +0000
== UNIX zaman damgası:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
Not:
UNIX zaman damgası
, UTC cinsinden, çağdan bu yana saniye cinsinden ifade edilen kayan noktalı bir sayıdır.
Düzenle:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600