select now(); 查看MySQL时间.如果时间和你本地当前时间一致 ,说明mysql的时间没有问题
当启用时区支持,Django 在数据库以 UTC 存储日期信息,在模板和表单中用时区转换为最终用户的时区。
Why 启动时区
django文档:https://docs.djangoproject.com/zh-hans/3.2/topics/i18n/timezones/
数据库中的时间比Django界面时间晚8h
django界面显示时间5.26号00:00, 但保存到数据库时有时差8h, 变成5.25号16:00。settings.py中设置了USE_TZ=True
和 TIME_ZONE = 'Asia/Shanghai'
。用datetime.datetime.now()
:
-
如果
USE_TZ=True
与TIME_ZONE = 'UTC'
,django会把这个时间当成UTC时间存储到数据库中去。 -
如果
USE_TZ=True
与TIME_ZONE = 'Asia/Shanghai'
,尽管数据库中存储的是UTC时间,但django会把这个时间当成TIME_ZONE所示的本地时间,即Asia/Shanghai东八区时间。所以出现数据库中的时间比本地时间会小8h。
不管你设置的TIME_ZONE是什么:
- 设置
USE_TZ=True
,存储到数据库中的时间永远是UTC时间。django.utils.timezone.now()
输出永远是UTC时间。 - 如果
USE_TZ=False
,则django.utils.timezone.now()
输出等同于datetime.datetime.now()
。
# django.utils.timezone.now()
def now():
"""
Return an aware or naive datetime.datetime, depending on settings.USE_TZ.
"""
if settings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
return datetime.utcnow().replace(tzinfo=utc)
else:
return datetime.now()
解决方案
数据库保存UTC时间,转成用户所在时区的时间
import pytz, datetime
pytz.timezone(settings.TIME_ZONE) # <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
t = obj.start_time # datetime.datetime(2021, 5, 25, 16, 0, tzinfo=<UTC>)
t.astimezone(pytz.timezone(settings.TIME_ZONE)) # datetime.datetime(2021, 5, 26, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
t.astimezone(pytz.timezone(settings.TIME_ZONE)).timestamp() # 时间戳 1621958400.0
native or aware time
naive time就是不带时区的时间,Active time就是带时区的时间,
- datetime.datetime.now():本地时间(naive time)与配置无任任何关系
- datetime.datetime.utcnow():如果配置USE_TZ=True则输出的是UTC时间(naive time);如果配置USE_TZ=False,则与datetime.datetime.now()完全相同。
- django.util.timezone.now():如果配置USE_TZ=True则输出的是UTC时间(active time),如果配置USE_TZ=False,则与datetime.datetime.now()完全相同。