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
8 changes: 4 additions & 4 deletions src/pendulum/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def closest(self, dt1: Time | time, dt2: Time | time) -> Self:
dt1 = self.__class__(dt1.hour, dt1.minute, dt1.second, dt1.microsecond)
dt2 = self.__class__(dt2.hour, dt2.minute, dt2.second, dt2.microsecond)

if self.diff(dt1).in_seconds() < self.diff(dt2).in_seconds():
if self.diff(dt1).total_seconds() < self.diff(dt2).total_seconds():
return dt1

return dt2
Expand All @@ -81,7 +81,7 @@ def farthest(self, dt1: Time | time, dt2: Time | time) -> Self:
dt1 = self.__class__(dt1.hour, dt1.minute, dt1.second, dt1.microsecond)
dt2 = self.__class__(dt2.hour, dt2.minute, dt2.second, dt2.microsecond)

if self.diff(dt1).in_seconds() > self.diff(dt2).in_seconds():
if self.diff(dt1).total_seconds() > self.diff(dt2).total_seconds():
return dt1

return dt2
Expand Down Expand Up @@ -226,11 +226,11 @@ def diff(self, dt: time | None = None, abs: bool = True) -> Duration:

us1 = (
self.hour * SECS_PER_HOUR + self.minute * SECS_PER_MIN + self.second
) * USECS_PER_SEC
) * USECS_PER_SEC + self.microsecond

us2 = (
dt.hour * SECS_PER_HOUR + dt.minute * SECS_PER_MIN + dt.second
) * USECS_PER_SEC
) * USECS_PER_SEC + dt.microsecond

klass = Duration
if abs:
Expand Down
50 changes: 50 additions & 0 deletions tests/time/test_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,56 @@ def test_farthest_with_equals():
assert t2 == farthest


def test_closest_with_microseconds():
instance = pendulum.time(12, 0, 0, 900000)
t1 = pendulum.time(12, 0, 0, 900000)
t2 = pendulum.time(12, 0, 1, 100000)

assert instance.closest(t1, t2) == t1
assert instance.closest(t2, t1) == t1


def test_closest_with_microseconds_across_a_second():
instance = pendulum.time(12, 0, 0, 900000)
t1 = pendulum.time(12, 0, 1)
t2 = pendulum.time(12, 0, 0)

assert instance.closest(t1, t2) == t1
assert instance.closest(t2, t1) == t1


def test_closest_with_microseconds_of_native_times():
instance = pendulum.time(12, 0, 0, 900000)
closest = instance.closest(time(12, 0, 0, 900000), time(12, 0, 1, 100000))

assert_time(closest, 12, 0, 0, 900000)


def test_farthest_with_microseconds():
instance = pendulum.time(12, 0, 0, 900000)
t1 = pendulum.time(12, 0, 0, 900000)
t2 = pendulum.time(12, 0, 1, 100000)

assert instance.farthest(t1, t2) == t2
assert instance.farthest(t2, t1) == t2


def test_farthest_with_microseconds_across_a_second():
instance = pendulum.time(12, 0, 0, 900000)
t1 = pendulum.time(12, 0, 1)
t2 = pendulum.time(12, 0, 0)

assert instance.farthest(t1, t2) == t2
assert instance.farthest(t2, t1) == t2


def test_farthest_with_microseconds_of_native_times():
instance = pendulum.time(12, 0, 0, 900000)
farthest = instance.farthest(time(12, 0, 1, 100000), time(12, 0, 0, 900000))

assert_time(farthest, 12, 0, 1, 100000)


def test_comparison_to_unsupported():
t1 = pendulum.now().time()

Expand Down
45 changes: 39 additions & 6 deletions tests/time/test_diff.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

from datetime import time

import pendulum

from pendulum import Time
Expand Down Expand Up @@ -96,6 +98,37 @@ def test_diff_in_seconds_ensure_is_truncated():
assert dt.diff(dt.add(seconds=1.9)).in_seconds() == 1


def test_diff_includes_microseconds():
dt = Time(12, 0, 0, 500000)
diff = dt.diff(Time(12, 0, 1))

assert diff.total_seconds() == 0.5
assert diff.microseconds == 500000
assert diff.in_seconds() == 0


def test_diff_includes_microseconds_negative_with_sign():
dt = Time(12, 0, 1)
diff = dt.diff(Time(12, 0, 0, 250000), False)

assert diff.total_seconds() == -0.75
assert diff.microseconds == -750000


def test_diff_includes_microseconds_within_the_same_second():
dt = Time(12, 0, 0, 1)
assert dt.diff(Time(12, 0, 0, 999999)).total_seconds() == 0.999998


def test_diff_includes_microseconds_of_native_time():
dt = Time(12, 0, 0)
assert dt.diff(time(12, 0, 0, 750000)).total_seconds() == 0.75


def test_diff_min_and_max():
assert Time.min.diff(Time.max).total_seconds() == 86399.999999


def test_diff_for_humans_now_and_second():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
now = pendulum.now().time()
Expand Down Expand Up @@ -167,42 +200,42 @@ def test_diff_for_humans_now_and_future_seconds():


def test_diff_for_humans_now_and_nearly_future_minute():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(seconds=59).diff_for_humans() == "in 59 seconds"


def test_diff_for_humans_now_and_future_minute():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(minutes=1).diff_for_humans() == "in 1 minute"


def test_diff_for_humans_now_and_future_minutes():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(minutes=2).diff_for_humans() == "in 2 minutes"


def test_diff_for_humans_now_and_nearly_future_hour():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(minutes=59).diff_for_humans() == "in 59 minutes"


def test_diff_for_humans_now_and_future_hour():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(hours=1).diff_for_humans() == "in 1 hour"


def test_diff_for_humans_now_and_future_hours():
with pendulum.travel_to(pendulum.today().at(12, 34, 56)):
with pendulum.travel_to(pendulum.today().at(12, 34, 56), freeze=True):
now = pendulum.now().time()

assert now.add(hours=2).diff_for_humans() == "in 2 hours"
Expand Down
22 changes: 22 additions & 0 deletions tests/time/test_sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,25 @@ def test_subtract_time():

with pytest.raises(TypeError):
t3 - t


def test_subtract_time_includes_microseconds():
t = Time(12, 0, 1)
t1 = Time(12, 0, 0, 500000)
t2 = time(12, 0, 0, 500000)

diff = t - t1
assert isinstance(diff, pendulum.Duration)
assert diff.total_seconds() == 0.5

diff = t1 - t
assert diff.total_seconds() == -0.5

diff = t - t2
assert diff.total_seconds() == 0.5

diff = t2 - t
assert diff.total_seconds() == -0.5

diff = Time(12, 0, 0, 999999) - t
assert diff.total_seconds() == -1e-06