SangminKim
SangminKim

Reputation: 9136

How to get local datetime from django model DateTimeField?

I set up USE_TZ = True and TIME_ZONE.

When I add datetime with timezone object, It just stores UTC time even I put with my local datetime tzinfo.

After that, when I get the datetime I put with local timezone, It returns UTC datetime still.

My question is

First is there any way to get local(settings.TIME_ZONE) datetime from django model not utc?

I know it can be done if I call timezone.localtime(..) but I want Django to return localtime itself automatically.

It means that ModelClass.objects.get(..).datetimeColunm returns local datetimeobject not utc.

Second is there any way to change DB session timezone in Django? I think if I can change DB session timezone in Django, I can get localtime datetime object since DB return local datetime to Django.

Upvotes: 3

Views: 2695

Answers (1)

Kevin Christopher Henry
Kevin Christopher Henry

Reputation: 48952

There are three possible places where you can control the timezone of datetime fields (assuming USE_TZ = True):

  • If your database doesn't support time zones (i.e. is not PostgreSQL) you can use the database TIME_ZONE setting to set the timezone that will be used for both storage and retrieval of datetimes.

  • Your database or database adapter might have a setting that allows you to control the timezone on a per-connection basis. (That is, it doesn't affect the storage of the datetime, it's just a conversion of the returned data.) Django won't change the value returned from the database adapter, so if it's in something other than UTC Django will leave it that way.

  • You could do something within Django to automate the conversion of the returned UTC datetime to TIME_ZONE.

There are several possible ways to do the conversion within Django depending on how general you want the solution to be. For example, if you were just going to access fields on individual instances an additional model method or property would work (e.g. model.datetimeColumnTz()).

The most general way would be to make a custom model field that returned the datetime in the timezone you want. This is untested, but something like this should work:

class DateTimeFieldTz(models.DateTimeField):

    def from_db_value(self, value, expression, connection, context):
        if value is None:
            return None
        else:
            return django.utils.timezone.localtime(value)

Upvotes: 5

Related Questions