DEV Community

Alex
Alex

Posted on

Converting an aware datetime object from one timezone to another in python

Problem

I recently ran into a beginner problem at work where I had to write a utility method that would receive a timestamp and the timezone of the timestamp and convert it into a human readable form for UTC timezone. Now, this looked straightforward except that I hadn't worked with the datetime library before. So after much searching, I came across the very useful datetime.astimezone() method which helped solve the problem.

About the datetime.astimezone(tz=None) method

The astimezone(tz=None) takes in a datetime object and returns a new datetime object with the time set to the equivalent time in the datetime.tzinfo attribute tz. If no tz object is not provided, it defaults to UTC timezone.

>>> from datetime import datetime
>>> from pytz import timezone

# Convert the local time in London to the local time in Sydney
>>> datetime.now(timezone('Europe/London')).astimezone(timezone('Australia/Sydney'))
datetime.datetime(2019, 10, 15, 22, 48, 4, 449019, tzinfo=<DstTzInfo 'Australia/Sydney' AEDT+11:00:00 DST>)

# Convert the time in London to it's equivalent in UTC
>>> datetime.now(timezone('Europe/London')).astimezone()
datetime.datetime(2019, 10, 15, 11, 54, 58, 952388, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))

Final Solution to my problem

Below is the solution I came up with which made use of the datetime.astimezone() method in the datetime library. Note that the code has been simplified to allow the reader to grasp it more easily.

from datetime import datetime
from pytz import timezone

def change_timezone_of_datetime_object(date_time_object, new_timezone_name):
    """Return the *date_time_object* with it's timezone changed to *new_timezone_name*

    :param date_time_object: The datetime object whose timezone is to be changed
    :type date_time_object: datetime
    :param new_timezone_name: The name of the timezone to which the *date_time_object* is to be changed to
    :type new_timezone_name: str
    :rtype: datetime
    """
    # Create a pytz.timezone object for the new_timezone
    new_timezone_object = timezone(new_timezone_name)
    # Update the timezone of the datetime object
    date_time_object = date_time_object.astimezone(new_timezone_object)
    # Return the converted datetime object
    return date_time_object

# Testing
>>> dtobj = datetime.now(timezone('UTC'))
>>> change_timezone_of_datetime_object(dtobj, 'Europe/London')
datetime.datetime(2019, 10, 15, 13, 56, 30, 220369, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)

References

Top comments (1)

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Great content man, thanks!