How to make an unaware datetime timezone aware in python

前端 未结 12 2079
一向
一向 2020-11-22 08:39

What I need to do

I have a timezone-unaware datetime object, to which I need to add a time zone in order to be able to compare it with other timezon

相关标签:
12条回答
  • 2020-11-22 09:02

    Changing between timezones

    import pytz
    from datetime import datetime
    
    other_tz = pytz.timezone('Europe/Madrid')
    
    # From random aware datetime...
    aware_datetime = datetime.utcnow().astimezone(other_tz)
    >> 2020-05-21 08:28:26.984948+02:00
    
    # 1. Change aware datetime to UTC and remove tzinfo to obtain an unaware datetime
    unaware_datetime = aware_datetime.astimezone(pytz.UTC).replace(tzinfo=None)
    >> 2020-05-21 06:28:26.984948
    
    # 2. Set tzinfo to UTC directly on an unaware datetime to obtain an utc aware datetime
    aware_datetime_utc = unaware_datetime.replace(tzinfo=pytz.UTC)
    >> 2020-05-21 06:28:26.984948+00:00
    
    # 3. Convert the aware utc datetime into another timezone
    reconverted_aware_datetime = aware_datetime_utc.astimezone(other_tz)
    >> 2020-05-21 08:28:26.984948+02:00
    
    # Initial Aware Datetime and Reconverted Aware Datetime are equal
    print(aware_datetime1 == aware_datetime2)
    >> True
    
    0 讨论(0)
  • 2020-11-22 09:03

    quite new to Python and I encountered the same issue. I find this solution quite simple and for me it works fine (Python 3.6):

    unaware=parser.parse("2020-05-01 0:00:00")
    aware=unaware.replace(tzinfo=tz.tzlocal()).astimezone(tz.tzlocal())
    
    0 讨论(0)
  • 2020-11-22 09:04

    In general, to make a naive datetime timezone-aware, use the localize method:

    import datetime
    import pytz
    
    unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
    aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)
    
    now_aware = pytz.utc.localize(unaware)
    assert aware == now_aware
    

    For the UTC timezone, it is not really necessary to use localize since there is no daylight savings time calculation to handle:

    now_aware = unaware.replace(tzinfo=pytz.UTC)
    

    works. (.replace returns a new datetime; it does not modify unaware.)

    0 讨论(0)
  • 2020-11-22 09:04

    Use dateutil.tz.tzlocal() to get the timezone in your usage of datetime.datetime.now() and datetime.datetime.astimezone():

    from datetime import datetime
    from dateutil import tz
    
    unlocalisedDatetime = datetime.now()
    
    localisedDatetime1 = datetime.now(tz = tz.tzlocal())
    localisedDatetime2 = datetime(2017, 6, 24, 12, 24, 36, tz.tzlocal())
    localisedDatetime3 = unlocalisedDatetime.astimezone(tz = tz.tzlocal())
    localisedDatetime4 = unlocalisedDatetime.replace(tzinfo = tz.tzlocal())
    

    Note that datetime.astimezone will first convert your datetime object to UTC then into the timezone, which is the same as calling datetime.replace with the original timezone information being None.

    0 讨论(0)
  • 2020-11-22 09:05

    In the format of unutbu's answer; I made a utility module that handles things like this, with more intuitive syntax. Can be installed with pip.

    import datetime
    import saturn
    
    unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
    now_aware = saturn.fix_naive(unaware)
    
    now_aware_madrid = saturn.fix_naive(unaware, 'Europe/Madrid')
    
    0 讨论(0)
  • 2020-11-22 09:09

    This codifies @Sérgio and @unutbu's answers. It will "just work" with either a pytz.timezone object or an IANA Time Zone string.

    def make_tz_aware(dt, tz='UTC', is_dst=None):
        """Add timezone information to a datetime object, only if it is naive."""
        tz = dt.tzinfo or tz
        try:
            tz = pytz.timezone(tz)
        except AttributeError:
            pass
        return tz.localize(dt, is_dst=is_dst) 
    

    This seems like what datetime.localize() (or .inform() or .awarify()) should do, accept both strings and timezone objects for the tz argument and default to UTC if no time zone is specified.

    0 讨论(0)
提交回复
热议问题