save time zone in Django Models

Question:

I am creating a form in Django. I have to put a input type field, which only stores the timezone in database(which will be chosen by a user from a drop Down list at form). I am not able to find out any approach to create this timezone model and how it will return the local time according to saved timezone. I choose following field but it stores also minute hours and second also

 timestamp = models.DateTimeField()

Drop down list should be in form of :

GMT +5:30
GMT +6:00…and so on.

Asked By: Amit Pal

||

Answers:

Neither django nor python provide a set of timezones for you to use.

For that, you will need an additional module like pytz. You can get a list of all timezones like this:

>>> import pytz
>>> pytz.all_timezones ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 'Africa/Asmara',
'Africa/Asmera'....

You can their store the timezone name in a CharField.

By the way, choosing a timezone by “GMT +6:00” is not a good idea. For example, EST is usually 5 hours behind GMT, but for 2 weeks around daylight savings time changes, the offset is different. Also, at some times of year someone in Queensland and someone in New South Wales both have the same GMT offset, but because NSW has DST and Queensland doesn’t, for half the year their GMT offsets are different. The only safe way to list timezones is to list the actual geographic timezones.

Answered By: kdt

django-timezone-field is an app that handles this nicely.

Answered By: yprez

The way I do this is using pytz valid timezone names. I adjusted my list to reflect only the ones I need, i.e.

TIMEZONES = (
    'Canada/Atlantic',
    'Canada/Central',
    'Canada/Eastern',
    'Canada/Mountain',
    'Canada/Pacific',
)

I then have a location class which sets the timezone as a Char Field as such:

class Location(models.Model):
    ....
    time_zone = models.CharField(max_length=100, blank=True, null=True, choices=TIMEZONES)  # 64 min
    ....

Notice I set blank & null to True to make the field optional. Take a look at django-timezone-field fields.py for further ideas.

To use this in my code with pytz, I import timezone:

from pytz import timezone
import datetime
from locations.models import Location # my object that has the time_zone field
loc = Location.objects.get(pk=1)  #get existing location or your object that has time_zone field
utc = pytz.utc
some_utc_date = datetime.datetime(2002, 10, 27, 6, 0, 0).replace(tzinfo=utc) #tz aware
some_date.astimezone(timezone(loc.time_zone))

Replace datetime.datetime(2002, 10, 27, 6, 0, 0) with the datetime field that corresponds to your location or specific object that has the time_zone field. In my case I store all my date fields in UTC format in a MongoDB collection. When I retrieve the data and want to create human readable output, I use the above method to show the date in the output. You can also create a custom tag to handle this in templates. See pytz doc for more details.

Answered By: radtek

I think the above answers are all correct, but I leave mine here as an simple example

class UserProfile(models.Model):  

    import pytz
    TIMEZONES = tuple(zip(pytz.all_timezones, pytz.all_timezones))

    # ...
    timezone = models.CharField(max_length=32, choices=TIMEZONES, 
    default='UTC')
# ...
Answered By: Slipstream

If you are migrating from pytz to zoneinfo:

try:
    import zoneinfo
except ImportError:
    from backports import zoneinfo

class UserProfile(models.Model):  
    TIMEZONE_CHOICES = ((x, x) for x in sorted(zoneinfo.available_timezones(), key=str.lower))
    timezone = models.CharField("Timezone", choices=TIMEZONE_CHOICES, max_length=250, default='Etc/GMT+2')
Answered By: run_the_race