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

Julien Fischer jfischer at opturion.com
Fri Apr 17 13:55:43 AEST 2026


Any takers to review this one?

Julien.

On Fri, 10 Apr 2026 at 16:15, Julien Fischer <jfischer at opturion.com> wrote:
>
> 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