Skip to content
forked from paluh/django-tz

Django timezones localization app based on global cache (similar to django.utils.translation).

License

Notifications You must be signed in to change notification settings

jasuca/django-tz

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

django_tz

OVERVIEW

This app is derived from brosner/django-timezones application (http://github.com/brosner/django-timezones). It takes different approach to timezones localization, so I’ve separated those two apps for clarity.

django-tz manages timezones transitions in a manner similar to how django implements language switching. Timezone is stored in global cache and datetime values can be ,,localized’’ according to it in templates with custom template filter or in forms with custom form fields. Because timezone localization works through form fields and template filter you can easily add it to an existing app.

,,What does this application do?’’

  • It defines TimeZoneField which is taken from django-timezones.
  • It provides global (per thread) timezone cache which can be easily updated by custom middleware.
  • It defines LocalizedDateTimeField (+ some additional form fields) – which makes automatically transitions: settings.TIME_ZONE <—> current timezone.
  • It implements template filter to localize datetime values according to cache.
  • It defines set_timezone view which stores given timezone in session or cookie.

HOW DOES IT WORK?

LocalizedDateTimeField

This multivalue form field decompresses given datetime value to datetime and timezone. It contains: DateTimeField and TimezoneField. TimezoneField is set by default to current global timezone (if given value has empty tzinfo) and datetime value is converted from default timezone (settings.TIME_ZONE) to selected timezone. After form submit this process is reversed.

There is also split (similar to SplitDateTimeField) version of this field (SplitLocalizedDateTimeField).

to_global_tz

This template filter takes datetime value and assumes that is given in default timezone (settings.TIME_ZONE) and converts it to current global timezone value.

set_timezone

This is simple view which is nearly copy of django.views.i18n.set_language. It caches timezone in session or cookie. Default middleware uses it to determine current timezone.

USAGE

Example:

Assume that we have Profile model which contains ,,timezone’’ field and MeetUp model with ,,start’’ field:


class Profile(models.Model):
    user = models.ForeignKey(User)
    timezone = models.TimeZoneField()

class MeetUp(models.Model):
    start = models.DateTimeField()
    user = models.ForeignKey(editable=False)

Now we want to switch timezone according to user settings for every request. This can be done through simple middleware:


from django_tz.middleware import GlobalTimezoneMiddleware, get_tz_from_request

class ProfileTimezoneMiddleware(GlobalTimezoneMiddleware):
    def get_tz(self, request):
        if hasattr(request, 'user') and request.user.is_authenticated():
            profile = request.user.get_profile()
            return profile.timezone

        return get_tz_from_request(request)


When you want display your meet ups in template you can use to_global_tz filter which converts it to currently used timezone:


{% load django_tz_tags %}

{{ meetup.start|to_global_tz }}

In forms you should use LocalizedDateTimeField (or it’s split version), which is multi value field (datettime + timezone):


class MeetUpForm(forms.ModelForm):
    start = LocalizedDateTimeField()
    class Model:
        model = MeetUp

This form renders as follows:


<p>
<label for="id_start_0">Start:</label>
<input type="text" name="start_0" id="id_start_0" />

<select name="start_1" id="id_start_1">
<option value="Africa/Abidjan">Africa/Abidjan</option>
<option value="Africa/Accra">Africa/Accra</option>
...
</select>
</p>

I think that in most cases you don’t want to show timezone subfield to the user. To hide it use HiddenInput widget:


class MeetUpForm(forms.ModelForm):
    start = LocalizedDateTimeField(timezone_widget=widgets.HiddenInput)
    ...

Use UTC

From pytz docs:
,,UTC is Universal Time, also known as Greenwich Mean Time or GMT in the United Kingdom. All other timezones are given as offsets from UTC. No daylight savings time occurs in UTC, making it a useful timezone to perform date arithmetic without worrying about the confusion and ambiguities caused by daylight savings time transitions, your country changing its timezone, or mobile computers that move roam through multiple timezones.’’


TIME_ZONE='UTC'

I think it’s better to keep all datetime values in UTC in database and convert them to other default timezone (for example with middleware and global cache).

TESTING

Add django_tz to INSTALLED_APPS and include django_tz.urls your url patterns (there are some tests for views) and run ./manage.py test django_tz.

TODO

  • DST ambiguity problem – there should be is_dst field (which can be ignored for most cases) in all form fields.

About

Django timezones localization app based on global cache (similar to django.utils.translation).

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published