[Python] Python pass tzinfo to naive datetime without pytz

Discussão em 'Python' iniciado por Stack, Setembro 18, 2025.

  1. Stack

    Stack Membro Participativo

    I've been struggling for way too long on dates/timezones in Python and was thinking someone could give me a hand here.

    Basically I want to do a conversion in UTC and taking into account DST changes.

    I've created the following tzinfo class from one of the Python tutorials (not 100% accurate I know but it doesn't need to):

    from datetime import tzinfo, timedelta, datetime

    ZERO = timedelta(0)
    HOUR = timedelta(hours=1)

    def first_sunday_on_or_after(dt):
    days_to_go = 6 - dt.weekday()
    if days_to_go:
    dt += timedelta(days_to_go)
    return dt

    DSTSTART_2007 = datetime(1, 3, 8, 2)
    DSTEND_2007 = datetime(1, 11, 1, 1)
    DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
    DSTEND_1987_2006 = datetime(1, 10, 25, 1)
    DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
    DSTEND_1967_1986 = DSTEND_1987_2006

    class USTimeZone(tzinfo):

    def __init__(self, hours, reprname, stdname, dstname):
    self.stdoffset = timedelta(hours=hours)
    self.reprname = reprname
    self.stdname = stdname
    self.dstname = dstname

    def __repr__(self):
    return self.reprname

    def tzname(self, dt):
    if self.dst(dt):
    return self.dstname
    else:
    return self.stdname

    def utcoffset(self, dt):
    return self.stdoffset + self.dst(dt)

    def dst(self, dt):
    if dt is None or dt.tzinfo is None:
    # An exception may be sensible here, in one or both cases.
    # It depends on how you want to treat them. The default
    # fromutc() implementation (called by the default astimezone()
    # implementation) passes a datetime with dt.tzinfo is self.
    return ZERO
    assert dt.tzinfo is self

    # Find start and end times for US DST. For years before 1967, return
    # ZERO for no DST.
    if 2006 < dt.year:
    dststart, dstend = DSTSTART_2007, DSTEND_2007
    elif 1986 < dt.year < 2007:
    dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
    elif 1966 < dt.year < 1987:
    dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
    else:
    return ZERO

    start = first_sunday_on_or_after(dststart.replace(year=dt.year))
    end = first_sunday_on_or_after(dstend.replace(year=dt.year))

    # Can't compare naive to aware objects, so strip the timezone from
    # dt first.
    if start <= dt.replace(tzinfo=None) < end:
    return HOUR
    else:
    return ZERO


    On the other side I have an arbitrary date object in EST, and I want to know the number of hours they differ by taking into account DST.

    I've tried something like this:

    >>> Eastern = ustimezone.USTimeZone(-5, "Eastern", "EST", "EDT")
    >>> x = datetime.date.today() # I actually get an arbitrary date but this is for the example
    >>> x_dt = datetime.datetime.combine(x, datetime.time())
    >>> x_dt_tz = x_dt.astimezone(Eastern)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ValueError: astimezone() cannot be applied to a naive datetime


    I've seen several posts who tell to use localize from the pytz module, but unfortunately I am not able to use additional modules, so impossible to use pyzt

    Does anyone know how I can get this naive datetime into a timezoned object without using pytz?

    Continue reading...

Compartilhe esta Página