How to add a timezone to a datetime object?
Asked Answered
M

2

9

I have a variable which is grabbing a date object from a file. My aim is to add a timezone to this object so that it automatically changes the time based on the date its it then. So I expected it to add +1hour to it for dates in summertime (between march and october) and add +0hour in wintertime (between october and march).

 dt_object =  '20200901-01u30m30s'    
 dt_object = datetime.datetime.strptime(dt_object, '%Y%m%d-%Hu%Mm%Ss') 

 >>>print(dt_object) >>> 2020-09-01 01:30:30 
                             
 timezone= 'Europe/Amsterdam'
 dt_object_tz = pytz.utc.localize(dt_object).astimezone(pytz.timezone(timezone))        
 timeDiff = dt_object_tz.utcoffset().total_seconds()
 official_time = pytz.utc.localize(dt_object_tz+datetime.timedelta(seconds=timeDiff))

 >>>print(official_time) >>> 2020-09-01 03:30:30+00:00 
                             

As you can see this is a datetime object of september (so summertime!), I literally have no clue why it adds +2hours instead of 1 hour.... Can someone explain it and tell me what went wrong?

I just want my datetime object to be timezone-aware so it autmatically changes from summer to wintertime based on the date in grabs.

Miscreant answered 16/12, 2020 at 7:36 Comment(4)
you input (e.g. '20200901-01u30m30s' ), does it represent UTC or local time, i.e. the wall time in e.g. 'Europe/Amsterdam'?Jesicajeske
@MrFuppes that is the system time where the files get generated/grabbed. I dont know what timezone it is but I know in winter it should be equal to Europe/Amsterdam and in summer it should be +1hourMiscreant
Europe/Amsterdam is UTC+2 in summer and UTC+1 in winter, is that what you mean? In your code, you treat the string as if it was UTC; if you apply astimezone, you effectively convert from UTC to the timezone you specify.Jesicajeske
@MrFuppes ahh so becaue I treat it as UTC it adds 2 hours. So How else should I treat it?Miscreant
J
15

Regarding pytz, note that there is zoneinfo in the standard lib. No need for a third party library for time zone handling with Python >= 3.9. Example usage.


Then, if your input represents wall time in some time zone, you can just localize. If the input represents UTC, you can set the tzinfo to UTC a bit more easily and then convert to local time using astimezone:

from datetime import datetime, timezone
import pytz

s = '20200901-01u30m30s'    
local_tz = 'Europe/Amsterdam'

# if s represents local time, just localize:
dtobj_tz = pytz.timezone(local_tz).localize(datetime.strptime(s, '%Y%m%d-%Hu%Mm%Ss'))
# datetime.datetime(2020, 9, 1, 1, 30, 30, tzinfo=<DstTzInfo 'Europe/Amsterdam' CEST+2:00:00 DST>)

# if s represents UTC, set it directly:
dtobj_utc = datetime.strptime(s, '%Y%m%d-%Hu%Mm%Ss').replace(tzinfo=timezone.utc)
# ...and convert to desired tz:
dtobj_tz = dtobj_utc.astimezone(pytz.timezone(local_tz))
# datetime.datetime(2020, 9, 1, 3, 30, 30, tzinfo=<DstTzInfo 'Europe/Amsterdam' CEST+2:00:00 DST>)
Jesicajeske answered 16/12, 2020 at 7:54 Comment(9)
okay s does not represent UTC so I did your first part. But when I print dtobj_tz I receive this: 2020-09-01 01:30:30+02:00Miscreant
@TangerCity: what would you expect instead?Jesicajeske
I would expect 2020-09-01 01:30:30+1:00 because that is a date in summer and if its a date in winter i would expect 2020-12-01 01:30:30+0:00. So short said: summer +1 and winter +0.Miscreant
@TangerCity: according to timeanddate.com, it's UTC+2 with DST and UTC+1 without DST. Europe/London would have UTC+1/UTC+0 for example.Jesicajeske
But that means we are both assuming that s is UTC. It should be something else....I dont know how I can know what it should beMiscreant
@TangerCity: if you can determine unambiguously to which time zone your input belongs, another option might be to work with naive datetime (tzinfo=None).Jesicajeske
but means I need to manually change my code to winter and summer time once a year...Miscreant
@TangerCity: not exactly but I'm not saying that naive datetime is your best option. I'd suggest to put some effort in determining the exact time zone of your source (which machine writes the file, in what process, with which program etc.). Information on that seems to be the key issue here.Jesicajeske
True I will have to investigate that. Thank you for your help though.Miscreant
D
2

Above python 3.9, it is recommended to use the standard 1st party python libraries / modules such as zoneinfo.

pytz offers no advantages beyond backwards compatibility with code written for earlier versions of Python.

You can achieve the same with the following code:

from datetime import datetime
from zoneinfo import ZoneInfo


date = datetime.now(tz=ZoneInfo("Europe/Amsterdam"))

The outcome:

datetime.datetime(2024, 8, 15, 11, 4, 47, 972573, tzinfo=zoneinfo.ZoneInfo(key='Europe/Amsterdam'))
Delores answered 15/8 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.