Mam datetime
obiekt w języku Python, który chcę przekonwertować na czas uniksowy lub sekundy / milisekundy od epoki 1970.
Jak mam to zrobic?
$ python -c 'import time; print(time.time())'
1584487455.698623
Mam datetime
obiekt w języku Python, który chcę przekonwertować na czas uniksowy lub sekundy / milisekundy od epoki 1970.
Jak mam to zrobic?
$ python -c 'import time; print(time.time())'
1584487455.698623
Odpowiedzi:
Wydaje mi się, że najprostszym sposobem na to jest
import datetime
epoch = datetime.datetime.utcfromtimestamp(0)
def unix_time_millis(dt):
return (dt - epoch).total_seconds() * 1000.0
%s
zależy od systemu operacyjnego! Dlatego każdy chce, aby kod działał niezawodnie, niezależnie od tego, jakiego systemu operacyjnego NIGDY nie należy używać %s
. Dla 2.3 <py ver <2.7. Można po prostu zbudować coś total_seconds()
takiego:delta.days*86400+delta.seconds+delta.microseconds/1e6
dt
musi być w UTC (nie lokalnym). Zobacz podobną odpowiedź ze wsparciem dla
utcfromtimestamp(0)
może powodować przesunięcie „tz” tylko wtedy, gdy „tz” nie wynosi 0. Wynika to z faktu, że dt
in dt- epoch
ma obliczone w nim „tz”, gdzie jako epoką jest czas UTC. Najlepszym sposobem obliczenia epoki jest uwzględnienie epoch = datetime.datetime(1970, 1, 1)
strefy czasowej.
datetime.utcfromtimestamp(0)
zwraca datetime bez tzinfo? Jest tam w nazwie metody, utc fromtimestamp. Aby uczynić go nie naiwnym, muszę zrobić coś takiego datetime.utcfromtimestamp(0).replace(tzinfo=pytz.UTC)
. Jest to konieczne, jeśli dt
wiadomo o strefie czasowej lub dostanieszTypeError: can't subtract offset-naive and offset-aware datetimes
W Pythonie 3.3 dodano nową metodę timestamp
:
import datetime
seconds_since_epoch = datetime.datetime.now().timestamp()
Twoje pytanie brzmiało, że potrzebujesz milisekund, które możesz uzyskać w następujący sposób:
milliseconds_since_epoch = datetime.datetime.now().timestamp() * 1000
Jeśli używasz timestamp
naiwnego obiektu typu data-godzina, zakłada się, że znajduje się on w lokalnej strefie czasowej. Użyj obiektów datetime uwzględniających strefę czasową, jeśli nie to chcesz.
.timestamp()
metoda zakłada, że naiwna wejściowa data / godzina znajduje się w lokalnej strefie czasowej (a czas lokalny może być niejednoznaczny). Jeśli jest w UTC, użyj dt.replace(tzinfo=timezone.utc).timestamp()
zamiast tego .
datetime.datetime.timestamp(datetime.datetime.now())
datetime.datetime.now(pytz.timezone('Europe/Paris')).timestamp() == datetime.datetime.now(pytz.utc).timestamp() == datetime.datetime.utcnow().timestamp()
ale nie (zawsze) równa datetime.datetime.now().timestamp()
(ta ostatnia jest równa reszcie, jeśli lokalna tz to UTC ...)
fromtimestamp
( docs.python.org/3/library/… )
>>> import datetime
>>> # replace datetime.datetime.now() with your datetime object
>>> int(datetime.datetime.now().strftime("%s")) * 1000
1312908481000
Lub pomoc modułu czasu (i bez formatowania daty):
>>> import datetime, time
>>> # replace datetime.datetime.now() with your datetime object
>>> time.mktime(datetime.datetime.now().timetuple()) * 1000
1312908681000.0
Odpowiedzi udzielono z pomocą: http://pleac.sourceforge.net/pleac_python/datesandtimes.html
Dokumentacja:
.timetuple()
zwraca tm_isdst=-1
siłę mktime()
do zgadnięcia. Może źle zgadnąć podczas DST (50% szansy na błąd +/- godziny). Zarówno „% s”, jak i mktime()
może używać niewłaściwego przesunięcia utc dla dat z przeszłości. Potrzebujesz historycznej bazy danych strefy czasowej, takiej jak dostarczona przez pytz
moduł, aby niezawodnie konwertować czas lokalny na sygnaturę czasową POSIX (chyba że system operacyjny już zapewnia taką db)
time.mktime(ts.timetuple())
gdzie ts jest obiektem datetime Pythona
mktime/timetuple
. timetuple()
Usuwa również ułamki sekundy, a celem pytania jest uzyskanie znacznika czasu z milisekundową precyzją.
Możesz używać Delorean do podróżowania w przestrzeni i czasie!
import datetime
import delorean
dt = datetime.datetime.utcnow()
delorean.Delorean(dt, timezone="UTC").epoch
Tak to robię:
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
Zalecenia z dokumentacji Python 2.7 dla time
modułu
time
modułu, ale OP zapytał o datetime
moduł. FWIW, najprostsza obecna epoka toint(time.time())
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()
działa tylko z czasem utc. Nie używa, tm_isdst
więc możesz użyć utcnow.timetuple()
zamiast utcnow.utctimetuple()
. Uwaga: użycie naive_local_datetime.utctimetuple()
byłoby niewłaściwe tutaj. Nie tłumaczy czasu lokalnego na utc. Wywołaj również timetuple()
paski ułamków sekundy od wyniku (to, czy ma to znaczenie, zależy od zastosowania). Pytanie dotyczy także * mili * sekund, a nie sekund
utctimetuple()
wycina ułamki sekundy. Pomnożenie przez 1000
nie spowoduje ich odzyskania.
>>> 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
Oto kolejna forma rozwiązania z normalizacją obiektu czasowego:
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
import time
seconds_since_epoch = time.mktime(your_datetime.timetuple()) * 1000
* 1000
, dostaniesz seconds_since_epoch
. Ulepszenie tej odpowiedzi, ponieważ w tej chwili nie dbam o milisekundy.
Oto funkcja, którą wykonałem na podstawie powyższej odpowiedzi
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
Możesz owinąć zwróconą wartość w następujący sposób: str (int (res)) Aby zwrócić ją bez wartości dziesiętnej do użycia jako łańcuch lub po prostu int (bez łańcucha)
To inne rozwiązanie dla potajemnej daty i godziny na unixtimestampmillis.
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;
}