pythondatetimestrptimepytz

Datetime doesn't seem to be converting


I am trying to cast from a 'created_at' value in UTC to a value in Eastern Time. But after converting the time using astimezone, the time is the same and raises the assert error that the two times are identical. I tried making the datetime aware by doing f_time.replace(tzinfo=pytz.utc) although I am not sure this is necessary.

def get_f_datetime(self, rec):
    f_time = datetime.datetime.strptime(rec['created_at'], "%Y-%m-%dT%H:%M:%SZ")
    f_time = f_time.replace(tzinfo=pytz.utc)
    eastern_time = f_time.astimezone(pytz.timezone('US/Eastern'))
    try:
        assert f_time != eastern_time
    except AssertionError():
        raise Exception(f'the time is the utc: {f_time} eastern: {eastern_time}. This is wrong.')
    dt_string= eastern_time.strftime("%m/%d/%Y %I:%M %p")
    return dt_string

The assertion error is triggering, indicating that f_time is identical to eastern_time. I want the eastern time to be offset.


Solution

  • As you're using strptime, your datetime object f_time is 'timezone naive'. When you attach the timezone information, it is only added as an extra information to the timezone naive datetime object, it is not necessarily making it a timezone aware utc datetime.

    To attach the timezone information correctly and make your datetime object timezone aware, use localize. As follows:

    f_time = pytz.utc.localize(f_time)  # make the datetime object aware
    

    i.e., the following works:

    import pytz
    import datetime
    
    def get_f_datetime(S):
        f_time = datetime.datetime.strptime(S, "%Y-%m-%dT%H:%M:%SZ")
        f_time = pytz.utc.localize(f_time)  # make the datetime object aware
        eastern_time = f_time.astimezone(pytz.timezone('US/Eastern'))
        try:
            assert f_time != eastern_time
        except AssertionError:
            raise Exception(f'the time is the utc: {f_time} eastern: {eastern_time}. This is wrong.')
        dt_string = eastern_time.strftime("%m/%d/%Y %I:%M %p")
        return dt_string
    
    get_f_datetime(S="2023-06-05T16:03:11Z")
    

    Logs:

    Exception: the time is the utc: 2023-06-05 16:03:11+00:00 eastern: 2023-06-05 12:03:11-04:00. This is wrong.
    

    The assertion is still triggering because these two datetimes are actually referring to the same time, thus equal. See following discussion: https://bugs.python.org/issue43237