Преобразовать строковую дату в отметку времени в Python

220

Как преобразовать строку в формате "%d/%m/%Y"в метку времени?

"01/12/2011" -> 1322697600
Шанкар Кабус
источник
Какой номер 2? Время эпохи Unix?
Hasteur
4
@ Хастер, да. Второе число представляет количество секунд, прошедших между началом эпохи Unix и указанной датой. Этот формат также упоминается как время POSIX.
эикономега

Ответы:

320
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
Katriel
источник
10
Предполагается полночь 01/12/2011 в местном часовом поясе. Если ввод в UTC; Вы могли бы использовать calendar.timegm()или.toordinal()
JFS
50
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()немного короче
Timdiels
11
@timdiels: снова. .timestamp()предполагает местное время вместо UTC, если не указан явный часовой пояс. Код в ответе работает (выдает ожидаемый результат 1322697600) только на компьютере, где местный часовой пояс имеет нулевое смещение utc.
Jfs
7
это не работает: datetime.datetime.strptime («2014: 06: 28 11:53:21», «% Y:% m:% d% H:% M:% S»). timestamp () Traceback ( последний вызов был последним): файл "<stdin>", строка 1, в <module> AttributeError: у объекта 'datetime.datetime' нет атрибута 'timestamp'
Зденек Макс
5
@ZdenekMaxa datetime.timestamp () доступно только для версий Python> = 3.3. docs.python.org/3/whatsnew/3.3.html
Джони Джонс
50

Я использую ciso8601, что в 62 раза быстрее, чем strptime для datetime.

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

Вы можете узнать больше здесь .

Эяль Ч
источник
2
это фантастическое предложение. я просто использовал это и сбрил тонны времени от моей казни.
Дэвид
3
Боже мой, это быстро
Хьюс
3
И +1 за то, что мне не нужно объяснять, что такое формат строки времени.
gowenfawr
40

Чтобы преобразовать строку в объект даты:

from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

Способ преобразования объекта даты в метку времени POSIX зависит от часового пояса. От преобразования datetime.dateв метку времени UTC в Python :

  • объект даты представляет полночь в UTC

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
  • объект date представляет полночь по местному времени

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())

Временные метки различаются, если только полночь в UTC и местное время не совпадают с экземпляром времени.

JFS
источник
Когда я запускаю примеры в этой должности, я получаю ошибку: NameError: name 'wckCalendar' is not defined. Я использую Python 3.4.1 на 32-битной машине с Windows. Любая идея? Спасибо.
sedeh
1
@sedeh в посте нет wckCalendar. Проверьте свой код.
JFS
@JFSebastian Точно, и я не пытался вызвать wckCalendar напрямую. Это просто появляется в сообщении об ошибке. Смотрите мой пост здесь, обсуждая проблему.
sedeh
1
@ törzsmókus: Если ответ неправильный, не имеет значения, насколько он читаем.
JFS
1
@ törzsmókus: посмотрите на мой ответ: он может дать два разных числа. Ваш ответ дает одно число, не упоминая, какое.
JFS
21

Ответ зависит также от введенной вами даты и часового пояса. Если ваша дата является локальной, то вы можете использовать mktime (), как сказал katrielalex - только я не понимаю, почему он использовал datetime вместо этой более короткой версии:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

Но обратите внимание, что мой результат отличается от его, так как я, вероятно, нахожусь в другом TZ (и результат - метка времени UNIX без часового пояса)

Теперь, если введенная дата уже в UTC, то я считаю, что правильное решение:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600
Nowakus
источник
Я думаю, что это лучше. Нет необходимости импортировать «время» и «время-дата».
кеннют
17

Просто используйте datetime.datetime.strptime:

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

Результат:

1322697600

Чтобы использовать UTC вместо местного часового пояса, используйте .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()
nm111
источник
Для полного ответа вы должны сказать, что он действителен только для Python 3.3+
Эдуардо
На первом примере результат floatнеint
CONvid19
6

Сначала вы должны класс strptime, чтобы преобразовать строку в формат struct_time.

Тогда просто используйте mktime, чтобы получить ваш float.

Cryptite
источник
6

Многие из этих ответов не удосуживаются считать, что дата наивна с самого начала

Чтобы быть точным, вам нужно сначала сделать наивную дату осведомленной о часовом поясе

import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

Также:

Будьте осторожны, используя pytzдля tzinfoв datetime.datetimeработы не для многих часовых поясов. Смотрите дату и время с часовым поясом. Различное смещение в зависимости от того, как установлена ​​tzinfo

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://en.wikipedia.org/wiki/Local_mean_time

MRE
источник
6

Я бы предложил dateutil :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()
törzsmókus
источник
Это неверно. ОП ожидает время в "%d/%m/%Y"формате. Сравните: dateutil.parser.parse("01/02/2001")аdatetime.strptime("01/02/2001", "%d/%m/%Y")
JFS
спасибо @jfs, хороший улов. Я обновил свой ответ соответственно. (
Будучи
1
он не даст ожидаемого, 1322697600если ваш местный часовой пояс не UTC. Смотрите мой комментарий от 2014 года
JFS
4

Кажется довольно эффективным:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

1,61 мкс ± 120 нс на цикл (среднее ± стандартное отклонение из 7 циклов, 100000 циклов в каждом)

Gerard
источник
Что за datetimeфункция? datetimeиз datetimeбиблиотеки не поддерживает.timestamp()
Joooeey
@Joooeey: Да , на Python 3.3 или новее . Не был доступен, когда вопрос был опубликован, но он был доступен с сентября 2012 года.
ShadowRanger
0

просто используйте datetime.timestamp (ваш экземпляр datetime), экземпляр datetime содержит информацию о часовом поясе, поэтому отметка времени будет стандартной отметкой времени utc. если вы преобразуете дату и время в timetuple, он потеряет свой часовой пояс, поэтому результатом будет ошибка. если вы хотите предоставить интерфейс, вы должны написать так: int (datetime.timestamp (time_instance)) * 1000

user6689187
источник
0

Вы можете преобразовать в изоформ

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()
Aliens Dev
источник
-1

Простая функция для получения времени UNIX Epoch.

ПРИМЕЧАНИЕ . Эта функция предполагает, что введенное время даты указано в формате UTC (см. Комментарии здесь).

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
    import datetime, calendar
    ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
    return calendar.timegm(ts.utctimetuple())

Использование :

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600
gihanchanuka
источник