Skip to content
18 changes: 18 additions & 0 deletions pendulum/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,24 @@ def __reduce_ex__( # type: ignore[override]
]:
return self.__class__, self._getstate(protocol)

def __le__(self, other: datetime.date) -> bool:
if isinstance(other, DateTime):
return self._cmp(other) <= 0
return super().__le__(other.date())

def __lt__(self, other: datetime.date) -> bool:
if isinstance(other, DateTime):
return self._cmp(other) < 0
return super().__lt__(other.date())

def __ge__(self, other: datetime.date) -> bool:
# Will default to the negative of its reflection
return NotImplemented

def __gt__(self, other: datetime.date) -> bool:
# Will default to the negative of its reflection
return NotImplemented

def _cmp(self, other: datetime.datetime, **kwargs: Any) -> int:
# Fix for pypy which compares using this method
# which would lead to infinite recursion if we didn't override
Expand Down
93 changes: 93 additions & 0 deletions tests/datetime/test_comparison.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import annotations

from datetime import datetime
from datetime import timedelta

import pytest
import pytz

from pytz import timezone

import pendulum

from tests.conftest import assert_datetime
Expand Down Expand Up @@ -195,6 +199,95 @@ def test_less_than_with_timezone_false():
assert not d1 < d3


@pytest.mark.parametrize(
"truth_fun",
(
lambda earlier, later: earlier < later,
lambda earlier, later: earlier <= later,
lambda earlier, later: later > earlier,
lambda earlier, later: later >= earlier,
),
)
def test_comparison_crossing_dst_transitioning_off_pendulum_pendulum(truth_fun):
# We only need to test turning off DST, since that's when the time
# component goes backwards.
# We start with 2019-11-03T01:30:00-0700
earlier = pendulum.datetime(2019, 11, 3, 8, 30).in_tz("US/Pacific")
# Adding 55 minutes to it, we turn off DST, but the time component is
# slightly less than before, i.e. we get 2019-11-03T01:25:00-0800
later = earlier.add(minutes=55)
# Run through all inequality-comparison functions
assert truth_fun(earlier, later)


@pytest.mark.parametrize(
"truth_fun",
(
lambda earlier, later: earlier < later,
lambda earlier, later: earlier <= later,
lambda earlier, later: later > earlier,
lambda earlier, later: later >= earlier,
),
)
def test_comparison_crossing_dst_transitioning_off_pendulum_datetime(truth_fun):
# We only need to test turning off DST, since that's when the time
# component goes backwards.
# We start with 2019-11-03T01:30:00-0700
earlier_pendulum = pendulum.datetime(2019, 11, 3, 8, 30).in_tz("US/Pacific")
us_pacific = timezone("US/Pacific")
earlier_datetime = datetime(2019, 11, 3, 1, 30, tzinfo=us_pacific)
# Adding 55 minutes to it, we turn off DST, but the time component is
# slightly less than before, i.e. we get 2019-11-03T01:25:00-0800
later_datetime = earlier_datetime + timedelta(minutes=55)
# Run through all inequality-comparison functions
assert truth_fun(earlier_pendulum, later_datetime)


@pytest.mark.parametrize(
"truth_fun",
(
lambda earlier, later: earlier < later,
lambda earlier, later: earlier <= later,
lambda earlier, later: later > earlier,
lambda earlier, later: later >= earlier,
),
)
def test_comparison_crossing_dst_transitioning_off_datetime_pendulum(truth_fun):
# We only need to test turning off DST, since that's when the time
# component goes backwards.
# We start with 2019-11-03T01:30:00-0700
earlier_pendulum = pendulum.datetime(2019, 11, 3, 8, 30).in_tz("US/Pacific")
us_pacific = timezone("US/Pacific")
earlier_datetime = datetime(2019, 11, 3, 1, 30, tzinfo=us_pacific)
# Adding 55 minutes to it, we turn off DST, but the time component is
# slightly less than before, i.e. we get 2019-11-03T01:25:00-0800
later_pendulum = earlier_pendulum.add(minutes=55)
# Run through all inequality-comparison functions
assert truth_fun(earlier_datetime, later_pendulum)


@pytest.mark.parametrize(
"truth_fun",
(
lambda earlier, later: earlier < later,
lambda earlier, later: earlier <= later,
lambda earlier, later: later > earlier,
lambda earlier, later: later >= earlier,
),
)
def test_comparison_crossing_dst_transitioning_off_datetime_datetime(truth_fun):
# We only need to test turning off DST, since that's when the time
# component goes backwards.
# We start with 2019-11-03T01:30:00-0700
us_pacific = timezone("US/Pacific")
earlier = datetime(2019, 11, 3, 1, 30, tzinfo=us_pacific)
# Adding 55 minutes to it, we turn off DST, but the time component is
# slightly less than before, i.e. we get 2019-11-03T01:25:00-0800
later = earlier + timedelta(minutes=55)
# Run through all inequality-comparison functions
assert truth_fun(earlier, later)


def test_less_than_or_equal_true():
d1 = pendulum.datetime(2000, 1, 1)
d2 = pendulum.datetime(2000, 1, 2)
Expand Down