Python'da (unix zamanı) dönemden bu yana datetime nesnesini milisaniyeye nasıl dönüştürebilirim?


Yanıtlar:


474

Bana öyle geliyor ki bunu yapmanın en basit yolu

import datetime

epoch = datetime.datetime.utcfromtimestamp(0)

def unix_time_millis(dt):
    return (dt - epoch).total_seconds() * 1000.0

32
Şimdiye kadar bu en iyi çözümdür (python sürümü> 2.7 ise). Çünkü uygulaması %sişletim sistemine bağlıdır! Böylece herhangi bir işletim sistemi ASLA kullanmanız gerekenden bağımsız olarak kodun güvenilir bir şekilde çalışmasını ister %s. 2.3 <p ver <2.7 için. Biri total_seconds()böyle bir şey inşa edebilir :delta.days*86400+delta.seconds+delta.microseconds/1e6
Wang

14
not: dtUTC (yerel değil) olmalıdır. Benzer cevaba
jfs

7
İstediğiniz tek şey burada tanımlandığı gibi gerçek bir unix zaman damgası ise en.wikipedia.org/wiki/Unix_time (ve bu nedenle sadece bu cevaptaki unix_time işlevini kullanacaksa), int ile delta.total_seconds () bir şamandıra ile bitmekten kaçının
corford

1
çağ kullanılarak hesaplanır utcfromtimestamp(0)bir 'tz' offset yalnızca 'tz' neden olabilir 0. değil Bunun nedeni dt de dt- epochvardır 'tz' çağın olarak UTC zamanı olduğu içinde hesapladı. Dönemi hesaplamanın en iyi yolu epoch = datetime.datetime(1970, 1, 1)saat diliminin dikkate alındığı yerdir.
ahj

35
Neden ah neden datetime.utcfromtimestamp(0)tzinfo olmadan datetime dönüyor? Tam burada yöntem adında, utc fromtimestamp. Naif olmamak için böyle bir şey yapmalıyım datetime.utcfromtimestamp(0).replace(tzinfo=pytz.UTC). Bu, dtsaat dilimi farkındaysa veya başka bir şey alırsanız gereklidirTypeError: can't subtract offset-naive and offset-aware datetimes
FGreg

172

Python 3.3'te yeni yöntem eklendi timestamp:

import datetime
seconds_since_epoch = datetime.datetime.now().timestamp()

Sorunuz milisaniyeye ihtiyacınız olduğunu belirtti ve bu şekilde alabilirsiniz:

milliseconds_since_epoch = datetime.datetime.now().timestamp() * 1000

Eğer kullanırsanız timestampbir naif datetime nesne üzerinde, o zaman yerel saat diliminde olduğu varsayılmıştır. Gerçekleştirmek istediğiniz şey bu değilse, saat dilimine duyarlı datetime nesneleri kullanın.


28
Not: .timestamp()yöntem, yerel bir giriş tarih saatinin yerel saat diliminde olduğunu (ve yerel saatin belirsiz olabileceğini) varsayar. UTC'de ise dt.replace(tzinfo=timezone.utc).timestamp()bunun yerine kullanın .
jfs

11
datetime.timestamp () döneme saniye olarak kayan noktalı sayı olarak döndürür. Milisaniye elde etmek için: int (datetime.timestamp () * 1000)
Solar.gy

9
Bu cevap, docs.python.org/3/library/… adresindeki insan dostu olmayan dokümanların ruhuyla kopyalanıp yapıştırılabilir bir örnek değildir - bu: datetime.datetime.timestamp(datetime.datetime.now())
MarkHu

3
3.6'da (en azından), datetime.timestamp (), saat dilimi naif (tzinfo = Yok) tarih saatinin UTC'de olduğunu varsayar. Saat diliminizin ayarlanması her zaman daha iyidir: datetime.datetime.now(pytz.timezone('Europe/Paris')).timestamp() == datetime.datetime.now(pytz.utc).timestamp() == datetime.datetime.utcnow().timestamp()(her zaman) eşit değil ( datetime.datetime.now().timestamp()bu sonuncusu yalnızca yerel tz UTC ise ...)
Bluu

1
İlginiz için bunun tersi] fromtimestamp( docs.python.org/3/library/… )
Flimm

98
>>> import datetime
>>> # replace datetime.datetime.now() with your datetime object
>>> int(datetime.datetime.now().strftime("%s")) * 1000 
1312908481000

Veya zaman modülünün yardımı (ve tarih formatlaması olmadan):

>>> import datetime, time
>>> # replace datetime.datetime.now() with your datetime object
>>> time.mktime(datetime.datetime.now().timetuple()) * 1000
1312908681000.0

Http://pleac.sourceforge.net/pleac_python/datesandtimes.html adresinden yardım alarak yanıtladı

Belgeler:


6
Btw, strftime ("% s") benim için boş bir dize döndürüyor. İkinci yol iyi çalışıyor.
Pavel Vlasov

23
Sadece ikinci bir doğruluğa sahiptir
shuckc

6
'% s' Python tarafından desteklenmez, örneğin Windows'ta olmayabilir. .timetuple()döner tm_isdst=-1o zorlar mktime()tahmin etmek. DST sırasında yanlış tahmin edebilir (% 50 hata +/- saat). Hem '% s' hem mktime()de geçmişten gelen tarihler için yanlış utc uzaklığını kullanabilir. pytzYerel saati POSIX zaman damgasına güvenilir bir şekilde dönüştürmek için modül tarafından sağlanan gibi tarihsel bir saat dilimine ihtiyacınız vardır (OS zaten böyle bir db
sağlamadığı

1
time.mktime(ts.timetuple())burada ts
python'un

1
@suhail: hakkındaki yorumumu okuyun mktime/timetuple. Ayrıca timetuple()bir saniyenin kesirlerini çıkarır ve sorunun amacı zaman damgasını milisaniye hassasiyetle elde etmektir.
jfs


13

Bunu nasıl yaparım:

from datetime import datetime
from time import mktime

dt = datetime.now()
sec_since_epoch = mktime(dt.timetuple()) + dt.microsecond/1000000.0

millis_since_epoch = sec_since_epoch * 1000


2
@JFSebastian Uyarılarınız için teşekkürler! aslında dikkate alınan herhangi bir dst yoktur. Sunucunuz UTC yerine yerel saatteyse fark yaratacaktır. UTC dışında bir şey sunucu ayarlamak için zorlayıcı bir neden (henüz) bulamadım. Benim moto "UTC yazmak, yerel saati okumak" olduğunu, bu yüzden her zaman nerede kaldığını biliyorsun ...
estani

2
Saat dilimini tahmin etmeye çalışırken mktime sorununu önlemek için her zaman mktime yerine calendar.timegm kullanabilirsiniz.
Decko

13

@ChristopherBull Saniyeye ulaşmak için milisaniye sayısını 1000'e bölün
Jonas

5
Yanlış anladınız ve yanlış yola saptınız. Saniye, yukarıdaki işlevlerde hazırdır. Milisaniyeye dönüştürebilirsiniz, ancak bir saniyenin hassasiyeti olacaktır.
Christopher Bull

1
Bu cevap timemodülü kullanıyor , ancak OP datetimemodülü sordu . FWIW, en basit dönemint(time.time())
MarkHu

7
from datetime import datetime
from calendar import timegm

# Note: if you pass in a naive dttm object it's assumed to already be in UTC
def unix_time(dttm=None):
    if dttm is None:
       dttm = datetime.utcnow()

    return timegm(dttm.utctimetuple())

print "Unix time now: %d" % unix_time()
print "Unix timestamp from an existing dttm: %d" % unix_time(datetime(2014, 12, 30, 12, 0))

timegm()sadece utc zamanı ile çalışır. Bu tm_isdstnedenle kullanmak utcnow.timetuple()yerine kullanamaz utcnow.utctimetuple(). Not: naive_local_datetime.utctimetuple()burada kullanmak yanlış olur. Yerel saati utc'ye çevirmez. Ayrıca timetuple()sonuçtan saniyenin kesirlerini ayırın (önemli olup olmadığı uygulamaya bağlıdır). Ayrıca soru saniye değil, * milli * saniye soruyor
jfs

Kodu kesinlikle UTC ile ilgili olduğunu açıklamak için utcnow () ve utctimetuple () kullanmayı tercih (ve bu şekilde okuyan herkes timegm sadece UTC olduğunu hatırlamak zorunda değildir). utctimetuple (), naif bir dttm nesnesi üzerinde çeviri anlamına gelmez (bu nedenle dttm'yi utcnow () ile başlatır). Ayrıca, soru belirtilen saniye veya milisaniye.
corford

Not: son yorumda sanırım o saniye ya da milisaniye istediğini ima olarak okudum (muhtemelen benim hatam). Milis için sadece 1000 ile çarpın (en yüksek puanlama cevabının önerdiği gibi).
corford

utctimetuple()saniyenin kesirlerini ayırır. İle çarpmak 1000onları geri almayacak.
jfs

1
OP'nin bu soruyu sorduğundan dolayı, tam olarak ne istediği belirsizdir (yani gerçek bir unix zaman damgası veya milisaniyelik doğruluğa sahip bir zaman damgası). Ne olursa olsun, her iki soru da başka bir yerde sorulmuş ve cevaplanmıştır. Bunu söyledikten sonra, buradaki cevapların, insanların sorunlara çeşitli çözümleri göstermek için en hızlı ve en temiz olduğunu düşünüyorum.
corford

3
>>> import datetime
>>> import time
>>> import calendar

>>> #your datetime object
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2013, 3, 19, 13, 0, 9, 351812)

>>> #use datetime module's timetuple method to get a `time.struct_time` object.[1]
>>> tt = datetime.datetime.timetuple(now)
>>> tt
time.struct_time(tm_year=2013, tm_mon=3, tm_mday=19, tm_hour=13, tm_min=0, tm_sec=9,     tm_wday=1, tm_yday=78, tm_isdst=-1)

>>> #If your datetime object is in utc you do this way. [2](see the first table on docs)
>>> sec_epoch_utc = calendar.timegm(tt) * 1000
>>> sec_epoch_utc
1363698009

>>> #If your datetime object is in local timeformat you do this way
>>> sec_epoch_loc = time.mktime(tt) * 1000
>>> sec_epoch_loc
1363678209.0

[1] http://docs.python.org/2/library/datetime.html#datetime.date.timetuple

[2] http://docs.python.org/2/library/time.html


3

Zaman nesnenizin normalleştirilmesiyle başka bir çözüm biçimi:

def to_unix_time(timestamp):
    epoch = datetime.datetime.utcfromtimestamp(0) # start of epoch time
    my_time = datetime.datetime.strptime(timestamp, "%Y/%m/%d %H:%M:%S.%f") # plugin your time object
    delta = my_time - epoch
    return delta.total_seconds() * 1000.0

2

Biraz panda kodu:

import pandas

def to_millis(dt):
    return int(pandas.to_datetime(dt).value / 1000000)

1
import time
seconds_since_epoch = time.mktime(your_datetime.timetuple()) * 1000

9
Bu yanlış! Zaman dilimi milisaniye içermez, bu nedenle mktime, dönemi milisaniye çözünürlükle döndürmez. Bu durumda işe yaramaz.
Wang

@Wang - haklısın efendim, bu milis döndürmez, sadece saniyeler
MattoTodd


1
Ancak çıkarırsanız * 1000, alırsınız seconds_since_epoch. Bu cevabı iptal ediyorum çünkü şu anda milisaniye umurumda değil.
Michael Scheper

0

İşte yukarıdaki cevaba dayanarak yaptığım bir fonksiyon

def getDateToEpoch(myDateTime):
    res = (datetime.datetime(myDateTime.year,myDateTime.month,myDateTime.day,myDateTime.hour,myDateTime.minute,myDateTime.second) - datetime.datetime(1970,1,1)).total_seconds()
    return res

Döndürülen değeri şu şekilde sarabilirsiniz: str (int (res)) Dize olarak kullanılacak ondalık değer olmadan veya yalnızca int (str olmadan) döndürmek için


-14

Unixtimestampmillis'e gizli tarih-saat için bu diğer çözüm.

private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    public static long GetCurrentUnixTimestampMillis()
    {
        DateTime localDateTime, univDateTime;
        localDateTime = DateTime.Now;          
        univDateTime = localDateTime.ToUniversalTime();
        return (long)(univDateTime - UnixEpoch).TotalMilliseconds;
    } 

2
Soru Python dili hakkında
Stéphane
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.