在Python中,如何打印完整的iso8601时间戳,包括当前的timezon

2024-10-01 11:33:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要以ISO 8601格式打印完整的本地日期/时间,包括本地时区信息,例如:

2007-04-05T12:30:00.0000-02:00

{tzi>如何使用这个对象?在

注意,我一直停留在python2.5上,这可能会降低一些选项的可用性。在


Tags: 对象信息格式选项时间iso可用性tzi
3条回答

接受@xorsyst的回答现在给了我错误的结果(2018年3月21日,欧洲/沃索区):

2018-03-21 19:02:10+00:59

(应为:2018-03-21 19:02:10+01:00)

@kwoldt给出的答案更好,但需要一个适当的偏移量参数。他的例子给出了糟糕的结果:

^{pr2}$

(应为:2018-03-21T19:06:54.024151+01:00)

我找到了一个对我有用的解决方案:

import datetime
import time

def local_datetime_isoformat():
    ts = time.time()
    local_dt = datetime.datetime.fromtimestamp(ts)
    struct_tm = time.localtime(ts)
    offset = time.altzone if struct_tm.tm_isdst else time.timezone
    local_iso = local_dt.isoformat(' ')
    if offset:
        sign = '+' if offset < 0 else '-'
        offset_hours = abs(offset) // 3600
        offset_minutes = (abs(offset) % 3600) // 60
        local_iso += '{0}{1:0<2}:{2:0<2}'.format(sign, offset_hours, offset_minutes)
    else:
        local_iso += 'Z'
    return local_iso

>>> print local_datetime_isoformat()
2018-03-21 19:04:03.631014+01:00

我已经想出了自己的方法,希望这对其他想要在输出文件中打印有用时间戳的人有用。在

import datetime

# get current local time and utc time
localnow = datetime.datetime.now()
utcnow = datetime.datetime.utcnow()

# compute the time difference in seconds
tzd = localnow - utcnow
secs = tzd.days * 24 * 3600 + tzd.seconds

# get a positive or negative prefix
prefix = '+'
if secs < 0:
    prefix = '-'
    secs = abs(secs)

# print the local time with the difference, correctly formatted
suffix = "%s%02d:%02d" % (prefix, secs/3600, secs/60%60)
now = localnow.replace(microsecond=0)
print "%s%s" % (now.isoformat(' '), suffix)

这感觉有点老套,但似乎是获得具有正确UTC偏移量的本地时间的唯一可靠方法。更好的答案欢迎!在

python标准库不提供tzinfo实现。你需要将其子类化。示例在datetime module中提供。在

接受的答案提供了错误的结果。例如,在我的时区+02中,结果是+01:59。这是因为在计算差值之前,需要在localnow和utcnow上对0进行微秒级的替换。在

这里是我的python 2.5版本:

# coding=utf-8


def isoformat_offset(dt, offset, dt_sep='T', hm_sep=True, short=True):
    """Return a string representing the date and time in ISO 8601 format,
    YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM. If microseconds is 0 .mmmmmm is omitted.
    The optional argument dt_sep (default 'T') is a one-character separator,
    placed between the date and time portions of the result.
    The optional argument hm_Sep (default True) indicates if a : separator
    should be placed between the hours and minutes portions of the time zone
    designator.
    The optional argument short (default True) defines if the minute portion of
    the time zone designator should be omitted in the case of zero minutes.

        >>> from datetime import datetime
        >>> cur = datetime(2017, 4, 26, 17, 14, 23, 123456)
        >>> off = 2 * 3600 # +02:00
        >>> isoformat_offset(cur, off)
        '2017-04-26T17:14:23.123456+02'
        >>> isoformat_offset(cur, off, ' ')
        '2017-04-26 17:14:23.123456+02'
        >>> isoformat_offset(cur, off, hm_sep=False)
        '2017-04-26T17:14:23.123456+02'
        >>> isoformat_offset(cur, off, short=False)
        '2017-04-26T17:14:23.123456+02:00'
        >>> isoformat_offset(cur, off, hm_sep=False, short=False)
        '2017-04-26T17:14:23.123456+0200'
        >>> cur = cur.replace(microsecond=0)
        >>> isoformat_offset(cur, off)
        '2017-04-26T17:14:23+02'
        >>> off = -2 * 3600 # -02:00
        >>> isoformat_offset(cur, off)
        '2017-04-26T17:14:23-02'
        >>> off = 2 * 3600 + 30 * 60 # +02:30
        >>> isoformat_offset(cur, off)
        '2017-04-26T17:14:23+02:30'
        >>> isoformat_offset(cur, off, hm_sep=False)
        '2017-04-26T17:14:23+0230'
    """
    offset_hours = offset // 3600
    offset_mins = (offset - offset_hours * 3600) // 60
    frmt = '%s%+03d'
    args = [dt.isoformat(dt_sep), offset_hours]
    if (short is True and offset_mins > 0) or (short is False and offset_mins == 0):
        if hm_sep is True:
            frmt += ':'
        frmt += '%02d'
        args.append(offset_mins)
    return frmt % tuple(args)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

要根据此函数的需要以秒为单位获取本地时区,请使用time module中的否定altzone:

^{pr2}$

相关问题 更多 >