Skip to content

Add resolve_imaginary function to tz #339

@pganssle

Description

@pganssle

It occurs to me from looking at arrow-py/arrow#72 that it might be useful to have a resolve_imaginary function built in to dateutil, similar to this one that I wrote as an example:

from dateutil.tz import datetime_exists
from datetime import timedelta

def resolve_imaginary(dt):
    if dt.tzinfo is not None and not datetime_exists(dt):
        # You need to shift this by the difference between the current offset
        # and the previous one. Historically, there has never been a time zone
        # shift of more than 24 hours, nor has there been two changes to a time
        # zone within 24 hours, so if we take the "wall time" - 24 hours, we
        # should be OK, barring any insane time zone behavior in the future.
        curr_offset = dt.utcoffset()
        old_offset = (dt - timedelta(hours=24)).utcoffset()

        dt += curr_offset - old_offset

    return dt

I'm fairly certain that an imaginary date you always want to "slide forward" - it will never be that you accidentally wanted to go back.

We have a particular advantage here because, like with datetime_ambiguous and datetime_exists, we can define an API in the tzinfo objects themselves that lets us avoid the "look back 24 hours" heuristic if at all possible. This works for all known transitions in the Olson database, but we could get a sudden breakage if, for example, a specific zone changes their DST and then changes back within 24 hours, or something like that.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions