Django timezone

作者: catttthrine | 来源:发表于2019-07-02 14:25 被阅读0次

    0x00.问题发现

    关于时间处理的爱恨情仇~
    每个网站存储时间都有不同的格式,或者说有不同的显示格式,这一点在python里其实可以得到很丰富的转换和reformat
    有一天遇到了一个没见过的warning

    RuntimeWarning: DateTimeField received a naive datetime while time zone support is active.

    虽然是warning,但是被写在log里也还是怪膈应的,所以探寻了一下问题的源头。

    0x01.Time zones

    首先,USE_TZ = True在项目的settings中是默认的,他表示时间类型里会包含时区信息。默认的时区是UTC,如果不加修改的话,我们在shell里看到的时间会比现实时间晚8h哦
    如果开启了USE_L10N,地区也会被格式化。

    0x02.Naive and aware datetime objects

    打个比方:在做爬虫的时候,页县时间一般是不包含tz_info的,所以在存储的时候因为缺少时区信息,就会出现顶端的这个warning,这种时间就是naive的。
    解决办法就是django提供了make aware方法来为naive time加上tz_info
    使用这个方法要调用到 django.utils 中的timezone

    aware_time = timezone.make_aware(naive_time, timezone.get_current_timezone())
    

    还蛮好理解的吧

    0x03.timezone.now() and datetime.now()

    假设我们现在设置了USE_TZ = True,让我们来参观一下源码
    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()
    

    显而易见的是,只有设置了Use_tz两者才有区别,USE_TZ的情况下,返回的是UTC的时间,并不受项目设置的影响(可能我会设置为Asia/Shanghai)
    再来看看 datetime.now():

    @classmethod
    def now(cls, tz=None):
        "Construct a datetime from time.time() and optional time zone info."
        t = _time.time()
        return cls.fromtimestamp(t, tz)
    

    当直接调用datetime.now()的时候,并没有传进tz的参数,因此_fromtimestamp中的utc参数为False,所以converter被赋值为time.localtime

    _fromtimestamp(cls, t, utc, tz):
    (!省略)
    converter = _time.gmtime if utc else _time.localtime
    (!省略)
    

    所以本质就是,时区会影响now()返回的信息

    0x04.MySQL DatetimeField

    mysql中的时间存储也和USE_TZ的设置有关联,如果你关闭了USE_TZ,
    却向MySQL中存储了一个aware datetime object,就会报错

    "ValueError: MySQL backend does not support timezone-aware datetimes. "

    0x05.参考

    https://docs.djangoproject.com/en/2.2/topics/i18n/timezones/
    https://juejin.im/post/5848b301128fe1006907d5ed

    相关文章

      网友评论

        本文标题:Django timezone

        本文链接:https://www.haomeiwen.com/subject/fbvzcctx.html