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 timezoneFirst, there is the task of detecting the user timezone. Put the following code in one of the models (e.g., db.py):
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> <script> $(function() { var tz_name = jstz.determine(); $.get("{{=URL('default', 'set_timezone')}}", tz_name); }); </script> {{pass}} In default.py, 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 = request.vars.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:
Converting data to-from the user timezoneOnce 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 |
Code > web2py recipes >