python 标准库不提供 tzinfo 实现。您需要将其子类化。中提供了示例日期时间模块 https://docs.python.org/2/library/datetime.html#tzinfo-objects.
接受的答案提供了错误的结果。例如,在我的时区 +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()
要根据此功能的需要获取本地时区(以秒为单位),请使用否定的 altzone时间模块 https://docs.python.org/2/library/time.html#time.altzone:
from datetime import datetime
import time
now = datetime.now()
offset = -time.altzone
print(isoformat_offset(now, offset))