python什么时候诞⽣的_关于RFC3339⽇期时间:在Python中
产⽣timestamp
我正在尝试在python中⽣成⼀个RFC3339 UTC时间戳。到⽬前为⽌,我已经能够做到以下⼏点:
>>> d = w()
>>> print d.isoformat('T')
2011-12-18T20:46:00.392227
我的问题是设置UTC偏移量。
根据⽂档,类⽅法w([tz])采⽤可选的tz参数,其中tz must be an instance of a class tzinfo subclass和info是an abstract ba class for time zone information objects.参数。
这就是我迷路的地⽅——为什么TZINFO是⼀个抽象类,我应该如何实现它?
(注意:在PHP中,它和timestamp = date(DATE_RFC3339);⼀样简单,这就是为什么我不理解为什么python的⽅法如此复杂的原因…)
刚刚发现了类似的问题:Python中的iso时间(iso8601)?
时区是⼀种痛苦,这可能就是为什么它们选择不将它们包括在⽇期时间库中的原因。
您需要⾸先创建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() #
print d.isoformat("T") +"Z"
'2017-04-13T14:34:23.111142Z'
@Monkut-谢谢-Pytz类看起来像另⼀个可以⼯作的实现,但是我最终使⽤了包含在⽂档中的⽰例,按照Ruakh的答案。
@蒙库特-+1你的第⼆个例⼦也是个好主意。
它不会为我返回微秒:-/
在Python 3.3 +中:
>>> from datetime import datetime, timezone
>>> local_time = w(timezone.utc).astimezone()
>>> local_time.isoformat()
'2015-01-16T16:52:58.547366+01:00'
在旧的python版本上,如果只需要⼀个以UTC表⽰当前时间的感知⽇期时间对象,那么可以定义⼀个简单的TZINFO⼦类,如⽂档中所⽰,以表⽰UTC时区:
from datetime import datetime
utc_now = w(utc)
print(utc_now.isoformat('T'))
# -> 2015-05-19T20:32:12.610841+00:00
您还可以使⽤tzlocal模块获取表⽰您的本地时区的pytz时区:
#!/usr/bin/env python
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal
now = w(get_localzone())
print(now.isoformat('T'))
它可以在python 2和3上⼯作。
⼿放低,python 3.3的最佳答案+
从技术上讲,ISO 8601和RFC 3339不完全兼容……存在⼀些差异,例如ISO 8601允许UTC偏移部分使⽤减号或连字符,⽽RFC 3339只允许使⽤连字符。到⽬前为⽌,我看到的每⼀个.isoformat()实现(只有两个)都与RFC3339重叠,但最好让⾃⼰意识到这些差异
@Villapx:RFC3339是ISO 8601的简介。碰巧,datetime.isoformat()是⽤于时区感知⽇期时间的RFC3339(这就是我使⽤它的原因)。
@J.F.Sebastian是的,看起来你是对的……从⽂件中,isotime()[gives] the UTC offt in (signed) hours and minutes: YYYY-MM-DDTHH:+HH:MM,这是RFC3339。它没有明确地说它将使⽤连字符,⽽不是减号,但它是由⽰例所隐含的
虽然,isoformat()没有考虑tzinfo对象的夏令时偏移量——当我更改dst()返回值时,isoformat()仍然返回相同的字符串。
@villapx:isoformat()返回正确的值,它只是反映datetime对象包含的内容。也就是说,它显⽰了它的.utcofft()值。
@J.F.Sebastian是的,这就是我的意思——只是想让潜在⽤户知道isoformat()不知道DST
@维拉克斯:不,是错的。你误导了"潜在⽤户"。如果.utcofft()没有反映.dst()的值,那么你的dateti
me类就坏了。
@J.F.塞巴斯蒂安哦,哇,你说得对。我完全被info.dst()⽂件误导了:Note that DST offt, if applicable, has already been added to the UTC offt returned by utcofft(), so there’s no need to consult dst() unless you’re interested in obtaining DST info parately.我没有直接在上⾯看到,对于utcofft()⽂件,上⾯写着"Note that this is intended to be the total offt from UTC."。
在您链接到的同⼀个⽂档中,它进⼀步解释了如何实现它,给出了⼀些⽰例,包括UTC类(表⽰UTC)的完整代码、FixedOfft类(表⽰与UTC有固定偏移的时区,⽽不是带有dst和whatnot的时区)以及其他⼀些⽰例。
@Ruakh-谢谢,我错过了那些例⼦-LocalTimezone()班的技巧。
@雅林:不客⽓!
@吉恩·伍德:希望你不要介意,我已经恢复了你的编辑。问题是,您实现的内容与OP实际需要的内容不匹配。
@鲁克没问题。我误解了。这是否是解决OP问题的代码⽰例?:/gene1wood/11386298
为什么不在问题中包括⼀个完整的⽰例⽽不是链接,这是stackoverflow的⾸选⽅法?@吉恩·伍德,为什么不⽤你的全部答案创造⼀个新的答案呢?
@Joakim当然,这是完整的答案
我很难使⽤rfc339⽇期时间格式,但我找到了⼀个合适的解决⽅案来在两个⽅向上转换⽇期字符串<=>datetimeu对象。
您需要两个不同的外部模块,因为其中⼀个模块只能在⼀个⽅向上进⾏转换(不幸的是):
第⼀次安装:
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.par_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=)
test_string = get_date_string(test_date)
# >>> '1989-01-01T00:18:07-05:00'
test_string is input_string # >>> True
尤⾥卡!现在,您可以轻松地(哈哈)使⽤⽇期字符串和⽇期字符串的可⽤格式。
"HueCKA"。失去"H"。
pytz包可⽤于python 2.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
如果您只需要UTC时区,则不需要pytz模块。定义UTC TZINFO很简单
谢谢。当我需要stdlib解决⽅案时,我会保存您的答案。UTC只是最短的⼀个例⼦。OP没有特别要求。pytz知道所有时区及其DST,我觉得这很有⽤。
注:在我的回答中,get_localzone()返回与本地时区相对应的时区。
我想它会返回pytz时区。⾃动更正?
对。应该是"pytz时区",⽽不是"puts时区"
您确实可以使⽤内置的⽇期时间模块。AS卢卡提到,在显⽰⽅式的页⾯。如果你看⼀下你会的请参阅⼀个显⽰许多不同⽤例的长⽰例。这是密码您正在寻找,它将⽣成⼀个RFC3339 UTC时间戳。
from datetime import tzinfo, timedelta, datetime
import time as _time
ZERO = timedelta(0)
STDOFFSET = timedelta(conds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(conds=-_time.altzone)
el:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcofft(lf, dt):
if lf._isdst(dt):
return DSTOFFSET
el:
return STDOFFSET
def dst(lf, dt):
if lf._isdst(dt):
return DSTDIFF
el:
return ZERO
def tzname(lf, dt):
return _ame[lf._isdst(dt)]
def _isdst(lf, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.cond,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
_isdst > 0
Local = LocalTimezone()
d = w(Local)
print d.isoformat('T')
# which returns
# 2014-04-28T15:44:45.758506-07:00
我刚开始使⽤的另⼀个有⽤的实⽤程序:⽤于时区处理和⽇期分析的dateutil库。推荐,包括这个答案