zoukankan      html  css  js  c++  java
  • Django中的时区

    Django的settings配置中有一个USE_TZ项,默认值为True。很多人不太清楚这个配置项具体是干什么的,只知道和时区有关。下面我们就来详细聊聊它。

    首先,我们要了解一下什么是offset-awareoffset-navie

    offset-aware与offset-navie

    在Python中,有一个datetime模块,相信大家都很熟悉。但是很少有人知道这个模块的时间还可以分下面两种类型:

    • offset-naive:不含时区的类型
    • offset-aware:有时区的类型

    并且,这两种类型的时间是不可以直接比较的,比如做减法、加法、时间对比等,会抛出下面的异常:

    TypeError: can't compare offset-naive and offset-aware datetimes
    

    根本的原因在于两者一个有时区信息,一个没有。

    我们可以通过查看datetime对象的tzinfo属性,来判断具体是两者中的哪种:

    >>> import datetime
    >>> now = datetime.datetime.now()
    >>> now
    datetime.datetime(2020, 5, 26, 18, 36, 59, 811729)
    >>> now.tzinfo
    >>> now.tzinfo==None
    True
    

    可以很清楚的看到,datetime.datetime.now()是一个offset-naive类型,不含时区信息的时间对象。

    我们可以借助pytz模块,将一个offset-naive类型的时间对象转换为一个offset-aware类型的时间对象。

    先安装pytz模块:

    pip install pytz
    

    来测试一下:

    >>> import pytz
    >>> now = now.replace(tzinfo=pytz.timezone('UTC'))
    >>> now
    datetime.datetime(2020, 5, 26, 18, 36, 59, 811729, tzinfo=<UTC>)
    >>> now.tzinfo
    <UTC>
    

    反过来,也可以将一个offset-aware型转换为offset-naive型:

    >>> now = now.replace(tzinfo=None)
    >>> now
    datetime.datetime(2020, 5, 26, 18, 36, 59, 811729)
    >>> now.tzinfo == None
    True
    

    USE_TZ配置

    回到Django种来。我们知道,在安装Django的同时,默认会安装一个pytz模块,然后在django.utils下就会有一个timezone模块,其实它就是pytz.timezone

    首先,我们要清楚一件事。Django的settings配置中的USE_TZ默认值为True,也就是说,默认情况下Django数据库里面存储的日期数据是带时区信息的,也就是offset-aware类型。

    这就导致了我们有些时候,进行时间对比或者加减的操作,会抛出前面说的异常。

    TypeError: can't compare offset-naive and offset-aware datetimes
    

    那怎么办呢?

    最原始朴素的方法,自然是对时间类型进行转换,采用上面的例子中的方法,统一起来,就可以进行比较了。

    还有一种更简单的方法,那就是将USE_TZ设置为False。此时,数据库里保存的时间对象就不在包含时区信息了,和原生的datetime.datetime是一种类型,都是offset-naive类型,自然不会发生冲突。

    Tips:应该在项目开始之初,创建数据表之前就设置USE_TZ为False,否则先前保存的时间数据可能依然带有时区信息。

    其实,还有一种更适用的方法,就是USE_TZ依然保持为True,但是不再使用datetime库了,而是使用timezone来获取now时间:

    from django.utils import timezone  
      
    now = timezone.now()
    

    这样,大家都带有时区信息,自然也是可以比较的。

  • 相关阅读:
    【leetcode】106. Construct Binary Tree from Inorder and Postorder Traversal
    【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
    【leetcode】236. Lowest Common Ancestor of a Binary Tree
    【leetcode】235. Lowest Common Ancestor of a Binary Search Tree
    【leetcode】352. Data Stream as Disjoint Intervals
    【leetcode】897. Increasing Order Search Tree
    【leetcode】900. RLE Iterator
    BEC listen and translation exercise 26
    BEC listen and translation exercise 25
    BEC listen and translation exercise 24
  • 原文地址:https://www.cnblogs.com/django-dev/p/12968403.html
Copyright © 2011-2022 走看看