先看看几个函数的表现行为
>>> import os
>>> os.environ['TZ']
'America/New_York'
>>> from datetime import datetime as dt
>>> n1 = dt.now()
>>> n1.tzinfo
>>> n2 = dt.utcnow()
>>> n2.tzinfo
>>> from django.utils import timezone
>>> n3 = timezone.now()
>>> n3.tzinfo
<UTC>
>>> n1
datetime.datetime(2018, 7, 26, 8, 15, 0, 165208)
>>> n2
datetime.datetime(2018, 7, 26, 12, 15, 20, 719818)
>>> n3
datetime.datetime(2018, 7, 26, 12, 15, 40, 593761, tzinfo=<UTC>)
- n1, n2 都是不带时区的,n3 是带时区信息的
- n1 是当前本地时间
- n2 根据当前环境变量 TZ 计算当前UTC时间
与数据库交互
先做两个假设:
- 数据库存储的是 UTC 时间
- 数据库查看软件 Sequel Pro 显示的是UTC时间
那么(这个转换是Django ORM做的,还是数据库做的呢)
- 不带时区信息的时间,会被当做本地时间,根据本地时区,转换为UTC时间,再存储进数据库
- 带时区信息的时间,会先转换为UTC时间,再存储进数据库
又因为
- Django 配置中填写时区,会改写环境变量 TZ 的值 (这是个假设)
所以,存入数据库的时候
- 当前时区的小时数是 8
- n1 小时数会 +4 再存储:8+4=12
- n2 是根据时区计算UTC时间,存储的时候被当成本地时间,又做了一次 +4:8+4+4=16
- n3 会被正常存储:(8+4)=12
最后来验证假设是否正确
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | UTC |
| time_zone | SYSTEM |
+------------------+--------+
假设1得证。