写点什么

Django 笔记二十五之数据库函数之日期函数

作者:Hunter熊
  • 2023-05-08
    北京
  • 本文字数:2574 字

    阅读完需:约 8 分钟

Django笔记二十五之数据库函数之日期函数

本文首发于公众号:Hunter 后端

原文链接:Django笔记二十五之数据库函数之日期函数


日期函数主要介绍两个大类,Extract() 和 Trunc()


Extract() 函数作用是提取日期,比如我们可以提取一个日期字段的年份,月份,日等数据


Trunc() 的作用则是截取,比如 2022-06-18 12:12:12,我们可以根据需求获取到日期 2020-06-18,或者更细粒度到时分秒


这次我们用到下面这个 model:


class Experiment(models.Model):    start_datetime = models.DateTimeField()    start_date = models.DateField(null=True, blank=True)    start_time = models.TimeField(null=True, blank=True)    end_datetime = models.DateTimeField(null=True, blank=True)    end_date = models.DateField(null=True, blank=True)    end_time = models.TimeField(null=True, blank=True)
复制代码


我们还是将其放到 blog/models.py 下,相关的 migration 操作这里不多做介绍


  1. Extract()

  2. Trunc()

1、Extract()

这个函数接受日期时间字段名称,和查询的年、月、日、时、分、秒等作为参数,提取出相应的值以整数类型返回


日期类型字段包括:DateTimeField,DateField,TimeField 提取的类型列举如下:


  • year——年份

  • quarter——季度

  • month——月份

  • day——某日

  • week——周数,一年的第几周

  • weekday——周几,周日的值是 1,周一是 2,一直到周六是 7

  • hour——小时

  • minute——分钟

  • second——秒数


首先创建测试用的数据:


from datetime import datetimestart = datetime(2015, 6, 15, 12, 30, 56)end = datetime(2015, 7, 2, 17, 21, 43)
from blog.models import ExperimentExperiment.objects.create( start_datetime=start, start_date=start.date(), end_datetime=end, end_date=end.date())
复制代码


新增字段获取开始时间的年份,周数,周几以及该天的小时数


from blog.models import Experimentfrom django.db.models.functions import Extract
experiment = Experiment.objects.annotate( start_year=Extract('start_datetime', 'year'), start_week=Extract('start_datetime', 'week'), start_week_day=Extract('start_datetime', 'week_day'), start_hour=Extract('start_datetime', 'hour')).get(id=1)
print(experiment.start_year)print(experiment.start_week)print(experiment.start_week_day)print(exprtiment.start_hour)
复制代码


搜索特定年份数据


Extract() 函数的用法也可以用于搜索特定的日期的某一项,比如某年,某月等


Experiment.objects.filter(start_datetime__year=Extract('end_datetime', 'year'))
复制代码


具体到日期某一项的用法


前面介绍了 Extract() 函数的用法是,接收字段名和日期项,Django 同时提供了另一种简便的、比 Extract()函数更具体的用法。


比如我们需要需要搜索年,可以直接使用函数为 ExtractYear()


搜索月,使用函数 ExtractMonth()等等。


每一种在我们上面可接收的参数都有其对应的函数,传参为需要处理的字段,以下是使用示例:


from blog.models import Experimentfrom django.db.models.functions import ExtractYear, ExtractWeekexpriment = Experiment.objects.annotate(    start_year=ExtractYear('start_datetime'),    start_week=ExtractWeek('start_datetime')).get(id=1)
print(expriment.start_year)print(expriment.start_week)
复制代码


如果是周数、时、分、秒的操作,函数名将上面的年月日的英文替换即可

2、Trunc()

这是一个对日期和时间截取的函数,我们可以将时间精确到 年、季度、月、日、时、分、秒


接受三个参数:


  • expression: 字段,可以是 DateField, DateTimeField, TimeField 等

  • kind: 精确到的程度,可以是 year,day,quarter 等

  • output_field: 输出格式,可以根据 kind 的值设置到最小值,如果不传这个参数,则默认是 expression 的值


假设一个日期时间为 2022–05-16 12:34:56


我们可以挨个处理一下:


# 创建数据from datetime import datetimestart_datetime = datetime(year=2022, month=5, day=16, hour=12, minute=34, second=56)
Experiment.objects.create(start_datetime=start_datetime)
from django.db.models.functions import Truncfrom django.db import models
experiment = Experiment.objects.annotate( start_year=Trunc('start_datetime', 'year', output_field=models.DateField()), start_quarter=Trunc('start_datetime', 'quarter', output_field=models.DateField()), start_month=Trunc('start_datetime', 'month', output_field=models.DateField()), start_day=Trunc('start_datetime', 'day', output_field=models.DateField()), start_hour=Trunc('start_datetime', 'hour', output_field=models.DateTimeField()), start_minute=Trunc('start_datetime', 'minute', output_field=models.DateTimeField()), start_second=Trunc('start_datetime', 'second', output_field=models.DateTimeField()),).get(id=2)
复制代码


然后挨个 print() 他们的结果如下:


>>> print(experiment.start_year)2022-01-01>>> print(experiment.start_quarter)2022-04-01>>> print(experiment.start_month)2022-05-01>>> print(experiment.start_day)2022-05-16>>> print(experiment.start_hour)2022-05-16 12:00:00+00:00>>> print(experiment.start_minute)2022-05-16 12:34:00+00:00>>> print(experiment.start_second)2022-05-16 12:34:56+00:00
复制代码


需要注意的是,截取到年、月、季度的数据,因为不关心当前时间刻度之下的数据,所以日期的日,都会被置为 1,时间都会是 0


从输出的结果看,日期时间都精确到了我们设置的细度,那么我们就可以利用这个来进行年度、月度、季度、以及日度等一些数据的统计


接下来以日度数据为例,我们做一下统计,统计每一天的数据的数量:


from django.db.models import CountExperiment.objects.annotate(start_day=Trunc("start_datetime", "day", output_field=models.DateField())).values("start_day").annotate(count_day=Count("id"))
复制代码


与 Extract() 函数类似,Trunc() 函数也有一些可以直接操作到时间的函数,比如 TruncYear(), TruncMonth() 这种,这里就不展开介绍了。


以上就是本篇笔记全部内容,下一篇将介绍数据库函数里计算公式相关函数。

发布于: 刚刚阅读数: 4
用户头像

Hunter熊

关注

公众号:Hunter后端 2018-09-17 加入

Python后端工程师,欢迎互相沟通交流

评论

发布
暂无评论
Django笔记二十五之数据库函数之日期函数_Python_Hunter熊_InfoQ写作社区