天天看点

Django 时区问题处理

问题:存储、搜索、展示数据不一致。如何解决和处理那?

设置 ( Django 1.4 之后存在时区问题)

# Django 设置 东八区 settings.py
USE_TZ = True
TIME_ZONE = 'Asia/Shanghai'
           

是否开启时区

  • 使用 Django 开发项目,DateTime 存在跨区开启时区。否则,建议不开启时区,开启时区意味你要在。存储、查询、格式化DateTime做对应处理。下面会讲到

关于时区

  • 中国时区(东八区)使用国际时区 UTC。国际通用也是 UTC 。
  • 北美、欧洲使用 CST (夏令时。中间有个“有趣”的故事可以搜一下)

Django 时区

ORM 实操

ORM 存储

frm datetime import datetime
import pytz
from dateutil.parser import parse

tz = pytz.timezone('Asia/Shanghai')

now = datetime.now() # 没有携带时区

dt = parse('2022-10-24 14:10:00')
dt.astimezone(pytz.utc)
# Django开启 东八区后存储 Django将转换后的数据存储到数据中
Out[31]: datetime.datetime(2022, 10, 24, 6, 10, tzinfo=<UTC>)

# 准确来说应该是这样的
tz = pytz.timezone('Asia/Shanghai')
dt_tz = tz.localize(dt)
dt_tz.astimezone(pytz.utc)
Out[33]: datetime.datetime(2022, 10, 24, 6, 10, tzinfo=<UTC>)


Model.objects.create(at='2022-10-24 16:30:00')
# 数据中得到的结果应该是
# 2022-10-24 08:30:00+00
           

ORM 查询

Model.objects.filter(at__gt='2022-10-24 16:30:00')
Model.objects.filter(at__range=('2022-10-24 00:00:00', '2022-10-24 16:30:00')

# Django SQL
# "at" > 2022-10-24 16:30:00+08:00
# BETWEEN 2022-10-24 00:00:00+08:00 AND 2022-10-24 16:30:00+08:00'


# 将 2022-10-24 16:30:00 转成时区为 上海时区 utc 
"alert_end_time" > 2022-10-24 08:30:00+00:00'
           

ORM DateTime strftime格式化

# 数据库读取结果是一个 utc datetime 后端格式化时结果和存储正好错 8 小时
datetime.datetime(2022, 10, 24, 8, 30, tzinfo=<UTC>)
obj.alert_end_time.strftime('%Y-%m-%d %H:%M:%S')
Out[42]: '2022-10-24 08:30:00'

# 转化时区格式化
_dt.astimezone(tz).strftime('%Y-%m-%d %H:%M:%S')
Out[47]: '2022-10-24 16:30:00'
           

总结