[m-rev.] for review: rename two calendar functions

Julien Fischer jfischer at opturion.com
Fri Apr 10 16:15:08 AEST 2026


For review by anyone.

---------------------------------

Rename two calendar functions.

Mark the existing names as obsolete.

library/calendar.m:
     Rename the function duration/2, which shares its name with the duration
     type, to duration_between/2. Add a forwarding function using the old name
     and mark it as obsolete.

     Rename the function day_duration/2 to fixed_duration_between/2. Extend
     its documentation.  Add a forwarding function using the old name and
     mark it as obsolete.

tests/hard_coded/calendar_test.m:
     Replace calls to obsolete predicates and functions.

NEWS.md:
     Announce the above changes.

Julien.

diff --git a/NEWS.md b/NEWS.md
index d70465ef1..7803a8531 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -246,6 +246,11 @@ Changes to the Mercury standard library
     - func `det_date_from_string/1` (replacement:
`det_date_time_from_string/1`)
     - func `date_to_string/1`       (replacement: `date_time_to_string/1`)

+* The following functions have been marked obsolete:
+
+    - func `duration/2`             (replacement: `duration_between/2`)
+    - func `day_duration/2`         (replacement: `fixed_duration_between/2`)
+
 * The following functions and predicates have been added:

     - pred `init_date_time/8`
@@ -256,6 +261,8 @@ Changes to the Mercury standard library
     - func `date_time_to_string/1`
     - func `days_in_month/2`
     - pred `is_leap_year/1`
+    - func `duration_between/2`
+    - func `fixed_duration_between/2`

 ### Changes to the `char` module

diff --git a/library/calendar.m b/library/calendar.m
index 496f8677a..86705d64a 100644
--- a/library/calendar.m
+++ b/library/calendar.m
@@ -529,7 +529,7 @@
     %
 :- pred local_time_offset(duration::out, io::di, io::uo) is det.

-    % duration(DateTimeA, DateTimeB) = Duration:
+    % duration_between(DateTimeA, DateTimeB) = Duration:
     %
     % Return the duration from DateTimeA to DateTimeB using a greedy algorithm
     % that maximises each component in this order: years, months, days, hours,
@@ -541,18 +541,32 @@
     % to find the duration between dates in different timezones or daylight
     % savings phases, first convert them both to UTC.
     %
-    % Note that due to month-end clamping, duration/2 is not always the
+    % Note that due to month-end clamping, duration_between/2 is not always the
     % inverse of add_duration/3. For example, the duration from 2001-01-31
     % to 2001-02-28 is 1 month, but adding -1 month to 2001-02-28 yields
     % 2001-01-28, not 2001-01-31.
     %
+:- func duration_between(date_time, date_time) = duration.
+
 :- func duration(date_time, date_time) = duration.
+:- pragma obsolete(func(duration/2), [duration_between/2]).

-    % As for duration/2, but the year and month components of the returned
-    % duration are always zero; the result is expressed in days, hours,
-    % minutes, seconds and microseconds only.
+    % fixed_duration_between(DateTimeA, DateTimeB) = Duration:
+    %
+    % Return the duration from DateTimeA to DateTimeB, expressed using only
+    % fixed-length units: days, hours, minutes, seconds and microseconds.
+    % The years and months components of the returned duration are always
+    % zero. The result is positive if DateTimeB is after DateTimeA and
+    % negative if DateTimeB is before DateTimeA. Leap seconds are ignored.
     %
+    % The dates should be in the same timezone and daylight savings phase;
+    % to find the duration between dates in different timezones or daylight
+    % savings phases, first convert them both to UTC.
+    %
+:- func fixed_duration_between(date_time, date_time) = duration.
+
 :- func day_duration(date_time, date_time) = duration.
+:- pragma obsolete(func(day_duration/2), [fixed_duration_between/2]).

 %---------------------------------------------------------------------------%
 %
@@ -1251,14 +1265,14 @@ local_time_offset(TZ, !IO) :-
     GMTM = time.gmtime(TimeT),
     LocalTime = tm_to_date(LocalTM),
     GMTime = tm_to_date(GMTM),
-    TZ = duration(GMTime, LocalTime).
+    TZ = duration_between(GMTime, LocalTime).

 %---------------------------------------------------------------------------%
 %
 % Computing the duration between two dates.
 %

-duration(DateA, DateB) = Duration :-
+duration_between(DateA, DateB) = Duration :-
     compare(CompResult, DateB, DateA),
     (
         CompResult = (<),
@@ -1272,6 +1286,8 @@ duration(DateA, DateB) = Duration :-
         greedy_subtract_descending(descending, DateB, DateA, Duration)
     ).

+duration(DateA, DateB) = duration_between(DateA, DateB).
+
 :- type order
     --->    ascending
     ;       descending.
@@ -1355,23 +1371,25 @@ subtract_ints_with_borrow(BorrowVal, Val1,
Val2, Diff, Borrow) :-
         Diff = BorrowVal + Val1 - Val2
     ).

-day_duration(DateA, DateB) = Duration :-
+fixed_duration_between(DateA, DateB) = Duration :-
     builtin.compare(CompResult, DateB, DateA),
     (
         CompResult = (<),
-        Duration0 = do_day_duration(DateB, DateA),
+        Duration0 = do_fixed_duration_between(DateB, DateA),
         Duration = negate(Duration0)
     ;
         CompResult = (=),
         Duration = zero_duration
     ;
         CompResult = (>),
-        Duration = do_day_duration(DateA, DateB)
+        Duration = do_fixed_duration_between(DateA, DateB)
     ).

-:- func do_day_duration(date, date) = duration.
+day_duration(DateA, DateB) = fixed_duration_between(DateA, DateB).
+
+:- func do_fixed_duration_between(date, date) = duration.

-do_day_duration(DateA, DateB) = Duration :-
+do_fixed_duration_between(DateA, DateB) = Duration :-
     some [!Borrow] (
         MicroSecond1 = DateB ^ dt_microsecond,
         MicroSecond2 = DateA ^ dt_microsecond,
diff --git a/tests/hard_coded/calendar_test.m b/tests/hard_coded/calendar_test.m
index 6c48ea44f..68bfc4065 100644
--- a/tests/hard_coded/calendar_test.m
+++ b/tests/hard_coded/calendar_test.m
@@ -122,10 +122,10 @@ test_dur_leq(Str1, Str2, !IO) :-
 :- pred test_add_dur(string::in, string::in, io::di, io::uo) is det.

 test_add_dur(Date0Str, DurStr, !IO) :-
-    Date0 = det_date_from_string(Date0Str),
+    Date0 = det_date_time_from_string(Date0Str),
     Dur = det_duration_from_string(DurStr),
     add_duration(Dur, Date0, Date),
-    DateStr = date_to_string(Date),
+    DateStr = date_time_to_string(Date),
     io.format("%s + %s = %s\n", [s(Date0Str), s(DurStr), s(DateStr)], !IO).

 :- pred test_diff(string::in, string::in, io::di, io::uo) is det.
@@ -144,39 +144,38 @@ test_diff(Date1, Date2, !IO) :-
 :- pred test_greedy_diff(string::in, string::in, io::di, io::uo) is det.

 test_greedy_diff(Date1Str, Date2Str, !IO) :-
-    Date1 = det_date_from_string(Date1Str),
-    Date2 = det_date_from_string(Date2Str),
-    duration(Date1, Date2) = Dur,
+    Date1 = det_date_time_from_string(Date1Str),
+    Date2 = det_date_time_from_string(Date2Str),
+    duration_between(Date1, Date2) = Dur,
     DurStr = duration_to_string(Dur),
     io.format("%s -> %s = %s", [s(Date1Str), s(Date2Str), s(DurStr)], !IO),
     add_duration(Dur, Date1, Date3),
     ( if Date2 = Date3 then
         io.write_string(" checked ok\n", !IO)
     else
-        io.write_string(" error: " ++ date_to_string(Date3) ++ "\n", !IO)
+        io.write_string(" error: " ++ date_time_to_string(Date3) ++ "\n", !IO)
     ).

 :- pred test_days_diff(string::in, string::in, io::di, io::uo) is det.

 test_days_diff(Date1Str, Date2Str, !IO) :-
-    Date1 = det_date_from_string(Date1Str),
-    Date2 = det_date_from_string(Date2Str),
-    Dur = day_duration(Date1, Date2),
+    Date1 = det_date_time_from_string(Date1Str),
+    Date2 = det_date_time_from_string(Date2Str),
+    Dur = fixed_duration_between(Date1, Date2),
     DurStr = duration_to_string(Dur),
     io.format("%s -> %s = %s", [s(Date1Str), s(Date2Str), s(DurStr)], !IO),
     add_duration(Dur, Date1, Date3),
     ( if Date2 = Date3 then
         io.write_string(" checked ok\n", !IO)
     else
-        io.write_string(" error: " ++ date_to_string(Date3) ++ "\n", !IO)
+        io.write_string(" error: " ++ date_time_to_string(Date3) ++ "\n", !IO)
     ).

 :- pred test_day_of_week(string::in, io::di, io::uo) is det.

 test_day_of_week(DateStr, !IO) :-
     io.write_string(DateStr ++ " : ", !IO),
-    io.write(day_of_week(det_date_from_string(DateStr)), !IO),
-    io.nl(!IO).
+    io.write_line(day_of_week(det_date_time_from_string(DateStr)), !IO).

 :- pred test_month_to_int(month::in, io::di, io::uo) is det.


More information about the reviews mailing list