Время ISO (ISO 8601) в Python

У меня есть файл. В Python я хотел бы взять время его создания и преобразовать его в строку времени ISO (ISO 8601) при сохранении того факта, что он был создан в восточном часовом поясе (ET ).

Как мне взять ctime файла и преобразовать его в строку времени ISO, которая указывает восточный часовой пояс (и при необходимости учитывает летнее время)?


person Joseph Turian    schedule 27.01.2010    source источник
comment
возможный дубликат Как перевести строку даты и времени ISO 8601 в объект даты и времени Python?   -  person Nick Johnson    schedule 13.06.2010
comment
@ Nick - Полезная ссылка, но не дубликат - спрашивает про конвертацию наоборот.   -  person Yarin    schedule 19.12.2011
comment
@ Joseph - Я только что спросил об этом в отношении RFC 3999 - должно работать для этого - Создать метку времени RFC 3339 в Python   -  person Yarin    schedule 19.12.2011


Ответы (13)


Локально в соответствии с ISO 8601:

import datetime
datetime.datetime.now().isoformat()
>>> 2020-03-20T14:28:23.382748

UTC согласно ISO 8601:

import datetime
datetime.datetime.utcnow().isoformat()
>>> 2020-03-20T01:30:08.180856

Локально согласно ISO 8601 без микросекунд:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:30:43

UTC в ISO 8601 с информацией о часовом поясе (Python 3):

import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
>>> 2020-03-20T01:31:12.467113+00:00

UTC в ISO 8601 с информацией о местном часовом поясе без микросекунды (Python 3):

import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:31:43+13:00

Локально для ISO 8601 с информацией о часовом поясе (Python 3):

import datetime
datetime.datetime.now().astimezone().isoformat()
>>> 2020-03-20T14:32:16.458361+13:00

Обратите внимание, что есть ошибка при использовании astimezone() во времени utc. Это дает неверный результат:

datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result

Для Python 2 см. И используйте pytz.

person estani    schedule 26.01.2015
comment
.isoformat() может принимать параметр-разделитель (в случае, если вам нужно что-то другое, кроме "T"): .isoformat(' ') - person ThorSummoner; 25.08.2016
comment
@ThorSummoner полезно знать! Но позаботьтесь о том, чтобы изменение разделителя больше не соответствовало ISO-8601 ... что не имеет особого смысла (кроме того, есть более эффективные способы печати дат, но вопрос не в этом). RFC - person estani; 25.08.2016
comment
Пробелы разрешены в рамках стандарта ISO-8601. It is permitted to omit the 'T' character by mutual agreement. - person raychi; 07.09.2016
comment
@raychi Всегда разрешено изменять стандарт по взаимному согласию (что во многих случаях нарушает стандарт, но кого волнует, если это взаимное соглашение, верно?). Мой 2c: просто не надо, оставь как есть. - person estani; 08.09.2016
comment
Этот ответ неверен, потому что datetime.datetime.now (). Isoformat () возвращает локальную строку ISO 8601, не помечая ее как локальную. У вас должен быть datetime.timezone, представляющий местный часовой пояс, чтобы изоформат работал правильно. - person Sam Hartman; 01.05.2017
comment
Похоже, offset=utc_offset_sec следует заменить на offset=datetime.timedelta(seconds=-utc_offset_sec) - person imbolc; 06.04.2018
comment
Раздел Local to ISO-8601 with TimeZone info (python 3) можно улучшить, используя: datetime.datetime.now(datetime.timezone(datetime.timedelta(seconds=time.localtime().tm_gmtoff))).isoformat(). Нет необходимости заменять tzinfo, когда вы можете передать его now, и проблема altzone решается с помощью tm_gmtoff. - person ToBeReplaced; 14.07.2018
comment
Как получить формат ISO-8601 в Python? Потому что нам нужно strptime строку. %Y-%m-%dT%H:%M:%S%z возвращает -HHMM или +HHMM, но не -HH:MM. - person Simin Jie; 08.08.2018
comment
UTC в ISO-8601 с информацией о часовом поясе (использует pytz) datetime.datetime.now(tz=pytz.utc).isoformat() - person Christian Long; 06.09.2018
comment
но мое другое время приложения javascript находится в формате 2019-02-23T04:01:55.360Z, Z для смещения нулевого часа, разве нет варианта для этого формата? - person Miranda; 25.02.2019
comment
UTC в ISO-8601 с информацией о часовом поясе (Python 3, без pytz): datetime.datetime.now(tz=datetime.timezone.utc).isoformat() - person Vinod Kurup; 05.09.2019
comment
Отсутствие буквы «Т» не меняет стандарт, поскольку он является частью стандарта ISO 8601. - person tomsv; 23.11.2019
comment
У меня были плохие времена, используя datetime.replace(tzinfo)! Я бы сказал: избегайте этого! Это добавляет минуты между преобразованиями. Вместо этого используйте pytz.localize(). Подробнее см. здесь. - person Renato Aloi; 17.06.2021

Вот что я использую для преобразования в формат даты и времени XSD:

from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string

Я столкнулся с этим вопросом, когда искал формат даты и времени XSD (xs:dateTime). Мне нужно было убрать микросекунды с isoformat.

person radtek    schedule 30.11.2015
comment
Что такое XSD (в данном контексте)? - person Peter Mortensen; 24.10.2018
comment
Я считаю, что он имеет в виду xs:date из таблиц стилей XSD / XML. - person sventechie; 17.11.2018
comment
Это означает xs:dateTime - person radtek; 19.11.2018

Представление времени в соответствии с ISO 8601

Международный стандарт ISO 8601 описывает строковое представление даты и времени. Два простых примера этого формата:

2010-12-16 17:22:15
20101216T172215

(которые оба означают 16 декабря 2010 г.), но формат также позволяет использовать время разрешения менее секунды и указывать часовые пояса. Этот формат, конечно, не зависит от Python, но он хорош для хранения даты и времени в переносимом формате. Подробности об этом формате можно найти в записи Маркуса Куна .

Я рекомендую использовать этот формат для хранения времени в файлах.

Один из способов получить текущее время в этом представлении - использовать strftime из модуля времени в стандартной библиотеке Python:

>>> from time import strftime
>>> strftime("%Y-%m-%d %H:%M:%S")
'2010-03-03 21:16:45'

Вы можете использовать конструктор strptime класса datetime:

>>> from datetime import datetime
>>> datetime.strptime("2010-06-04 21:08:12", "%Y-%m-%d %H:%M:%S")
datetime.datetime(2010, 6, 4, 21, 8, 12)

Самым надежным является модуль Egenix mxDateTime:

>>> from mx.DateTime.ISO import ParseDateTimeUTC
>>> from datetime import datetime
>>> x = ParseDateTimeUTC("2010-06-04 21:08:12")
>>> datetime.fromtimestamp(x)
datetime.datetime(2010, 3, 6, 21, 8, 12)

Ссылки

person Voislav Sauca    schedule 16.12.2010
comment
В каком смысле он более надежен? - person Stéphane; 29.07.2017
comment
Дата: 2018-05-25 - person loxaxs; 25.05.2018
comment
Дата и время в формате UTC: 2018-05-25T12:16:14+00:00 - person loxaxs; 25.05.2018
comment
Дата и время в формате UTC: 2018-05-25T12:16:14Z - person loxaxs; 25.05.2018
comment
Дата и время в формате UTC: 20180525T121614Z - person loxaxs; 25.05.2018
comment
как создать эту комбинированную дату и время в UTC: 2018-05-25T12: 16: 14Z @Ioxaxs - person Khan; 01.12.2018

ISO 8601 допускает компактное представление без разделителей, за исключением T, поэтому мне нравится использовать этот однострочник, чтобы получить быструю строку временной метки:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'

Если микросекунды вам не нужны, просто опустите часть .%f:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'

По местному времени:

>>> datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
'20180905T140903'

Редактировать:

Прочитав это еще раз, я рекомендую оставить знаки препинания. RFC 3339 рекомендует этот стиль потому что, если все будут использовать знаки препинания, нет риска, что несколько строк ISO 8601 будут отсортированы в группы по их знакам препинания. Таким образом, один вкладыш для совместимой строки будет:

>>> datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
'2018-09-05T14:09:03Z'
person Jim Hunziker    schedule 05.09.2018
comment
есть ли способ ограничить количество миллисекунд до 3? то есть мое другое приложение javascript будет создавать 2019-02-23T04:02:04.051Z с new Date().toISOString() - person Miranda; 25.02.2019
comment
Предупреждение: буква «Z» в конце неверна. Правильный способ вывода часового пояса, включая символ «Z», - «% z» или «% Z», что делает его «datetime.datetime.now (). Strftime (% Y-% m-% dT% H: % M:% S% z) '. Я потратил 2 часа, пытаясь найти ошибку в моем коде ... - person Dr_Zaszuś; 31.07.2020
comment
@ Dr_Zaszuś Это неправильно. % z генерирует смещение часового пояса для вашего местного времени, что я не рекомендую для отметок времени, особенно если вы смотрите на несколько систем. Буквальный Z является сокращением ISO 8601 для UTC. - person Jim Hunziker; 03.08.2020
comment
@Miranda javascript, например output datetime.datetime.now (datetime.timezone.utc) .isoformat () [: 23] + Z - person seizu; 03.04.2021

Я нашел datetime.isoformat в документации. Кажется, ты делаешь то, что хочешь:

datetime.isoformat([sep])

Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if microsecond is 0, YYYY-MM-DDTHH:MM:SS

If utcoffset() does not return None, a 6-character string is appended, giving the UTC offset in (signed) hours and minutes: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or, if microsecond is 0 YYYY-MM-DDTHH:MM:SS+HH:MM

The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result. For example,
>>>

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
person user2120810    schedule 28.02.2013

Формат времени ISO 8601 не хранит название часового пояса, только соответствующее время в формате UTC. смещение сохраняется.

Чтобы преобразовать файл ctime в строку времени ISO 8601 при сохранении смещения UTC в Python 3:

>>> import os
>>> from datetime import datetime, timezone
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, timezone.utc)
>>> dt.astimezone().isoformat()
'2015-11-27T00:29:06.839600-05:00'

Код предполагает, что ваш местный часовой пояс Восточный часовой пояс (ET) и что ваша система предоставляет правильный Смещение UTC для данной отметки времени POSIX (ts), т. Е. Python имеет доступ к базе данных исторических часовых поясов в вашей системе, или часовой пояс имел те же правила в заданную дату.

Если вам нужно портативное решение; используйте модуль pytz, который обеспечивает доступ к база данных tz:

>>> import os
>>> from datetime import datetime
>>> import pytz  # pip install pytz
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, pytz.timezone('America/New_York'))
>>> dt.isoformat()
'2015-11-27T00:29:06.839600-05:00'

В этом случае результат такой же.

Если вам нужно название часового пояса / аббревиатуру / идентификатор зоны, сохраните его отдельно.

>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)')
'2015-11-27 00:29:06-0500 (EST)'

Примечание: нет, : в смещении UTC и аббревиатура EST часового пояса не являются частью формата времени ISO 8601. Это не уникально.

Различные библиотеки / разные версии одной и той же библиотеки могут использовать разные правила часовых поясов для одной даты / часового пояса. Если это дата в будущем, правила могут быть еще неизвестны. Другими словами, одно и то же время в формате UTC может соответствовать разному местному времени в зависимости от того, какие правила вы используете - при сохранении времени в формате ISO 8601 сохраняется время в формате UTC и местное время, которое соответствует текущему времени. правила зоны, используемые на вашей платформе. Возможно, вам придется пересчитать местное время на другой платформе, если для нее действуют другие правила.

person jfs    schedule 28.11.2015

Вам нужно будет использовать os.stat, чтобы получить время создания файла, и комбинацию time.strftime и time.timezone для форматирования:

>>> import time
>>> import os
>>> t = os.stat('C:/Path/To/File.txt').st_ctime
>>> t = time.localtime(t)
>>> formatted = time.strftime('%Y-%m-%d %H:%M:%S', t)
>>> tz = str.format('{0:+06.2f}', float(time.timezone) / 3600)
>>> final = formatted + tz
>>> 
>>> final
'2008-11-24 14:46:08-02.00'
person Max Shawabkeh    schedule 27.01.2010
comment
Учитывает ли часовой пояс летнее время? Похоже, что tz будет одинаковым вне зависимости от перехода на летнее время или нет. - person Joseph Turian; 29.01.2010
comment
Это будет любое смещение, действующее в данный момент. Если DST активен, он будет иметь другое смещение, чем когда DST не активен. - person Max Shawabkeh; 29.01.2010

Для тех, кто ищет решение только для дат, это:

import datetime

datetime.date.today().isoformat()
person Alexander Zinchuk    schedule 14.09.2020
comment
Я сделал это таким образом, чтобы не импортировать больше, чем класс datetime: from datetime import datetime; datetime.now (). isoformat () [: 10] (извините, я не могу найти этот фрагмент кода) - person David Elgstuen; 15.07.2021

Поправьте меня, если я ошибаюсь (это не так), но смещение от UTC меняется с переходом на летнее время. Итак, вы должны использовать

tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)

Я тоже считаю, что знак должен быть другим:

tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)

Могу ошибаться, но я так не думаю.

person Jarek Przygódzki    schedule 08.06.2010

Я согласен с Яреком, и, кроме того, отмечу, что символ разделителя смещения ISO - это двоеточие, поэтому я думаю, что окончательный ответ должен быть таким:

isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')
person mattbornski    schedule 27.10.2010


Стандартный RFC-3339 в миллисекундах

Мне нужно было время в этом формате для приложения LoRa, поэтому я придумал это, надеюсь, это поможет:

from datetime import datetime
from time import strftime


# Get the current time in the format: 2021-03-20T16:51:23.644+01:00
def rfc3339_time_ms():
        datetime_now = datetime.utcnow()
        # Remove the microseconds
        datetime_now_ms = datetime_now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
        # Add the timezone as "+/-HHMM", and the colon in "+/-HH:MM"
        datetime_now_ms_tz = datetime_now_ms + strftime("%z")
        rfc3339_ms_now = datetime_now_ms_tz[:-2] + ":" + datetime_now_ms_tz[-2:]
        # print(f"Current time in ms in RFC-3339 format: {rfc3339_ms_now}")
        return rfc3339_ms_now
person chronoclast    schedule 20.03.2021

Я разработал эту функцию:

def iso_8601_format(dt):
    """YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)"""

    if dt is None:
        return ""

    fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S')
    tz = dt.utcoffset()
    if tz is None:
        fmt_timezone = "+00:00"
    else:
        fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds() / 3600))

    return fmt_datetime + fmt_timezone
person Andre Avilla    schedule 08.11.2016