Python 如何在Django中舍入时区感知日期
我正在尝试将默认时区Python 如何在Django中舍入时区感知日期,python,django,datetime,timezone,Python,Django,Datetime,Timezone,我正在尝试将默认时区datetime转换为localtime,并在Django视图中将时间舍入到15分钟。我有以下往返时间功能: def roundTime(dt=None, dateDelta=timedelta(minutes=1)): """Round a datetime object to a multiple of a timedelta dt : datetime.datetime object, default now. dateDelta : timed
datetime
转换为localtime
,并在Django视图中将时间舍入到15分钟。我有以下往返时间功能:
def roundTime(dt=None, dateDelta=timedelta(minutes=1)):
"""Round a datetime object to a multiple of a timedelta
dt : datetime.datetime object, default now.
dateDelta : timedelta object, we round to a multiple of this, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
Stijn Nevens 2014 - Changed to use only datetime objects as variables
"""
roundTo = dateDelta.total_seconds()
if dt == None:
dt = datetime.now()
seconds = (dt - dt.min).seconds
# // is a floor division, not a comment on following line:
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + timedelta(0,rounding-seconds,-dt.microsecond)
以下是我迄今为止所做的尝试:
mytime = roundTime(datetime.now(),timedelta(minutes=15)).strftime('%H:%M:%S') #works OK
mytime = datetime.strptime(str(mytime), '%H:%M:%S') #works OK
mytime = timezone.localtime(mytime)
但最后一行给了我这个错误:
错误:astimezone()无法应用于原始日期时间
当我使用:
local_time = timezone.localtime(timezone.now())
我确实得到了正确的当地时间,但由于某些原因,我无法通过执行以下操作来调整时间:
mytime = roundTime(local_time,timedelta(minutes=15)).strftime('%H:%M:%S')
它与上面的datetime.now()配合使用
我想出了一个不漂亮但有效的代码:
mytime = timezone.localtime(timezone.now())
mytime = datetime.strftime(mytime, '%Y-%m-%d %H:%M:%S')
mytime = datetime.strptime(str(mytime), '%Y-%m-%d %H:%M:%S')
mytime = roundTime(mytime,timedelta(minutes=15)).strftime('%H:%M:%S')
mytime = datetime.strptime(str(mytime), '%H:%M:%S')
有更好的解决方案吗?您正在使用的roundTime
功能不适用于时区感知日期。
要支持它,您可以这样修改它:
def roundTime(dt=None, dateDelta=timedelta(minutes=1)):
"""Round a datetime object to a multiple of a timedelta
dt : datetime.datetime object, default now.
dateDelta : timedelta object, we round to a multiple of this, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
Stijn Nevens 2014 - Changed to use only datetime objects as variables
"""
roundTo = dateDelta.total_seconds()
if dt == None :
dt = datetime.now()
#Make sure dt and datetime.min have the same timezone
tzmin = dt.min.replace(tzinfo=dt.tzinfo)
seconds = (dt - tzmin).seconds
# // is a floor division, not a comment on following line:
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + timedelta(0,rounding-seconds,-dt.microsecond)
通过这种方式,该函数可以处理naive和TZ感知日期。
然后,您可以继续进行第二次尝试:
local_time = timezone.localtime(timezone.now())
mytime = roundTime(local_time, timedelta(minutes=15))
您正在使用的roundTime
功能不适用于时区感知日期。
要支持它,您可以这样修改它:
def roundTime(dt=None, dateDelta=timedelta(minutes=1)):
"""Round a datetime object to a multiple of a timedelta
dt : datetime.datetime object, default now.
dateDelta : timedelta object, we round to a multiple of this, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
Stijn Nevens 2014 - Changed to use only datetime objects as variables
"""
roundTo = dateDelta.total_seconds()
if dt == None :
dt = datetime.now()
#Make sure dt and datetime.min have the same timezone
tzmin = dt.min.replace(tzinfo=dt.tzinfo)
seconds = (dt - tzmin).seconds
# // is a floor division, not a comment on following line:
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + timedelta(0,rounding-seconds,-dt.microsecond)
通过这种方式,该函数可以处理naive和TZ感知日期。
然后,您可以继续进行第二次尝试:
local_time = timezone.localtime(timezone.now())
mytime = roundTime(local_time, timedelta(minutes=15))
要舍入时区感知的日期时间对象,请执行以下操作:
为了避免浮点问题,可以使用整数微秒(dt.resolution
)重写所有计算
例如:
>>> round_time(delta=timedelta(minutes=15))
要舍入时区感知的日期时间对象,请执行以下操作:
为了避免浮点问题,可以使用整数微秒(dt.resolution
)重写所有计算
例如:
>>> round_time(delta=timedelta(minutes=15))
roundTime
是你的功能吗?如果是,你能显示它的代码吗?我已经发布了roundTime
和我想出的一个工作代码。roundTime
是你的功能吗?如果是,你能显示它的代码吗?我已经发布了roundTime
和我想出的一个工作代码。谢谢你的帮助。我不想弄乱其他地方也在使用的往返时间函数。也许我可以为时区的需要做另一个版本。再次感谢你的帮助!此新版本在代码的其余部分中的行为将与以前相同,它只支持以前未使用过的新用例(您可以确定您没有使用它,因为您可能会遇到错误)@WayBehind:舍入可能会跨越DST边界,因此。感谢您的帮助。我不想弄乱其他地方也在使用的往返时间函数。也许我可以为时区的需要做另一个版本。再次感谢你的帮助!这个新版本在您的代码的其余部分中的行为将与以前一样,它只支持您以前没有使用过的新用例(您可以确定您没有使用它,因为您可能会遇到错误)@WayBehind:舍入可能会跨越DST边界,因此。