Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM public.ecr.aws/d3j8x8q7/olympus-base-python:latest

WORKDIR /app

# Copy repository into the image before installing
COPY . .

# Use pip to install in editable mode with test extras to avoid Poetry issues
RUN python -m pip install --upgrade pip
RUN python -m pip install -e ".[test]"

CMD ["/bin/bash"]
42 changes: 42 additions & 0 deletions src/pendulum/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,48 @@ def is_anniversary( # type: ignore[override]

return (self.month, self.day) == (instance.month, instance.day)

# Rich ordering operations
def __lt__(self, other: datetime.datetime) -> bool: # type: ignore[override]
if not isinstance(other, datetime.datetime):
return NotImplemented

# Normalize both operands to UTC stdlib datetimes using base implementation
self_utc = datetime.datetime.astimezone(self, UTC)
other_dt = other if isinstance(other, DateTime) else DateTime.instance(other)
other_utc = datetime.datetime.astimezone(other_dt, UTC)

return datetime.datetime.__lt__(self_utc, other_utc)

def __le__(self, other: datetime.datetime) -> bool: # type: ignore[override]
if not isinstance(other, datetime.datetime):
return NotImplemented

self_utc = datetime.datetime.astimezone(self, UTC)
other_dt = other if isinstance(other, DateTime) else DateTime.instance(other)
other_utc = datetime.datetime.astimezone(other_dt, UTC)

return datetime.datetime.__le__(self_utc, other_utc)

def __gt__(self, other: datetime.datetime) -> bool: # type: ignore[override]
if not isinstance(other, datetime.datetime):
return NotImplemented

self_utc = datetime.datetime.astimezone(self, UTC)
other_dt = other if isinstance(other, DateTime) else DateTime.instance(other)
other_utc = datetime.datetime.astimezone(other_dt, UTC)

return datetime.datetime.__gt__(self_utc, other_utc)

def __ge__(self, other: datetime.datetime) -> bool: # type: ignore[override]
if not isinstance(other, datetime.datetime):
return NotImplemented

self_utc = datetime.datetime.astimezone(self, UTC)
other_dt = other if isinstance(other, DateTime) else DateTime.instance(other)
other_utc = datetime.datetime.astimezone(other_dt, UTC)

return datetime.datetime.__ge__(self_utc, other_utc)

# ADDITIONS AND SUBSTRACTIONS

def add(
Expand Down
24 changes: 24 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh
set -eu

if [ "$#" -ne 1 ]; then
echo "Usage: $0 {base|new}"
exit 1
fi

case "$1" in
base)
# Run the comparison file but exclude the new regression test that
# doesn't exist in the base commit.
poetry run pytest -q tests/datetime/test_comparison.py -k "not less_than_with_fold"
;;
new)
# Run the full file including the new regression test.
poetry run pytest -q tests/datetime/test_comparison.py
;;
*)
echo "Usage: $0 {base|new}"
exit 1
;;
esac

32 changes: 32 additions & 0 deletions tests/datetime/test_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,35 @@ def test_comparison_to_unsupported():

assert dt1 != "test"
assert dt1 not in ["test"]


def test_less_than_with_fold():
d1 = pendulum.datetime(
2023,
11,
5,
1,
15,
tz="America/Los_Angeles",
fold=1,
)

d2 = pendulum.datetime(
2023,
11,
5,
1,
25,
tz="America/Los_Angeles",
fold=0,
)

assert d1.timestamp() > d2.timestamp()

# Verify rich ordering operators behave consistently when fold differs but
# the absolute instant (timestamp) shows d1 is later than d2.
assert not (d1 < d2)
assert d1 > d2
assert d2 < d1
assert d1 >= d2
assert not (d1 <= d2)