Code‎ > ‎web2py recipes‎ > ‎

UTC to localtime and back in web2py

Here is how we can detect the user timezone in web2py, and convert from localtime to UTC and back, so that dates are always stored in UTC in web2py, and yet displayed in the user's local timezone.  Many thanks to Massimo and Niphold for this!

Detecting the user timezone

First, there is the task of detecting the user timezone.  Put the following code in one of the models (e.g., 

is_timezone_unknown = (session.user_timezone is None)
user_timezone = session.user_timezone or 'UTC'

This code works in tandem with the following code, that you have to put in layout.html:

  <!-- Code for timezone detection -->
  {{if is_timezone_unknown:}}
    <script src="{{=URL('static', 'plugin_timezone/jstz.min.js')}}"></script>
      $(function() {
        var tz_name = jstz.determine();
        $.get("{{=URL('default', 'set_timezone')}}", tz_name);

In, you need to put the code to receive the above Ajax call:

def set_timezone():
    """Ajax call to set the timezone information for the session."""
    tz_name =
    from pytz import all_timezones_set
    if tz_name in all_timezones_set:
        session.user_timezone = tz_name

The code above works as follows.  If the timezone is not known in the user session, the javascript plugin jstz.min.js is loaded.  This detects the timezone in the browser, and sends to the server the timezone name via the $.get JQuery AJAX call. 

In order for this to work, you have to do two additional things:
  • Install the jstz javacript or the plugin_timezone in your application (also read the nice documentation of the plugin_timezone).
  • Install the Python pytz package.  If you are working on appengine, you need to install this version of pytz in your site-packages directory -- the standard version of pytz will not work well. 

Converting data to-from the user timezone

Once you know the time in the user timezone, you need to convert the times to and from UTC as you store data in the database, or read from it.  These two lines create a validator for a datetime localized in the user's local time (you can change the date format to be whatever you like):

DATE_FORMAT = '%Y-%m-%d %H:%M %Z'
datetime_validator = IS_DATETIME(timezone=pytz.timezone(user_timezone), format=DATE_FORMAT)

You can then declare fields to use this validator as follows:

db.table.field.requires = datetime_validator