[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