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

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

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

Ответ 1

Локальный по ISO-8601:

import datetime
datetime.datetime.now().isoformat()

UTC по ISO-8601:

import datetime
datetime.datetime.utcnow().isoformat()

Ответ 2

Я нашел datetime.isoformat в doc; кажется, делает то, что вы хотите:

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'

Ответ 3

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)

Ссылки

Ответ 4

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

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

Я столкнулся с этим вопросом при поиске формата даты XSD. Мне нужно было удалить микросекунды с isoformat. Ура!

Ответ 5

Формат времени ISO8601 не сохраняет имя часового пояса, сохраняется только соответствующее смещение 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'

В коде предполагается, что ваш часовой пояс - это Восточный часовой пояс и что ваша система обеспечивает правильное смещение 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)'

Примечание: no : в смещении utc и EST сокращение от часовой пояс не является частью формата времени ISO8601. Это не уникально.

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

Ответ 6

Вам понадобится 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'

EDIT: Переключено с gmtime() на localtime().

Ответ 7

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

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

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

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

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

Ответ 8

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

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

Ответ 9

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

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

Ответ 10

import datetime, time    
def convert_enddate_to_seconds(self, ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
     dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds 

>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26