2

I have a codebase where this error might be pretty often in it: Adding a timedelta to a timezone-aware datetime object can result in a datetime object which has the right timezone and the right point in time, but the wrong offset due to DST.

I would like to overwrite the behviour of datetime.__add__. I thought I subclass datetime and then import my modified subclass, but due to datetime being immutable it is more complicated than I thought.

Here is what I tried:

#!/usr/bin/env python

import datetime as dt_orig

# 3rd party
import pytz


class datetime(dt_orig.datetime):
    def __new__(cls, *args, **kwargs):
        tzstring = None
        if 'tzinfo' in kwargs and isinstance(kwargs['tzinfo'], str):
            tzstring = kwargs['tzinfo']
            kwargs['tzinfo'] = dt_orig.timezone.utc
        dt_obj = super().__new__(cls, *args, **kwargs)
        # if tzstring is not None:  # When this is uncommented, it's not the custom datetime class but the standard Python class
        #     dt_obj = dt_obj.astimezone(pytz.timezone(tzstring))
        return dt_obj

    def __add__(self, other):
        if isinstance(other, dt_orig.timedelta):
            tmp = super().__add__(other)  # creates a datetime.datetime
            tmp = tmp.astimezone(pytz.utc).astimezone(tmp.tzinfo)
            return tmp
        else:
            return super().__add__(other)

    __radd__ = __add__

This way I can create a custom datetime object, but when I apply obj.astimezone(...) (or any other method like add) I get the datetime.datetime back.

How can I get my custom datetime object back while keeping the implementation of datetime.datetime in most cases?

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958

0 Answers0