在Python中生成RFC3339时间戳
我正在尝试用Python生成UTC时间戳。到目前为止,我已经能够做到以下几点:在Python中生成RFC3339时间戳,python,datetime,iso8601,rfc3339,Python,Datetime,Iso8601,Rfc3339,我正在尝试用Python生成UTC时间戳。到目前为止,我已经能够做到以下几点: >>> d = datetime.datetime.now() >>> print d.isoformat('T') 2011-12-18T20:46:00.392227 我的问题是设置UTC偏移量 根据,classmethoddatetime.now([tz])采用可选的tz参数,其中tz必须是类tzinfo子类的实例,而datetime.tzinfo是时区信息对象的抽象基类。
>>> d = datetime.datetime.now()
>>> print d.isoformat('T')
2011-12-18T20:46:00.392227
我的问题是设置UTC偏移量
根据,classmethoddatetime.now([tz])
采用可选的tz
参数,其中tz必须是类tzinfo子类的实例,而datetime.tzinfo
是时区信息对象的抽象基类。
这就是我迷路的地方——为什么tzinfo是一个抽象类,我应该如何实现它
(注意:在PHP中,它就像
timestamp=date(date_rfc339);
一样简单,这就是为什么我无法理解Python的方法如此复杂的原因…时区是一种痛苦,这可能就是为什么他们选择不将它们包含在datetime库中
试试pytz,它有你想要的tzinfo:
您需要首先创建datetime
对象,然后像下面那样应用时区,然后您的.isoformat()
输出将根据需要包括UTC偏移:
d = datetime.datetime.utcnow()
d_with_timezone = d.replace(tzinfo=pytz.UTC)
d_with_timezone.isoformat()
“2017-04-13T14:34:23.111142+00:00”
或者,只需使用UTC,并在末尾抛出一个“Z”(代表祖鲁时区),将“时区”标记为UTC
d=datetime.datetime.utcnow()#我刚刚开始使用的另一个有用的实用工具:用于时区处理和日期解析的库。建议这样做,包括Python 3.3+中的这一点:
>>> from datetime import datetime, timezone
>>> local_time = datetime.now(timezone.utc).astimezone()
>>> local_time.isoformat()
'2015-01-16T16:52:58.547366+01:00'
在较早的Python版本中,如果您只需要一个表示当前UTC时间的aware datetime对象,那么您可以:
您还可以使用获取代表本地时区的pytz
时区:
#!/usr/bin/env python
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal
now = datetime.now(get_localzone())
print(now.isoformat('T'))
它可以在Python2和Python3上工作。该软件包可用于Python2.X和3.X。它实现了tzinfo
的具体子类以及其他服务,因此您不必这样做
要添加UTC偏移,请执行以下操作:
导入日期时间
进口皮茨
dt = datetime.datetime(2011, 12, 18, 20, 46, 00, 392227)
utc_dt = pytz.UTC.localize(dt)
现在这个:
print utc_dt.isoformat()
将打印:
2011-12-18T20:46:00.392227+00:00
我在RFC3339 datetime格式方面做了很多努力,但我找到了一个合适的解决方案,可以在两个方向上转换date\u字符串datetime\u对象
您需要两个不同的外部模块,因为其中一个模块只能在一个方向上进行转换(很遗憾):
首次安装:
sudo pip install rfc3339
sudo pip install iso8601
然后包括:
import datetime # for general datetime object handling
import rfc3339 # for date object -> date string
import iso8601 # for date string -> date object
为了不需要记住哪个模块是哪个方向的,我编写了两个简单的辅助函数:
def get_date_object(date_string):
return iso8601.parse_date(date_string)
def get_date_string(date_object):
return rfc3339.rfc3339(date_object)
在您的代码中,您可以像这样轻松地使用:
input_string = '1989-01-01T00:18:07-05:00'
test_date = get_date_object(input_string)
# >>> datetime.datetime(1989, 1, 1, 0, 18, 7, tzinfo=<FixedOffset '-05:00' datetime.timedelta(-1, 68400)>)
test_string = get_date_string(test_date)
# >>> '1989-01-01T00:18:07-05:00'
test_string is input_string # >>> True
input_string='1989-01-01T00:18:07-05:00'
测试日期=获取日期对象(输入字符串)
#>>>datetime.datetime(1989,1,1,0,18,7,tzinfo=)
测试字符串=获取日期字符串(测试日期)
#“1989-01-01T00:18:07-05:00”
测试字符串为输入字符串#>>>True
海瑞卡!现在,您可以轻松地(哈哈)使用日期字符串和可用格式的日期字符串。您确实可以使用内置的
模块。作为
,在
显示如何操作的页面。如果你看一下
你会
请参阅显示许多不同用例的长示例。这是这个的代码
您正在寻找,即生成RFC 3339 UTC时间戳
from datetime import tzinfo, timedelta, datetime
import time as _time
ZERO = timedelta(0)
STDOFFSET = timedelta(seconds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds=-_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
d = datetime.now(Local)
print d.isoformat('T')
# which returns
# 2014-04-28T15:44:45.758506-07:00
在现代(3.x)python上,要获得RFC 3339 UTC时间,只需使用datetime和这一行(无需第三方模块):
结果是这样的:“2019-06-13T15:29:28.972488+00:00”
这个ISO 8601字符串也与RFC3339兼容。@monkut-谢谢-pytz类看起来像是另一个可以工作的实现,但根据ruakh的回答,我最终使用了文档中包含的示例。它不会为我返回微秒:-/如果您只想使用UTC时区,则不需要pytz
模块。感谢很简单。我会把你的答案留到我需要stdlib解决方案的时候。UTC是最短的演示时间。OP并没有特别要求pytz
知道所有时区及其DST,我觉得这很有用。注意:返回与本地时区对应的puts时区。是。它应该是“pytz
timezone”,而不是“put
timezone”,这是python3.3+@villapx的最佳答案:rfc3339是iso8601的配置文件。碰巧,datetime.isoformat()
是RFC 3339,用于时区感知的日期时间(这就是我使用它的原因)。@villapx:不,它是错误的。你在误导“潜在用户”。如果.utcoffset()
未反映.dst()
值,则您的日期时间
类将被破坏。@J.F.Sebastian噢,哇,您是对的。我完全被datetime.tzinfo.dst()
误导了:请注意,dst偏移量(如果适用)已经添加到utcoffset()返回的UTC偏移量中,因此没有必要咨询dst(),除非您有兴趣单独获取dst信息。
对于utcoffset()
,我没有直接看到上面的内容,其中指出,“请注意,这是UTC的总偏移量。”
@jrc:now()本身可能不明确(例如,在DST转换期间)。“Heureka”。丢失“H”。实际上Python datetime与ISO 8601不兼容,因为它不允许在链接到的同一文档中以“Z”结尾的字符串,它解释了如何实现它,并给出了一些示例,包括UTC
类(表示UTC)的完整代码,一个FixedOffset
类(表示与UTC有固定偏移量的时区,而不是带有DST和诸如此类的时区)和其他一些。@ruakh-谢谢,我错过了这些示例-LocalTimezone()
类完成了这个任务。刚刚发现了类似的问题:
input_string = '1989-01-01T00:18:07-05:00'
test_date = get_date_object(input_string)
# >>> datetime.datetime(1989, 1, 1, 0, 18, 7, tzinfo=<FixedOffset '-05:00' datetime.timedelta(-1, 68400)>)
test_string = get_date_string(test_date)
# >>> '1989-01-01T00:18:07-05:00'
test_string is input_string # >>> True
from datetime import tzinfo, timedelta, datetime
import time as _time
ZERO = timedelta(0)
STDOFFSET = timedelta(seconds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds=-_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
d = datetime.now(Local)
print d.isoformat('T')
# which returns
# 2014-04-28T15:44:45.758506-07:00
import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()