Search code examples
pythondjangopytz

Python Django convert timestamp from UTC to local timezone


Im am working with Django + DRF, to develop a REST API. I have configured the django settings to work with the timezone support on:

USE_I18N = True
USE_L10N = True
USE_TZ = True

As previously mentioned, my database is receiving and storing data in UTC. My problem is that for some users (each user has their configuration) I must return responses in their time zone (usually in UTC-3 or UTC-2). I was reading several posts and tried several combinations of: astimezone and normalize without succes. I attach my attempts:

timezone_arg = pytz.timezone('America/Buenos_Aires')
print(ts_a, ts_b)
ts_a = ts_a.astimezone(timezone_arg) 
ts_b = ts_b.astimezone(timezone_arg) 
print(ts_a, ts_b)

utc = pytz.timezone('UTC')
ts_a = timezone_arg.normalize(ts_a.astimezone(utc))
ts_b = timezone_arg.normalize(ts_b.astimezone(utc))
print(ts_a, ts_b)

I am getting the following:

2022-06-17 05:39:09 2022-06-17 05:46:49
2022-06-17 05:39:09-03:00 2022-06-17 05:46:49-03:00
2022-06-17 05:39:09-03:00 2022-06-17 05:46:49-03:00

I understand that django is interpreting that what I am telling it is that the timestamps are already in UTC-3... and it is normalizing them to UTC. But what I want is to cast from UTC to UTC-3. My input/output should be:

2022-06-17 05:39:09 2022-06-17 05:46:49
2022-06-17 02:39:09 2022-06-17 02:46:49

Since I don't only work with the time zone of Argentina (UTC-3), I can't compute a timedelta of 3 hours.. the difference may be different for other clients. My last resource would be to use the -03:00:00 at the end of the normalized timestamps, and do a subtraction. But I would like to know if there is a more direct and correct way.These timestamps are sent directly to users and must be easy to read.


Solution

  • It would be something like that:

    from datetime import datetime
    from dateutil import tz
    
    from_zone = tz.tzutc()
    to_zone = tz.tzlocal()
    
    utc = datetime.strptime('2022-06-17 05:39:09', '%Y-%m-%d %H:%M:%S')
    
    utc = utc.replace(tzinfo=from_zone)
    
    # Convert to local time zone
    to_local_time = utc.astimezone(to_zone)
    
    print(utc,to_local_time)