Django和Python中的Timezone处理
在现实环境中,存在有多个时区。用户之间很有可能存在于不同的时区,并且许多国家都拥有自己的一套夏令时系统。所以如果网站面向的是多个时区用户,只以当前时间为标准开发,便会在时间计算上产生错误。
为解决这个此类问题,在代码和数据库中统一使用 UTC 时间,仅在与最终用户进行交互时使用本地时间是一个很好的办法 。
Django 默认关闭时区支持,开启时区支持,需要在 settings 中设置 USE_TZ = True 。
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
最好同时安装 pytz 模块(pip install pytz) 。
Naive 和 Aware 类型的 datetime 对象
Python 的 datatime.datetime对象有一个 tzinfo 属性,该属性是 datetime.tzinfo 子类的一个实例,他被用来存储时区信息。当某个 datetime 对象的 tzinfo 属性被设置并给出一个时间偏移量时,我们称该 datetime 对象是 aware (已知) 的。否则称其为 naive (原生) 的。
可以使用 is_aware() 和 is_naive() 函数来判断某个 datetime 对象是 aware 类型或 naive 类型。
- 当关闭时区时,django 使用原生的 datetime 对象保存本地时间:
import datetime
now = datetime.datetime.now()
- 当开启时区时,django 使用已知 (aware) 的 datetime 对象存储本地时间:
from django.utils import timezone
now = timezone.now()
而默认Django开启时区且为utc,所以在不改变TIME_ZONE的情况下,django数据库中的时间一定是timezone aware的时间,如果要生成时间,要通过replace timezone设置为本地时区。
数据库中的时间都是utc时间
Django中的timezone
from django.utils import timezone
t=timezone.now()
print(t)
datetime.datetime(2016, 1, 4, 2, 13, 54, 582231, tzinfo=<UTC>)
new_t=timezone.localtime(t)
print(new_t)
datetime.datetime(2016, 1, 4, 10, 13, 54, 582231, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
Python中的datetime
import datetime
t = datetime.datetime.strptime("2016-1-4", "%Y-%m-%d")
print(t)
datetime.datetime(2016, 1, 4, 0, 0)
new_t = t.replace(tzinfo=(pytz.timezone('Asia/Shanghai')))
print(new_t)
datetime.datetime(2016, 1, 4, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)
人生苦短,我用python!