Подтвердить что ты не робот

Datetime до метки времени Unix с точностью до миллисекунды

Я пытаюсь сделать что-то действительно простое, преобразовать объект datetime три дня в будущее в метку времени UTC Unix:

import datetime, time
then = datetime.datetime.now() + datetime.timedelta(days=3)
# Method 1
print then.strftime("%s")
# Method 2
print time.mktime(then.timetuple())
# Method 3 
print time.mktime(then.timetuple()) * 1000

Способ 1 и 2 дает мне время Unix в секундах, а не миллисекундах, а метод 3 дает миллисекунды без фактической миллисекундной точности.

Когда я просто печатаю then, я получаю datetime.datetime(2011, 11, 19, 15, 16, 8, 278271), поэтому я знаю, что точность доступна для миллисекунд. Как я могу получить временную метку Unix с фактической точностью в миллисекундах? Если он возвращался как float, и я должен сгладить его до int, это прекрасно. Есть ли решение, которое я ищу, что делает это?

4b9b3361

Ответ 1

Объекты Datetime имеют поле с именем microsecond. Итак, один из способов добиться того, что вам нужно:

time.mktime(then.timetuple())*1e3 + then.microsecond/1e3

Это возвращает миллисекунды с эпохи UNIX с требуемой точностью.

Ответ 2

В Python 3.3 и выше, которые поддерживают метод datetime.timestamp(), вы можете сделать это:

from datetime import datetime, timezone, timedelta

(datetime.now(timezone.utc) + timedelta(days=3)).timestamp() * 1e3

Ответ 3

long((time.time() + 0.5) * 1000)

это имеет миллисекундную точность

Ответ 4

День всегда 86400 секунд в POSIX. Чтобы получить временную метку POSIX через 3 дня в будущем как поплавок (с долей секунды):

import time

DAY = 86400 # seconds
future = time.time() + 3 * DAY

Предполагается, что time.gmtime(0) - 1970 (эпоха POSIX).

Если у вас уже есть объект наивного datetime, который представляет время в локальном часовом поясе, метка времени может быть неоднозначной во время переходов DST. Чтобы избежать двусмысленности, вы можете использовать объект datetime, имеющий информацию о часовом поясе, или наивный объект datetime, который представляет время в формате UTC.

Чтобы преобразовать локальное datetime dt в секунды с момента Epoch:

from datetime import datetime
from time import mktime

timestamp = dt.timestamp() # Python 3.3+
timestamp = mktime(dt.timetuple()) + dt.microsecond / 1e6 # Python 2.7

Он может выйти из строя, если в локальном часовом поясе было другое смещение utc в прошлом, а реализация time не имеет доступа к базе данных часовых поясов в системе. Используйте pytz для обработки таких случаев.

Чтобы конвертировать UTC datetime utc_dt в метку времени POSIX:

timestamp = (utc_dt - datetime(1970, 1, 1)).total_seconds()

Чтобы получить миллисекунды, просто умножьте любое число с плавающей запятой секунд на 1e3.

Ответ 5

Если вы используете Python 2.7 или 3.2+, вы можете использовать timedelta.total_seconds(), чтобы получить это довольно легко:

import datetime, time
print time.time() + datetime.timedelta(days=3).total_seconds()

Ответ 6

Если вы придерживаетесь даты в UTC, вы можете сохранить эту абстракцию и использовать timedelta:

from datetime import datetime, timedelta

epoch = datetime.utcfromtimestamp(0)

def dt_from_ms(ms):
    return datetime.utcfromtimestamp(ms / 1000.0)

def dt_to_ms(dt):
    delta = dt - epoch
    return int(delta.total_seconds() * 1000)

то

now = datetime.utcnow()
now
-> datetime.datetime(2017, 1, 25, 1, 30, 42, 765846)  # note microsecond precision

dt_to_ms(now)
-> 1485307842765

dt_from_ms(1485307842765)
-> datetime.datetime(2017, 1, 25, 1, 30, 42, 765000)  # note millisecond precision

then = now + timedelta(days=3)
dt_to_ms(then)
-> 1485567042765

(1485567042765 - 1485307842765) / (24*60*60*1000.0)
-> 3.0