如何使TimeField有时区感知?

Jos*_*osh 8 django

有时您需要从用户那里收集时间而不收集相关日期.例如,如果用户正在配置每天同时运行的重复事件.但Django TimeField并没有使用时区.但是,在这种特殊情况下(并且可能在您自己记录时间的任何时候),时区是一个重要因素.那么,你如何存储时区感知时间?

Jos*_*osh 6

答案是你不知道。为了使时间成为时区感知,它必须具有与之关联的日期。想想夏令时...我的解决方案是DateTimeField在模型上使用a 并覆盖如下形式:

# Model
class MyModel(models.Model):
    time_of_day = models.DateTimeField()

# Form Fields
from django.forms.util import from_current_timezone
from django.forms.util import to_current_timezone
from django.utils import timezone

class TzAwareTimeField(forms.fields.TimeField):
    def prepare_value(self, value):
        if isinstance(value, datetime.datetime):
            value = to_current_timezone(value).time()
        return super(TzAwareTimeField, self).prepare_value(value)

    def clean(self, value):
        value =  super(TzAwareTimeField, self).to_python(value)
        dt = to_current_timezone(timezone.now())
        return dt.replace(
            hour=value.hour, minute=value.minute,
            second=value.second, microsecond=value.microsecond)


# Forms
class MyForm(forms.ModelForm):
    time_of_day = TzAwareTimeField()
Run Code Online (Sandbox Code Playgroud)

  • 您的开场白(以及Django的行为)与Python处理“时间”对象的方式不一致。Python的“时间”对象可能有一个“ tzinfo”字段,允许一个不带关联日期的时区感知“时间”对象,这在某些情况下很有用,例如将日期存储在其他地方。我刚刚在Django的Day模型中遇到了open_time和close_time TimeField的问题。理想情况下,这些时间可以识别时区,但是不能因为Django不支持时区而已。 (4认同)