Django时区感知

本案例使用 python3.8 + django3.2.18

项目配置

settings.py

python 复制代码
# 时区设置为中国上海
TIME_ZONE = 'Asia/Shanghai'

# 开启时区感知功能
USE_TZ = True

获取当前时间

执行代码:

python 复制代码
from django.utils import timezone
from datetime import datetime

date_time = datetime.now()
zone_time = timezone.now()
local_time = timezone.localtime()
print("date_time:", type(date_time), date_time, date_time.tzinfo)
print("django_time:", type(zone_time), zone_time, zone_time.tzinfo)
print("local_time:", type(local_time), local_time, local_time.tzinfo)

执行结果:

date_time: <class 'datetime.datetime'> 2025-09-11 10:28:50.410969 None

django_time: <class 'datetime.datetime'> 2025-09-11 02:28:50.410969+00:00 UTC

local_time: <class 'datetime.datetime'> 2025-09-11 10:28:50.410969+08:00 Asia/Shanghai

三者数据类型均为datetime.datetime,主要区别在于时间和时区

源码解析:

datetime.now() python自带的包,一般都用这个获取当前时间,不带时区信息,没啥好说的。

**timezone.now()**django的包,用于获取当前时间,并且携带时区信息,如果开启了时区感知,则获取的是UTC时区的时间,否则效果和datetime.now()相同

源码:

**timezone.localtime()**django的包,默认用于获取当前时间,并将其转换为TIME_ZONE所配置的时区;此外这个函数还可以将指定的时间转换为指定的时区,但是要注意传递的时间必须是携带时区信息,否则就会抛出179行的异常:localtime() cannot be applied to a naive datetime,表示这个时间没有时区信息,无法转换到目标时区

源码:

时区转换

python 复制代码
from django.utils import timezone
from datetime import datetime
import pytz

date_str = "2025-09-10 10:00:00"
# 将字符串格式的时间转换为datetime类型
date_time = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
# 获取当前时区
tz = timezone.get_current_timezone()
# 将时间标记为utc时区
utc_time = timezone.make_aware(date_time, timezone=timezone.utc)
# 转换为指定时区的时间
sh_time = timezone.localtime(utc_time, tz)
at_time = timezone.localtime(utc_time, pytz.timezone('Asia/Tokyo'))
print("tz:", type(tz), tz)
print("date_time:", type(date_time), date_time, date_time.tzinfo)
print("utc_time:", type(utc_time), utc_time, utc_time.tzinfo)
print("中国上海时间:", type(sh_time), sh_time, sh_time.tzinfo)
print("日本东京时间:", type(at_time), at_time, at_time.tzinfo)

输出结果:

tz: <class 'pytz.tzfile.Asia/Shanghai'> Asia/Shanghai

date_time: <class 'datetime.datetime'> 2025-09-10 10:00:00 None

utc_time: <class 'datetime.datetime'> 2025-09-10 10:00:00+00:00 UTC

中国上海时间: <class 'datetime.datetime'> 2025-09-10 18:00:00+08:00 Asia/Shanghai

日本东京时间: <class 'datetime.datetime'> 2025-09-10 19:00:00+09:00 Asia/Tokyo

时区感知对数据库操作的影响

创建数据库表:

sql 复制代码
CREATE TABLE user  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NULL,
  `update_time` datetime NULL,
  PRIMARY KEY (`id`)
);

DajngoModel层:

python 复制代码
class User(models.Model):
    name = models.CharField(max_length=255)
    update_time = models.DateTimeField()

    class Meta:
        db_table = "user"

执行代码:

python 复制代码
from django.utils import timezone
from datetime import datetime
import pytz

date_str = "2025-09-10 10:00:00"
date_time = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
tz = timezone.get_current_timezone()
utc_time = timezone.make_aware(date_time, timezone=timezone.utc)
sh_time = timezone.localtime(utc_time, tz)
at_time = timezone.localtime(utc_time, pytz.timezone('Asia/Tokyo'))

user_1 = User.objects.filter(update_time=date_str)
user_2 = User.objects.filter(update_time=date_time)
user_3 = User.objects.filter(update_time=utc_time)
user_4 = User.objects.filter(update_time=sh_time)
user_5 = User.objects.filter(update_time=at_time)
print(user_1.query, "   date_str:", date_str)   # 输出sql,实际 where update_time=2025-09-10 02:00:00
print(user_2.query, "   date_time:", date_time)   # 输出sql,实际 where update_time=2025-09-10 02:00:00
print(user_3.query, "   utc_time:", utc_time)   # 输出sql,实际 where update_time=2025-09-10 10:00:00
print(user_4.query, "   sh_time:", sh_time)   # 输出sql,实际 where update_time=2025-09-10 10:00:00
print(user_5.query, "   at_time:", at_time)   # 输出sql,实际 where update_time=2025-09-10 10:00:00

输出结果(观察sql中的where条件值和变量值):

SELECT `user`.`id`, `user`.`name`, `user`.`update_time` FROM `user` WHERE `user`.`update_time` = 2025-09-10 02:00:00 date_str: 2025-09-10 10:00:00

SELECT `user`.`id`, `user`.`name`, `user`.`update_time` FROM `user` WHERE `user`.`update_time` = 2025-09-10 02:00:00 date_time: 2025-09-10 10:00:00

SELECT `user`.`id`, `user`.`name`, `user`.`update_time` FROM `user` WHERE `user`.`update_time` = 2025-09-10 10:00:00 utc_time: 2025-09-10 10:00:00+00:00

SELECT `user`.`id`, `user`.`name`, `user`.`update_time` FROM `user` WHERE `user`.`update_time` = 2025-09-10 10:00:00 sh_time: 2025-09-10 18:00:00+08:00

SELECT `user`.`id`, `user`.`name`, `user`.`update_time` FROM `user` WHERE `user`.`update_time` = 2025-09-10 10:00:00 at_time: 2025-09-10 19:00:00+09:00

总结:当开启了时区感知,使用DjangoORM操作数据库时会自动将时间转换为UTC时区,对于没有时区信息的时间,会将其视为settings.py中所配置的TIME_ZONE时区,因此推荐使用timezone.localtime()来获取当前时间

API接口返回指定格式时间

假设现在有一个API接口要返回时间相关的数据:

python 复制代码
from django.utils import timezone
from django.http import JsonResponse

def getTime(request):
    data = {
        'message': '成功获取当前时间',
        'localtime': timezone.localtime()
    }
    return JsonResponse(data)

API接口返回结果:

{

"message": "成功获取当前时间",

"localtime": "2025-09-13T14:22:45.675+08:00"

}

所返回的时间可能并非我们期望的格式,此时可以使用自定义json编码器对数据进行格式化

CustomizeEncoder.py

python 复制代码
import json
from datetime import datetime
from decimal import Decimal
from django.utils import timezone

# 自定义json编码器,将指定类型的数据进行格式化
class CustomizeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            if o.tzinfo:
                return timezone.localtime(o).strftime('%Y-%m-%d %H:%M:%S')
            else:
                return o.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(o, Decimal):
            return float(o)
        # 使用默认的编码
        return json.JSONEncoder.default(self, o)

修改后的代码:

python 复制代码
from django.utils import timezone
from django.http import JsonResponse
from XX.XX.CustomizeEncoder import CustomizeEncoder

data = {
    'message': '成功获取当前时间',
    'localtime': timezone.localtime()
}
return JsonResponse(data, encoder=CustomizeEncoder)

再次请求API接口,返回结果:

{

"message": "成功获取当前时间",

"localtime": "2025-09-13 14:40:59"

}

相关推荐
颜酱7 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
喵手7 小时前
Python爬虫实战:旅游数据采集实战 - 携程&去哪儿酒店机票价格监控完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集结果csv导出·旅游数据采集·携程/去哪儿酒店机票价格监控
2501_944934737 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
helloworldandy7 小时前
使用Pandas进行数据分析:从数据清洗到可视化
jvm·数据库·python
肖永威9 小时前
macOS环境安装/卸载python实践笔记
笔记·python·macos
TechWJ9 小时前
PyPTO编程范式深度解读:让NPU开发像写Python一样简单
开发语言·python·cann·pypto
枷锁—sha9 小时前
【SRC】SQL注入WAF 绕过应对策略(二)
网络·数据库·python·sql·安全·网络安全
Coder_Boy_9 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
abluckyboy10 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法
喵手10 小时前
Python爬虫实战:构建各地统计局数据发布板块的自动化索引爬虫(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集数据csv导出·采集各地统计局数据发布数据·统计局数据采集