详解Django 中是否使用时区的区别


Posted in Python onJune 14, 2018

起步

在 Django 的模型中新加了一个日期的字段:

import datetime
class Instance(models.Model):
  ...
  start_time = models.DateTimeField(default=datetime.datetime.now)

同步到数据库时 Django 报出了一个警告:

django/db/models/fields/__init__.py:1423: RuntimeWarning: DateTimeField Instance.start_time received a naive datetime (2018-06-14 08:59:54.761510) while time zone support is active.

这个意思是应用中开启了时区功能,而字段中却使用了 naive datetime 。我看了配置文件确实启用的时区的功能:

TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True

如果设置了使用时区,那么Django在数据库中以 UTC 存储日期时间信息。

要想知道时区的 Django 中的作用,我们要先了解时间有时区的没有时区的区别。

带时区与不带时区

日期时间存在两个概念: naive time 和 aware time 。 naive time 就是不带时区的时间, aware time 则是带时区的时间。比方说, datatime.datetime.utcnow() datatime.datetime.now() ,前者是 UCT 时间,后者会取机器上的本地时间,这两者呢,对于 django 来说,都是不带时区的时间(下一段会讲原因);而使用 django.utils.timezone.now() 才是带时区的时间(aware time)。

datetime.datetime.now() 输出永远都是本地时间,与配置没有任何关系。 datatime.datetime.utcnow() 则是当前的UTC日期和时间, datetime 模块是 python 的标准库,尽管 datetime.datetime 对象有一个 tzinfo 属性可以用来存储时区信息。除非该对象设置了 tzinfo 属性,否则统统会被 django 认为是 naive time 。判断可以通过 is_naive() 来判断:

import datetime
from django.utils import timezone

print(timezone.is_naive( datetime.datetime.now() ))  # False
print(timezone.is_naive( datetime.datetime.utcnow() )) # False

显然 now() 和 utcnow() 都是没有设置 tzinfo 的。

django判断日期对象是否是原生的唯一标准就是该对象是否设置了 tzinfo

datetime 与 timezone

datetime 是标准库的模块, timezone 是 django 提供的时区的工具, timezone 其实是在 datetime 基础上进行的整合的,比方 django 中的 now 函数:

[timezone.py]
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()

返回的其实也是一个 datetime 对象。

设置了 USE_TZ=True 之后

设置了 USE_TZ=True 之后,model 里面认为 DateTimeField 使用的是UTC时间(带时区的时间),这时用 datetime.datetime.now() 获取的时间是不带时区的就会报最开始说的那个警告。

并且呢, 所有的存储和内部处理,全部都是 UTC 时间 ,包括 timezone.now() ,存储也就是指数据库中存储的是UTC时间,也就只有在表单输入或模板渲染输出的时候,才会执行 UTC 到时区的转换。基本对于开发者而言,基本不用考虑本地时间的存在,所有的使用都是 UTC 时间,这也能避免手残的手动转换,尽量使用 Django 系统代劳。

USE_TZ=False 则所有关于时间和时区的问题都有开发人员自己把控。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现朴素贝叶斯分类器的方法详解
Jul 04 Python
对python字典元素的添加与修改方法详解
Jul 06 Python
Django保护敏感信息的方法示例
May 09 Python
关于PyTorch源码解读之torchvision.models
Aug 17 Python
python3 下载网络图片代码实例
Aug 27 Python
Linux下通过python获取本机ip方法示例
Sep 06 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
Oct 09 Python
详解Python中打乱列表顺序random.shuffle()的使用方法
Nov 11 Python
Python文件操作方法详解
Feb 09 Python
Django CSRF认证的几种解决方案
Mar 03 Python
python如何调用百度识图api
Sep 29 Python
详解基于python的全局与局部序列比对的实现(DNA)
Oct 07 Python
python dataframe 输出结果整行显示的方法
Jun 14 #Python
Python3.6基于正则实现的计算器示例【无优化简单注释版】
Jun 14 #Python
Python3.6简单反射操作示例
Jun 14 #Python
Python3.6日志Logging模块简单用法示例
Jun 14 #Python
Python实现的knn算法示例
Jun 14 #Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
Jun 14 #Python
Tensorflow 查看变量的值方法
Jun 14 #Python
You might like
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
window.open关于浏览器拦截问题分析及解决方法
2013/02/05 Javascript
JS Map 和 List 的简单实现代码
2013/07/08 Javascript
yepnope.js使用详解及示例分享
2014/06/23 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
JS获取IMG图片高宽的简单实例
2016/05/17 Javascript
判断输入的字符串是否是日期格式的简单方法
2016/07/11 Javascript
浅谈移动端之js touch事件 手势滑动事件
2016/11/07 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
实例分析nodejs模块xml2js解析xml过程中遇到的坑
2017/03/18 NodeJs
javascript实现二叉树的代码
2017/06/08 Javascript
React中的refs的使用教程
2018/02/13 Javascript
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
2019/01/24 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
小程序中canvas的drawImage方法参数使用详解
2019/07/04 Javascript
vue 地区选择器v-distpicker的常用功能
2019/07/23 Javascript
微信小程序上传图片并等比列压缩到指定大小的实例代码
2019/10/24 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
Python数据类型详解(一)字符串
2016/05/08 Python
Pandas读取MySQL数据到DataFrame的方法
2018/07/25 Python
对Python的zip函数妙用,旋转矩阵详解
2018/12/13 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
Python定义函数功能与用法实例详解
2019/04/08 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
python opencv摄像头的简单应用
2019/06/06 Python
python将unicode和str互相转化的实现
2020/05/11 Python
python3.7添加dlib模块的方法
2020/07/01 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
2021/03/03 Python
营销部内勤岗位职责
2014/04/30 职场文书
会计专业求职信
2014/08/10 职场文书
中小学生学籍证明
2014/10/25 职场文书
信息技术课教学反思
2016/02/23 职场文书