如何在Djang中取整时区软件日期

2024-05-23 14:42:57 发布

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

我试图将默认时区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)

以下是我迄今为止所做的努力:

^{pr2}$

但最后一行给出了一个错误:

error: astimezone() cannot be applied to a naive datetime

当我使用:

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')

有更好的解决办法吗?在


Tags: todatetimeobject时间dtnowtimedeltaseconds
2条回答

要舍入时区感知日期时间对象,make it a naive datetime object, round it, and attach the correct time zone info for the rounded time

from datetime import timedelta
from django.utils import timezone

def round_time(dt=None, delta=timedelta(minutes=1)):
    if dt is None:
        dt = timezone.localtime(timezone.now()) # assume USE_TZ=True
    tzinfo, is_dst = dt.tzinfo, bool(dt.dst())
    dt = dt.replace(tzinfo=None)
    f = delta.total_seconds()
    rounded_ordinal_seconds = f * round((dt - dt.min).total_seconds() / f)
    rounded_dt = dt.min + timedelta(seconds=rounded_ordinal_seconds)
    localize = getattr(tzinfo, 'localize', None)
    if localize:
        rounded_dt = localize(rounded_dt, is_dst=is_dst)
    else:
        rounded_dt = rounded_dt.replace(tzinfo=tzinfo)
    return rounded_dt

为了避免浮点问题,可以使用整数微秒(dt.resolution)重写所有计算。在

示例:

^{pr2}$

您正在使用的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)

这样,函数就可以同时处理naiver和TZ-aware日期。 然后您可以继续进行第二次尝试:

^{pr2}$

相关问题 更多 >