Django时区/时间处理/时间范围计算周、月、季度、半年、年

小熊 2021年12月26日Python评论1,318 views62662字阅读8分52秒阅读模式

我在使用Django的过程中发现时区的处理比较简单易用,但也有一些细节需要注意。

配置时区

setting.py文件中修改配置节,若无则手动添加
注意:所有与django有关的内部包全部都使用会自动使用此时区

# 使用时区
USE_TZ = True
# 设置时区
TIME_ZONE = 'Asia/Shanghai'

具体的时区有哪些字符串可以参考 pytz__init__.py文件中的all_timezones变量。

all_timezones = \
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 'Africa/Algiers',
...

python中使用时区

python里常用datetime来获取时间,如果是平时使用默认utc时区,可以通过这样的方式传入时区,此时再使用则就正常了

from django.conf import settings
from pytz import timezone
from datetime import datetime

datetime.now(tz=timezone(settings.TIME_ZONE))

而在django中应该使用timezone来替代datetime

from django.utils import timezone
# timezone.localtime 将时间转换为本地配置中的时区
now = timezone.localtime(timezone.now())

为什么一定要这么用,django 对此有更多更详细的解释,感兴趣自己看看

django官方文档4.0 time zones

时间范围计算周、月、季度、半年、年

我有一个需求,要计算报表,以不同的时间范围汇聚数据,进行数据降准,比如把分钟数据通过某算法计算得到小时数据,这样一天就只有24个点了。用户在大时间范围查询数据的时候根本不会关注到那么细的时间粒度,而是看一个趋势。

所以与时间相关的工具函数如下(函数名已经自释义了,我就不解释了)

from django.utils import timezone
from datetime import timedelta


# 季度 1 2 3 4
def get_quarterly_from_month(month):
    return int((month - 1) / 3) + 1


def get_offset_from_quarterly(quarterly):
    if quarterly > 0:
        year_offset = int((quarterly - 1) / 4)
        quarterly = (quarterly - 1) % 4 + 1
    else:
        year_offset = int(quarterly / 4) - 1
        quarterly = 4 + -((-quarterly) % 4)
    return year_offset, quarterly


def get_quarterly_first_day(quarterly):
    year_offset, quarterly = get_offset_from_quarterly(quarterly)
    now = timezone.localtime(timezone.now())
    return now.replace(year=now.year + year_offset, month=(quarterly * 3 - 2), day=1, hour=0, minute=0, second=0,
                       microsecond=0)


def get_quarterly_last_day(quarterly):
    year_offset, quarterly = get_offset_from_quarterly(quarterly)
    now = timezone.localtime(timezone.now())
    next_month = quarterly * 3 + 1
    year_offset += int(next_month / 12)
    next_month = (next_month - 1) % 12 + 1
    next_month_first_day = now.replace(year=now.year + year_offset, month=next_month, day=1, hour=0,
                                       minute=0, second=0, microsecond=0)
    return next_month_first_day - timedelta(microseconds=1)


# h1 h2
def get_h1h2_from_month(month):
    return int((month - 1) / 6) + 1


def get_offset_from_h1h2(h1h2):
    if h1h2 > 0:
        year_offset = int((h1h2 - 1) / 2)
        h1h2 = (h1h2 - 1) % 2 + 1
    else:
        year_offset = int(h1h2 / 2) - 1
        h1h2 = 2 + -((-h1h2) % 2)
    return year_offset, h1h2


def get_h1h2_first_day(h1h2):
    year_offset, h1h2 = get_offset_from_h1h2(h1h2)
    now = timezone.localtime(timezone.now())
    return now.replace(year=now.year + year_offset, month=(h1h2 * 6 - 5), day=1, hour=0, minute=0, second=0,
                       microsecond=0)


def get_h1h2_last_day(h1h2):
    year_offset, quarterly = get_offset_from_h1h2(h1h2)
    now = timezone.localtime(timezone.now())
    next_month = h1h2 * 6 + 1
    year_offset += int(next_month / 12)
    next_month = (next_month - 1) % 12 + 1
    next_month_first_day = now.replace(year=now.year + year_offset, month=next_month, day=1, hour=0,
                                       minute=0, second=0, microsecond=0)
    return next_month_first_day - timedelta(microseconds=1)

最后

感兴趣监控数据处理,自动降准数据查询可以参考thanos-query的源码,降准数据计算可以参考thanos-compact,不过是go语言实现的

weinxin
公众号
在号内与我交流,回复【资源】获取技术大礼包
Python最后更新:2021-12-30
小熊