Menu Close

Django DateTimeZoneField

In a scheduling project I’ve been working on, I’ve come across the need to ingest and present a lot of datetime information. The input will include many different timezones and may not reflect the user’s timezone. Thus the user must specify the timezone in the datetime stamp field. You’d think Django would handle this out of the box, but it really doesn’t. My solution is to have the user explicitly specify the timezone in the datetime field via a neat widget, and have the server side coerce that data into UTC before storing it. As long as your django instance has timezone settings configured, this will let you store a naïve datetime that is guaranteed to be UTC. There are benefits to this – datetime arithmetic becomes simple and the presentation layer can handle converting to other timezones.

My solution is to create a new field class that inherits from forms.DateTimeField, and simply override the way it initially converts the string value to a datetime stamp. I use the dateutil parser to give the datetime string a bit of wiggle room , though in most cases the javascript widget will produce the input. The parsed datetime object will be timezone aware, but is then converted to UTC before django handles form validation / input cleaning. I didn’t need to, but you could also explicitly remove the tzinfo at this stage.

Define a new field type in your

class DateTimeZoneField(forms.DateTimeField):
    def to_python(self, value):
        "Respect the TZ input and immediately convert the value to UTC" 
        if not value:
            return None 
        dtz = dateutil.parser.parse(value).astimezone(pytz.utc) 
        return dtz

When defining your form / modelform, explicitly specify the field and widget, i.e:

class TimeZoneTestForm(forms.ModelForm):
    start = DateTimeZoneField(widget=forms.DateTimeInput(attrs={'class':'starttime-form'}))
    class Meta:
        model = TimeZoneTest
        fields = ('start',)

In the template you render your form in, use the class you’ve specified to enable a jquery-ui datepicker. In my case, I’m using jquery-ui-timepicker:

        dateFormat: 'yy-mm-dd',
        timeFormat: 'HH:mm:ss Z'

Don’t forget the css/js dependencies:

<script src="/static/js/jquery.js"></script>
<link href="/static/css/jquery-ui.min.css" rel="stylesheet" type="text/css">
<link href="/static/css/jquery-ui-timepicker-addon.min.css" rel="stylesheet" type="text/css">
<script src="/static/js/jquery-ui.min.js"></script>
<script src="/static/js/jquery-ui-timepicker-addon.min.js"></script>

 4,669 total views,  1 views today

Leave a Reply

Your email address will not be published. Required fields are marked *