1

I'm facing a python timezones problem and am unsure of what is the right approach to deal with it. I have to calculate timedeltas from given start and end DateTime objects. It can happen that daylight saving time will change during the runtime of my events, so I have to take that into account.

So far I've learned that for this to work I need to save my start and end times as timezone aware DateTime objects rather than regular UTC DateTimes.

I've been looking into DateTime.tzinfo, pytz,and dateutil but from what I understand these are all mostly focused on localised display of UTC DateTime objects or calculating the offsets between different timezones. Other helpers I found expect the timezone as a UTC offset, so would already require me to know if a date is affected by daylight saving or not.

So, I guess my question is: Is there a way so save a DateTime as "Central Europe" and have it be aware of daytime savings when doing calculations with them? Or, if not, what would be the established way to check if two DateTime objects are within daylight saving, so I can manually adjust the result if necessary?

I'd be grateful for any pointers.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
Overgrown
  • 13
  • 2
  • 1
    Not sure why you think pytz etc. are insufficient. You localise two `datetime`s using one of those libraries to a specific timezone like `Europe/Berlin`, then you subtract them to get their delta. This will take DST into account. What exactly have you tried and where are you stuck? – deceze Jan 27 '23 at 09:17
  • 1
    Regarding pytz, a more up-to-date way to handle time zones in Python is to use [zoneinfo](https://docs.python.org/3/library/zoneinfo.html) (Python 3.9), see e.g. [Python Timezone conversion](https://stackoverflow.com/a/62142178/10197418) or [Display the time in a different time zone](https://stackoverflow.com/a/63628816/10197418) – FObersteiner Jan 27 '23 at 09:41
  • Might also be helpful: [Storing UTC is not a silver bullet](https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/) – FObersteiner Jan 27 '23 at 09:53

1 Answers1

0

You just need to produce an aware (localised) datetime instance, then any calculation you do with it will take DST into account. Here as an example with pytz:

>>> import pytz
>>> from datetime import *
>>> berlin = pytz.timezone('Europe/Berlin')
>>> d1 = berlin.localize(datetime(2023, 3, 25, 12))
datetime.datetime(2023, 3, 25, 12, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>)
>>> d2 = berlin.localize(datetime(2023, 3, 26, 12))
datetime.datetime(2023, 3, 26, 12, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>)
>>> d2 - d1
datetime.timedelta(seconds=82800)
>>> (d2 - d1).total_seconds() / 60 / 60
23.0
deceze
  • 510,633
  • 85
  • 743
  • 889
  • pytz and a star-import, are you serious? ^^ – FObersteiner Jan 27 '23 at 09:30
  • 1
    I just happened to have a pytz install at hand, and for short REPL examples, yes, I'll even `import *`. :P – deceze Jan 27 '23 at 09:31
  • Thank you! This example is exactly what I was trying to do. I'd been reading the examples on https://pythonhosted.org/pytz/ and got thoroughly confused. – Overgrown Jan 27 '23 at 09:40
  • I'll add a link to zoneinfo in the question's comments ;-) – FObersteiner Jan 27 '23 at 09:42
  • @Overgrown Maybe because pytz is purely concerned with producing a `datetime` object with the correct `tzinfo`. It does not concern itself with timedeltas, that is core Python functionality. – deceze Jan 27 '23 at 09:42
  • So, just to make sure, the recommended way is still storing all my DateTimes as regular UTC and then just using localize() when using them in calculations? Or should I use pytz to add the respective offsets and store those also. From what I read common best practice would be UTC only? – Overgrown Jan 27 '23 at 09:48
  • @Overgrown That depends a lot on how you "store" them. Most databases will normalise any datetimes to UTC anyway, even if you can pass them to the database as local time. If your storage can store localised aware datetimes, I'd go for that; but in practice you'll probably be storing UTC times and separately what timezone they should be in, and then localise the UTC times in Python code. – deceze Jan 27 '23 at 09:50