Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make TimeField timezone-aware?

Tags:

django

There are occasions when you need to collect a time from a user without collecting an associated date. For example, if the user is configuring a repeating event that runs every day at the same time. Django's TimeField doesn't play with timezones though. However, in this particular case (and probably any time you record a time by itself), timezone is an important factor. So, how do you store a timezone-aware time?

like image 685
Josh Avatar asked Nov 05 '13 00:11

Josh


1 Answers

The answer is you don't. For a time to be timezone aware, it has to have a date associated with it. Think of daylight savings... My solution for this was to use a DateTimeField on the model and to override the form like so:

# 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()
like image 187
Josh Avatar answered Nov 15 '22 17:11

Josh