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

    0x00.问题发现 关于时间处理的爱恨情仇~每个网站存储时间都有不同的格式,或者说有不同的显示格式,这一点在pyt...

  • django time problem

    all time in django are timezone-sensitive(AKA. offeset-aw...

  • Django timezone() 时间问题

    最近在做一个问卷系统,使用Django框架,其中在与时间有关的变量时使用timezone()遇到的主要有两个问题。...

  • DateTimeField

    默认为时区时间时,需要导入django内置的timezone模块 默认为当天时,需要导入python内置的date...

  • Django和Python中的Timezone处理

    总的原理 进入到django数据库中的时间一定是timezone aware的时间,如果要生成时间,要通过repl...

  • django技巧

    关于时间:timezone.localtime(timezone.now())delta = datetime.t...

  • PHP处理时间的常用函数

    date_default_timezone_get()返回默认时区 date_default_timezone_s...

  • 2019-04-24

    TimeZone【】

  • TimeZone

    一、简介 TimeZone 定义了时区的行为,时区值 表示 相对 格林威治标准时间(GMT)的 时间偏移量(正或负...

  • timezone + dateparse

    timezone FixedOffset tzinfo的子类 get_fixed_timezone 可接收参数ti...

网友评论

    本文标题:Django timezone

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