pendulum icon indicating copy to clipboard operation
pendulum copied to clipboard

pendulum.instance() incorrectly converts timezone to "+00:00" instead of "UTC"

Open ecerulm opened this issue 3 years ago • 1 comments

  • [x] I am on the latest Pendulum version.
  • [x] I have searched the issues of this repo and believe that this is not a duplicate.
  • OS version and name: macOS Big Sur
  • Pendulum version: 2.1.2

Issue

from datetime import datetime,timezone

dt = datetime(2019, 8, 1, tzinfo=timezone.utc) # datetime.datetime(2019, 8, 1, 0, 0, tzinfo=datetime.timezone.utc)
pdt = pendulum.instance(dt) # DateTime(2019, 8, 1, 0, 0, 0, tzinfo=Timezone('+00:00'))

the timezone returned is Timezone('+00:00') instead of the expected Timezone('UTC') this is not consistent with the behaviour of the pendulum.datetime constructor:

pdt2 = pendulum.datetime(2019, 8, 1, tz=timezone.utc) #  DateTime(2019, 8, 1, 0, 0, 0, tzinfo=Timezone('UTC'))

So the same original timezone timezone.utc is converted to Timezone('+00:00') by pendulum.instance() and to Timezone('UTC') by pendulum.datetime.

I consider that timezone.utc should be always interpreted as pendulum.timezone('UTC')

ecerulm avatar Jun 23 '21 09:06 ecerulm

Quick debug indicates that

hasattr(tz, "localize") is False

in this case (within the pendulum.instance code:)

def instance(
    dt, tz=UTC
):  # type: (_datetime.datetime, Optional[Union[str, _Timezone]]) -> DateTime
    """
    Create a DateTime instance from a datetime one.
    """
    if not isinstance(dt, _datetime.datetime):
        raise ValueError("instance() only accepts datetime objects.")

    if isinstance(dt, DateTime):
        return dt

    tz = dt.tzinfo or tz

    # Checking for pytz/tzinfo
    if isinstance(tz, _datetime.tzinfo) and not isinstance(tz, _Timezone):
        # pytz
        if hasattr(tz, "localize") and tz.zone:
            tz = tz.zone
        else:
            # We have no sure way to figure out
            # the timezone name, we fallback
            # on a fixed offset
            tz = tz.utcoffset(dt).total_seconds() / 3600

    return datetime(
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, tz=tz
    )

(I am using Python 3.9.12 and pendulum 2.1.2)

But I see the code on master has already changed: https://github.com/sdispater/pendulum/blob/master/pendulum/init.py#L172

And

_safe_timezone(tz)
>>Timezone('UTC')

would fix the issue. So I guess it is a matter of waiting for a release.

stripedpumpkin avatar Feb 15 '23 14:02 stripedpumpkin