Skip to content

Commit 2aee507

Browse files
committed
feat: add comparison function for Duration
1 parent 170b797 commit 2aee507

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

lib/elixir/lib/calendar/duration.ex

+49
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,55 @@ defmodule Duration do
299299
}
300300
end
301301

302+
@doc """
303+
Compares two durations.
304+
305+
Returns `:eq` if the durations are equal, `:lt` if the first duration is less than the second, and `:gt` if the first
306+
duration is greater than the second.
307+
308+
## Examples
309+
310+
iex> Duration.compare(Duration.new!(second: 10), Duration.new!(second: 20))
311+
:lt
312+
iex> Duration.compare(Duration.new!(second: 20), Duration.new!(second: 10))
313+
:gt
314+
iex> Duration.compare(Duration.new!(second: 10), Duration.new!(second: 10))
315+
:eq
316+
"""
317+
@doc since: "1.19.0"
318+
@spec compare(t, t) :: :eq | :lt | :gt
319+
def compare(%Duration{} = d1, %Duration{} = d2) do
320+
d1_us = to_microseconds(d1)
321+
d2_us = to_microseconds(d2)
322+
323+
cond do
324+
d1_us == d2_us -> :eq
325+
d1_us < d2_us -> :lt
326+
d1_us > d2_us -> :gt
327+
end
328+
end
329+
330+
@second_in_us 1_000_000 # 1 second in microseconds
331+
@minute_in_us @second_in_us * 60 # 1 minute = 60 seconds
332+
@hour_in_us @minute_in_us * 60 # 1 hour = 60 minutes
333+
@day_in_us @hour_in_us * 24 # 1 day = 24 hours
334+
@week_in_us @day_in_us * 7 # 1 week = 7 days
335+
@month_in_us @day_in_us * 30 # 1 month = 30 days
336+
@year_in_us @day_in_us * 365 # 1 year = 365 days
337+
338+
def to_microseconds(duration) do
339+
{microsecond, _precision} = duration.microsecond
340+
341+
duration.year * @year_in_us +
342+
duration.month * @month_in_us +
343+
duration.week * @week_in_us +
344+
duration.day * @day_in_us +
345+
duration.hour * @hour_in_us +
346+
duration.minute * @minute_in_us +
347+
duration.second * @second_in_us +
348+
microsecond
349+
end
350+
302351
@doc """
303352
Parses an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) formatted duration string to a `Duration` struct.
304353

0 commit comments

Comments
 (0)