[m-rev.] for review: rename date/0 to date_time/0

Julien Fischer jfischer at opturion.com
Fri Mar 27 19:45:23 AEDT 2026


For review by anyone.
--------------------------------

Rename date/0 to date_time/0.

The date/0 type is misnamed. Values of the type have both a date and a time
component. The common name for combined date and time values is a "date_time",
for which we have had a type synonym since 2014. This change makes date_time
the proper name for type and make date into the type synonym.

Deprecate the date/0 name and note that we will change its meaning in a future
release. (It will eventually be used for data values that do not have a time
component.)

Rename predicates and functions accordingly and mark the existing versions as
obsolete.

library/calendar.m:
    Make the above renamings.

library/hard_coded/stream.string_writer.m:
    Replace a call to a now obsolete function.

NEWS.md:
    Add entry describing the above.

tests/hard_coded/calendar_init_date.{m,exp}:
tests/hard_coded/calendar_test.m:
tests/hard_coded/fold_days.m:
tests/hard_coded/stream_string_writer_types.m:
     Conform to the above changes.

Julien.

diff --git a/NEWS.md b/NEWS.md
index 2e5f084be..372f4257f 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -226,6 +226,21 @@ Changes to the Mercury standard library

 ### Changes to the `calendar` module

+* The `date/0` type has been renamed to `date_time/0` and `date/0` is now
+  a type synonym for `date_time/0` rather than the other way around, as
+  previously.
+
+  The use of the name `date/0` is deprecated. Its meaning will be changed
+  in a future release. As a result of this, the following predicates and
+  functions are now obsolete:
+
+    - pred `init_date/8`            (replacement: `init_date_time/8`)
+    - func `det_init_date/7`        (replacement: `det_init_date_time/7`)
+    - pred `unpack_date/8`          (replacement: `unpack_date_time/8`)
+    - pred `date_from_string/2`     (replacement: `date_time_from_string/2`)
+    - 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 function and predicate have been added:

     - func `days_in_month/2`
diff --git a/library/calendar.m b/library/calendar.m
index ee6fba765..7c7549bc2 100644
--- a/library/calendar.m
+++ b/library/calendar.m
@@ -14,7 +14,7 @@
 % a representation of durations (differences between two points in time),
 % and operations on those representations.
 %
-% This module identifies points in time by a date specifying a day,
+% This module identifies points in time by a date_time specifying a day,
 % and a time within that day. It uses dates from the proleptic Gregorian
 % calendar, which is a version of the Gregorian calendar that has been
 % extended backward in time to dates before its introduction in 1582.
@@ -37,13 +37,15 @@

     % A point on the proleptic Gregorian calendar, to the nearest microsecond.
     %
-:- type date.
+:- type date_time.

-    % A more precisely descriptive name for the above.
+    % A deprecated name for date_time.
+    % In a future release, this name will be used for date values without
+    % a time component.
     %
-:- type date_time == date.
+:- type date == date_time.

-    % Date components.
+    % Date_time components.
     %
 :- type year == int.         % Year 0 is 1 BC, -1 is 2 BC, etc.
 :- type day_of_month == int. % 1 .. 31 depending on the month and year
@@ -77,16 +79,16 @@

 %---------------------%

-    % Functions to retrieve the components of a date.
+    % Functions to retrieve the components of a date_time.
     %
-:- func year(date) = year.
-:- func month(date) = month.
-:- func day_of_month(date) = day_of_month.
-:- func day_of_week(date) = day_of_week.
-:- func hour(date) = hour.
-:- func minute(date) = minute.
-:- func second(date) = second.
-:- func microsecond(date) = microsecond.
+:- func year(date_time) = year.
+:- func month(date_time) = month.
+:- func day_of_month(date_time) = day_of_month.
+:- func day_of_week(date_time) = day_of_week.
+:- func hour(date_time) = hour.
+:- func minute(date_time) = minute.
+:- func second(date_time) = second.
+:- func microsecond(date_time) = microsecond.

     % int_to_month(Int, Month):
     %
@@ -146,9 +148,10 @@

 %---------------------%

-    % init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond, Date):
+    % init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond,
+    %   DateTime):
     %
-    % Initialise a new date from the given components. Fails if any of the
+    % Initialise a new date_time from the given components. Fails if any of the
     % following conditions are not met:
     %
     %   - Day is in the range 1 .. N,
@@ -165,23 +168,37 @@
     %
     % This predicate accepts all values for Year.
     %
+:- pred init_date_time(year::in, month::in, day_of_month::in, hour::in,
+    minute::in, second::in, microsecond::in, date_time::out) is semidet.
+
+:- pragma obsolete(pred(init_date/8), [init_date_time/8]).
 :- pred init_date(year::in, month::in, day_of_month::in, hour::in,
-    minute::in, second::in, microsecond::in, date::out) is semidet.
+    minute::in, second::in, microsecond::in, date_time::out) is semidet.

     % As above, but throw an exception if the date is invalid.
     %
+:- func det_init_date_time(year, month, day_of_month, hour, minute, second,
+    microsecond) = date_time.
+
+:- pragma obsolete(func(det_init_date/7), [det_init_date_time/7]).
 :- func det_init_date(year, month, day_of_month, hour, minute, second,
-    microsecond) = date.
+    microsecond) = date_time.

     % Retrieve all the components of a date.
     %
-:- pred unpack_date(date::in,
+:- pred unpack_date_time(date_time::in,
+    year::out, month::out, day_of_month::out, hour::out, minute::out,
+    second::out, microsecond::out) is det.
+
+:- pragma obsolete(pred(unpack_date/8), [unpack_date_time/8]).
+:- pred unpack_date(date_time::in,
     year::out, month::out, day_of_month::out, hour::out, minute::out,
     second::out, microsecond::out) is det.

 %---------------------%

-    % Convert a string of the form "[-]YYYY-MM-DD HH:MM:SS.mmmmmm" to a date.
+    % Convert a string of the form "[-]YYYY-MM-DD HH:MM:SS.mmmmmm" to a
+    % date_time.
     %
     % The year must have at least four digits. This requirement comes from
     % ISO standard 8601, and its main intention is to prevent repeats of
@@ -189,7 +206,7 @@
     % It also prevents possible confusion between the year part of the date,
     % and the month or the day parts.
     %
-    % Since some simulation programs may want to handle dates in the far
+    % Since some simulation programs may want to handle date_times in the far
     % future, the predicate accepts years with more than four digits.
     %
     % The microseconds component (.mmmmmm) is optional. If present,
@@ -198,57 +215,67 @@
     % This predicate fails if the string does not conform to the above format,
     % or if any date or time component is outside its valid range.
     %
-:- pred date_from_string(string::in, date::out) is semidet.
+:- pred date_time_from_string(string::in, date_time::out) is semidet.
+
+:- pragma obsolete(pred(date_from_string/2), [date_time_from_string/2]).
+:- pred date_from_string(string::in, date_time::out) is semidet.

     % As above, but throw an exception if the string is not a valid date.
     %
-:- func det_date_from_string(string) = date.
+:- func det_date_time_from_string(string) = date_time.
+
+:- pragma obsolete(func(det_date_from_string/1),
+    [det_date_time_from_string/1]).
+:- func det_date_from_string(string) = date_time.

-    % Convert a date to a string of the form "[-]YYYY-MM-DD HH:MM:SS.mmmmmm".
+    % Convert a date_time to a string of the form "[-]YYYY-MM-DD
HH:MM:SS.mmmmmm".
     % If the microseconds component of the date is zero, then omit the
     % ".mmmmmm" part.
     %
-:- func date_to_string(date) = string.
+:- func date_time_to_string(date_time) = string.
+
+:- pragma obsolete(func(date_to_string/1), [date_time_to_string/1]).
+:- func date_to_string(date_time) = string.

 %---------------------%

     % current_local_time(Now, !IO):
     %
-    % Return the current local time as a date. The microseconds component
-    % of the returned date is always zero, as the underlying system call
-    % has only second-level resolution. The timezone used is the system
-    % local timezone.
+    % Return the current local time as a date_time. The microseconds component
+    % of the returned date_time is always zero, as the underlying system call
+    % has only second-level resolution. The timezone used is the system local
+    % timezone.
     %
-:- pred current_local_time(date::out, io::di, io::uo) is det.
+:- pred current_local_time(date_time::out, io::di, io::uo) is det.

     % current_utc_time(Now, !IO):
     %
-    % Return the current UTC time as a date. The microseconds component
-    % of the returned date is always zero, as the underlying system call
-    % has only second-level resolution.
+    % Return the current UTC time as a date_time. The microseconds component of
+    % the returned date_time is always zero, as the underlying system call has
+    % only second-level resolution.
     %
-:- pred current_utc_time(date::out, io::di, io::uo) is det.
+:- pred current_utc_time(date_time::out, io::di, io::uo) is det.

-    % julian_day_number(Date) = JDN:
+    % julian_day_number(DateTime) = JDN:
     %
-    % Return the Julian day number for Date on the proleptic Gregorian
+    % Return the Julian day number for DateTime on the proleptic Gregorian
     % calendar. The Julian day number is the integer number of days since
     % the start of the Julian period (noon on 1 January, 4713 BC in the
-    % proleptic Julian calendar). The time-of-day components of Date are
+    % proleptic Julian calendar). The time-of-day components of DateTime are
     % ignored; the result is the Julian day number for the date at noon.
     %
-:- func julian_day_number(date) = int.
+:- func julian_day_number(date_time) = int.

     % Return the Unix epoch, 1970-01-01 00:00:00.
     %
-:- func unix_epoch = date.
+:- func unix_epoch = date_time.

     % same_date(A, B):
     %
     % Succeed if-and-only-if A and B refer to the exact same day.
     % Their time components are ignored.
     %
-:- pred same_date(date::in, date::in) is semidet.
+:- pred same_date(date_time::in, date_time::in) is semidet.

 %---------------------------------------------------------------------------%
 %
@@ -447,14 +474,14 @@

 %---------------------%

-    % add_duration(Duration, Date0, Date):
+    % add_duration(Duration, DateTime0, DateTime):
     %
-    % Add Duration to Date0 to yield Date, clamping the day to the end of the
-    % month if the month or year component of the duration causes it to fall
-    % out of range.
+    % Add Duration to DateTime0 to yield DateTime, clamping the day to the end
+    % of the month if the month or year component of the duration causes it to
+    % fall out of range.
     % (See the documentation of the type duration/0 for the clamping rules.)
     %
-:- pred add_duration(duration::in, date::in, date::out) is det.
+:- pred add_duration(duration::in, date_time::in, date_time::out) is det.

     % duration_leq(DurationA, DurationB):
     %
@@ -495,12 +522,13 @@
     %
 :- pred local_time_offset(duration::out, io::di, io::uo) is det.

-    % duration(DateA, DateB) = Duration:
+    % duration(DateTimeA, DateTimeB) = Duration:
     %
-    % Return the duration from DateA to DateB using a greedy algorithm that
-    % maximises each component in this order: years, months, days, hours,
-    % minutes, seconds, microseconds. The result is positive if DateB is after
-    % DateA and negative if DateB is before DateA. Leap seconds are ignored.
+    % Return the duration from DateTimeA to DateTimeB using a greedy algorithm
+    % that maximises each component in this order: years, months, days, hours,
+    % minutes, seconds, microseconds. 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
@@ -511,26 +539,26 @@
     % 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(date, date) = duration.
+:- func duration(date_time, date_time) = duration.

     % 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.
     %
-:- func day_duration(date, date) = duration.
+:- func day_duration(date_time, date_time) = duration.

 %---------------------------------------------------------------------------%
 %
-% Folds over ranges of dates.
+% Folds over ranges of date_times.
 %

     % foldl_days(Pred, Start, End, !Acc):
     %
-    % Call Pred for each date in the range Start to End (inclusive), passing an
-    % accumulator. Each date in the range is generated by adding a duration of
-    % one day to the previous date using add_duration/3.
+    % Call Pred for each date_time in the range Start to End (inclusive),
+    % passing an accumulator. Each date_time in the range is generated by
+    % adding a duration of one day to the previous date using add_duration/3.
     %
-:- pred foldl_days(pred(date, A, A), date, date, A, A).
+:- pred foldl_days(pred(date_time, A, A), date_time, date_time, A, A).
 :- mode foldl_days(in(pred(in, in, out) is det),
     in, in, in, out) is det.
 :- mode foldl_days(in(pred(in, mdi, muo) is det),
@@ -548,7 +576,8 @@
     %
     % As above, but with two accumulators.
     %
-:- pred foldl2_days(pred(date, A, A, B, B), date, date, A, A, B, B).
+:- pred foldl2_days(pred(date_time, A, A, B, B), date_time, date_time,
+    A, A, B, B).
 :- mode foldl2_days(in(pred(in, in, out, in, out) is det),
     in, in, in, out, in, out) is det.
 :- mode foldl2_days(in(pred(in, in, out, mdi, muo) is det),
@@ -566,7 +595,7 @@
     %
     % As above, but with three accumulators.
     %
-:- pred foldl3_days(pred(date, A, A, B, B, C, C), date, date,
+:- pred foldl3_days(pred(date_time, A, A, B, B, C, C), date_time, date_time,
     A, A, B, B, C, C).
 :- mode foldl3_days(in(pred(in, in, out, in, out, in, out) is det),
     in, in, in, out, in, out, in, out) is det.
@@ -595,8 +624,8 @@

 %---------------------------------------------------------------------------%

-:- type date
-    --->    date(
+:- type date_time
+    --->    date_time(
                 dt_year             :: int,
                 dt_month            :: int,
                 dt_day              :: int,
@@ -729,7 +758,8 @@ is_leap_year(Year) :-

 %---------------------------------------------------------------------------%

-init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond, Date) :-
+init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond,
+        DateTime) :-
     Day >= 1,
     Day =< days_in_month(Year, Month),
     Hour >= 0,
@@ -740,28 +770,44 @@ init_date(Year, Month, Day, Hour, Minute,
Second, MicroSecond, Date) :-
     Second < 62,
     MicroSecond >= 0,
     MicroSecond < 1000000,
-    Date = date(Year, month_to_int(Month), Day, Hour, Minute, Second,
+    DateTime = date_time(Year, month_to_int(Month), Day, Hour, Minute, Second,
         MicroSecond).

-det_init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond)
-        = Date :-
+init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond, DateTime) :-
+    init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond,
+        DateTime).
+
+det_init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond)
+        = DateTime :-
     ( if
-        init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond, Date0)
+        init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond,
+            DateTime0)
     then
-        Date = Date0
+        DateTime = DateTime0
     else
-        Msg = string.format("invalid date: %i-%i-%i %i:%i:%i",
+        Msg = string.format("invalid date_time: %i-%i-%i %i:%i:%i",
             [i(Year), i(month_to_int(Month)), i(Day), i(Hour),
             i(Minute), i(Second)]),
         unexpected($pred, Msg)
     ).

-unpack_date(date(Year, Month, Day, Hour, Minute, Second, MicroSecond),
-    Year, det_int_to_month(Month), Day, Hour, Minute, Second, MicroSecond).
+det_init_date(Year, Month, Day, Hour, Minute, Second, MicroSecond) =
+    det_init_date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond).
+
+unpack_date_time(DateTime, Year, Month, Day, Hour, Minute, Second,
+        MicroSecond) :-
+    DateTime = date_time(Year, IntMonth, Day, Hour, Minute, Second,
+        MicroSecond),
+    Month = det_int_to_month(IntMonth).
+
+unpack_date(DateTime, Year, Month, Day, Hour, Minute, Second,
+        MicroSecond) :-
+    unpack_date_time(DateTime, Year, Month, Day, Hour, Minute, Second,
+        MicroSecond).

 %---------------------------------------------------------------------------%

-date_from_string(Str, Date) :-
+date_time_from_string(Str, Date) :-
     some [!Chars] (
         !:Chars = string.to_char_list(Str),
         ( if read_char((-), !.Chars, Rest1) then
@@ -793,18 +839,24 @@ date_from_string(Str, Date) :-
         Second < 62,
         read_microseconds(MicroSecond, !Chars),
         !.Chars = [],
-        Date = date(Year, Month, Day, Hour, Minute, Second, MicroSecond)
+        Date = date_time(Year, Month, Day, Hour, Minute, Second, MicroSecond)
     ).

-det_date_from_string(Str) = Date :-
-    ( if date_from_string(Str, Date0) then
-        Date = Date0
+date_from_string(Str, Date) :-
+    date_time_from_string(Str, Date).
+
+det_date_time_from_string(Str) = DateTime :-
+    ( if date_time_from_string(Str, DateTime0) then
+        DateTime = DateTime0
     else
-        unexpected($pred, "invalid date: " ++ Str)
+        unexpected($pred, "invalid date_time: " ++ Str)
     ).

-date_to_string(Date) = Str :-
-    unpack_date(Date, Year0, Month, Day, Hour, Minute, Second, MicroSecond),
+det_date_from_string(Str) = det_date_time_from_string(Str).
+
+date_time_to_string(DateTime) = Str :-
+    unpack_date_time(DateTime, Year0, Month, Day, Hour, Minute, Second,
+        MicroSecond),
     ( if Year0 < 0 then
         SignStr = "-",
         Year = -Year0
@@ -817,6 +869,8 @@ date_to_string(Date) = Str :-
         [s(SignStr), i(Year), i(month_to_int(Month)), i(Day),
         i(Hour), i(Minute), i(Second), s(MicroSecondStr)]).

+date_to_string(DateTime) = date_time_to_string(DateTime).
+
 %---------------------------------------------------------------------------%

 current_local_time(Now, !IO) :-
@@ -839,9 +893,9 @@ tm_to_date(TM) = Date :-
     Hour = TMHour,
     Minute = TMMinute,
     Second = TMSecond,
-    Date = date(Year, Month, Day, Hour, Minute, Second, 0).
+    Date = date_time(Year, Month, Day, Hour, Minute, Second, 0).

-julian_day_number(date(Year, Month, Day, _, _, _, _)) = JDN :-
+julian_day_number(date_time(Year, Month, Day, _, _, _, _)) = JDN :-
     % The algorithm is described at
     % https://en.wikipedia.org/wiki/Julian_day.
     A = (14 - Month) div 12,
@@ -850,11 +904,11 @@ julian_day_number(date(Year, Month, Day, _, _,
_, _)) = JDN :-
     JDN = Day + ( 153 * M + 2 ) div 5 + 365 * Y + Y div 4 - Y div 100 +
         Y div 400 - 32045.

-unix_epoch = date(1970, 1, 1, 0, 0, 0, 0).
+unix_epoch = date_time(1970, 1, 1, 0, 0, 0, 0).

 same_date(A, B) :-
-    A = date(Year, Month, Day, _, _, _, _),
-    B = date(Year, Month, Day, _, _, _, _).
+    A = date_time(Year, Month, Day, _, _, _, _),
+    B = date_time(Year, Month, Day, _, _, _, _).

 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -1087,7 +1141,7 @@ add_duration(D, S, !:E) :-
             TempDays = S ^ dt_day
         ),
         EDay = TempDays + D ^ dur_days + !.Carry,
-        !:E = date(EYear, EMonth, EDay, EHour, EMinute, ESecond, EMicrosecond),
+        !:E = date_time(EYear, EMonth, EDay, EHour, EMinute, ESecond,
EMicrosecond),
         add_duration_loop(D, S, !E)
     ).

@@ -1177,10 +1231,10 @@ duration_leq(DurA, DurB) :-
 :- func test_dates = list(date).

 test_dates = [
-    date(1696, 9, 1, 0, 0, 0, 0),
-    date(1697, 2, 1, 0, 0, 0, 0),
-    date(1903, 3, 1, 0, 0, 0, 0),
-    date(1903, 7, 1, 0, 0, 0, 0)
+    date_time(1696, 9, 1, 0, 0, 0, 0),
+    date_time(1697, 2, 1, 0, 0, 0, 0),
+    date_time(1903, 3, 1, 0, 0, 0, 0),
+    date_time(1903, 7, 1, 0, 0, 0, 0)
 ].

 local_time_offset(TZ, !IO) :-
diff --git a/library/stream.string_writer.m b/library/stream.string_writer.m
index 3b431a8c7..6caf7da7b 100644
--- a/library/stream.string_writer.m
+++ b/library/stream.string_writer.m
@@ -622,7 +622,7 @@ print(Stream, NonCanon, Term, !State) :-
         ;
             TypeCtorModuleName = "calendar",
             ( if dynamic_cast(Term, DateTime) then
-                put(Stream, date_to_string(DateTime), !State)
+                put(Stream, date_time_to_string(DateTime), !State)
             else if dynamic_cast(Term, Duration) then
                 put(Stream, duration_to_string(Duration), !State)
             else
diff --git a/tests/hard_coded/calendar_init_date.exp
b/tests/hard_coded/calendar_init_date.exp
index 3981fbf4b..044670eeb 100644
--- a/tests/hard_coded/calendar_init_date.exp
+++ b/tests/hard_coded/calendar_init_date.exp
@@ -1,34 +1,34 @@
-PASS: valid date (ordinary date)
-PASS: valid date (minimum components)
-PASS: valid date (max hour)
-PASS: valid date (max minute)
-PASS: valid date (max second)
-PASS: valid date (leap second)
-PASS: valid date (max microsecond)
-PASS: valid date (jan 31)
-PASS: valid date (feb 28 non-leap)
-PASS: valid date (feb 29 leap)
-PASS: valid date (mar 31)
-PASS: valid date (apr 30)
-PASS: valid date (dec 31)
-PASS: valid date (feb 28 century)
-PASS: valid date (feb 29 400-year)
-PASS: valid date (negative year)
-PASS: valid date (year zero)
-PASS: valid date (far future)
-PASS: init_date/8 failed for invalid date (day zero)
-PASS: init_date/8 failed for invalid date (day 32 in january)
-PASS: init_date/8 failed for invalid date (feb 29 non-leap)
-PASS: init_date/8 failed for invalid date (feb 29 century)
-PASS: init_date/8 failed for invalid date (apr 31)
-PASS: init_date/8 failed for invalid date (negative hour)
-PASS: init_date/8 failed for invalid date (hour 24)
-PASS: init_date/8 failed for invalid date (negative minute)
-PASS: init_date/8 failed for invalid date (minute 60)
-PASS: init_date/8 failed for invalid date (negative second)
-PASS: init_date/8 failed for invalid date (second 62)
-PASS: init_date/8 failed for invalid date (negative microsecond)
-PASS: init_date/8 failed for invalid date (microsecond 1000000)
-PASS: det_init_date threw exception for (det: day 32)
-PASS: det_init_date threw exception for (det: hour 24)
-PASS: det_init_date threw exception for (det: minute 60)
+PASS: valid date_time (ordinary date)
+PASS: valid date_time (minimum components)
+PASS: valid date_time (max hour)
+PASS: valid date_time (max minute)
+PASS: valid date_time (max second)
+PASS: valid date_time (leap second)
+PASS: valid date_time (max microsecond)
+PASS: valid date_time (jan 31)
+PASS: valid date_time (feb 28 non-leap)
+PASS: valid date_time (feb 29 leap)
+PASS: valid date_time (mar 31)
+PASS: valid date_time (apr 30)
+PASS: valid date_time (dec 31)
+PASS: valid date_time (feb 28 century)
+PASS: valid date_time (feb 29 400-year)
+PASS: valid date_time (negative year)
+PASS: valid date_time (year zero)
+PASS: valid date_time (far future)
+PASS: init_date_time/8 failed for invalid date_time (day zero)
+PASS: init_date_time/8 failed for invalid date_time (day 32 in january)
+PASS: init_date_time/8 failed for invalid date_time (feb 29 non-leap)
+PASS: init_date_time/8 failed for invalid date_time (feb 29 century)
+PASS: init_date_time/8 failed for invalid date_time (apr 31)
+PASS: init_date_time/8 failed for invalid date_time (negative hour)
+PASS: init_date_time/8 failed for invalid date_time (hour 24)
+PASS: init_date_time/8 failed for invalid date_time (negative minute)
+PASS: init_date_time/8 failed for invalid date_time (minute 60)
+PASS: init_date_time/8 failed for invalid date_time (negative second)
+PASS: init_date_time/8 failed for invalid date_time (second 62)
+PASS: init_date_time/8 failed for invalid date_time (negative microsecond)
+PASS: init_date_time/8 failed for invalid date_time (microsecond 1000000)
+PASS: det_init_date_time threw exception for (det: day 32)
+PASS: det_init_date_time threw exception for (det: hour 24)
+PASS: det_init_date_time threw exception for (det: minute 60)
diff --git a/tests/hard_coded/calendar_init_date.m
b/tests/hard_coded/calendar_init_date.m
index fc93d6f72..d20c5cec9 100644
--- a/tests/hard_coded/calendar_init_date.m
+++ b/tests/hard_coded/calendar_init_date.m
@@ -1,7 +1,7 @@
 %---------------------------------------------------------------------------%
 % vim: ft=mercury ts=4 sw=4 et
 %---------------------------------------------------------------------------%
-% Test calendar.init_date/8 and calendar.det_init_date/7.
+% Test calendar.init_date_time/8 and calendar.det_init_date_time/7.
 %---------------------------------------------------------------------------%

 :- module calendar_init_date.
@@ -56,19 +56,20 @@ test_valid_dates(!IO) :-

 test_valid_case(TestDate, !IO) :-
     TestDate  = test_date(Desc, Y, M, D, H, Min, S, Us),
-    ( if init_date(Y, M, D, H, Min, S, Us, Date) then
-        % Round-trip: verify that components are preserved by unpack_date/8.
-        unpack_date(Date, Y2, M2, D2, H2, Min2, S2, Us2),
+    ( if init_date_time(Y, M, D, H, Min, S, Us, DateTime) then
+        % Round-trip: verify that components are preserved by
+        % unpack_date_time/8.
+        unpack_date_time(DateTime, Y2, M2, D2, H2, Min2, S2, Us2),
         ( if
             Y = Y2, M = M2, D = D2, H = H2, Min = Min2, S = S2, Us = Us2
         then
-            io.format("PASS: valid date (%s)\n", [s(Desc)], !IO)
+            io.format("PASS: valid date_time (%s)\n", [s(Desc)], !IO)
         else
-            io.format("FAIL: round-trip mismatch for valid date (%s)\n",
+            io.format("FAIL: round-trip mismatch for valid date_time (%s)\n",
                 [s(Desc)], !IO)
         )
     else
-        io.format("FAIL: init_date/8 failed for valid date (%s)\n",
+        io.format("FAIL: init_date_time/8 failed for valid date_time (%s)\n",
             [s(Desc)], !IO)
     ).

@@ -126,11 +127,11 @@ test_invalid_dates(!IO) :-

 test_invalid_case(TestDate, !IO) :-
     TestDate = test_date(Desc, Y, M, D, H, Min, S, Us),
-    ( if init_date(Y, M, D, H, Min, S, Us, _Date) then
-        io.format("FAIL: init_date/8 succeeded for invalid date (%s)\n",
+    ( if init_date_time(Y, M, D, H, Min, S, Us, _DateTime) then
+        io.format("FAIL: init_date_time/8 succeeded for invalid
date_time (%s)\n",
             [s(Desc)], !IO)
     else
-        io.format("PASS: init_date/8 failed for invalid date (%s)\n",
+        io.format("PASS: init_date_time/8 failed for invalid date_time (%s)\n",
             [s(Desc)], !IO)
     ).

@@ -163,7 +164,7 @@ invalid_dates = [

 %---------------------------------------------------------------------------%
 %
-% Test det_init_date/7.
+% Test det_init_date_time/7.
 %

 :- pred test_det_init_date(io::di, io::uo) is cc_multi.
@@ -176,13 +177,13 @@ test_det_init_date(!IO) :-
 test_det_exception_case(TestDate, !IO) :-
     TestDate = test_date(Desc, Y, M, D, H, Min, S, Us),
     ( try []
-        Date = det_init_date(Y, M, D, H, Min, S, Us)
+        DateTime = det_init_date_time(Y, M, D, H, Min, S, Us)
     then
-        use_date(Date, !IO),
-        io.format("FAIL: det_init_date did not throw for (%s)\n",
+        use_date_time(DateTime, !IO),
+        io.format("FAIL: det_init_date_time did not throw for (%s)\n",
             [s(Desc)], !IO)
     catch_any _ ->
-        io.format("PASS: det_init_date threw exception for (%s)\n",
+        io.format("PASS: det_init_date_time threw exception for (%s)\n",
             [s(Desc)], !IO)
     ).

@@ -194,10 +195,10 @@ exception_dates = [
     test_date("det: minute 60", 2024, january,  1, 0, 60, 0, 0)
 ].

-:- pragma no_inline(pred(use_date/3)).
-:- pred use_date(date::in, io::di, io::uo) is det.
+:- pragma no_inline(pred(use_date_time/3)).
+:- pred use_date_time(date_time::in, io::di, io::uo) is det.

-use_date(_, !IO).
+use_date_time(_, !IO).

 %---------------------------------------------------------------------------%
 :- end_module calendar_init_date.
diff --git a/tests/hard_coded/calendar_test.m b/tests/hard_coded/calendar_test.m
index a92d2b3e4..6c48ea44f 100644
--- a/tests/hard_coded/calendar_test.m
+++ b/tests/hard_coded/calendar_test.m
@@ -94,9 +94,9 @@ main(!IO) :-
     list.foldl(test_int0_to_month, -1..13, !IO),
     io.nl(!IO),
     io.write_string("Same date:\n", !IO),
-    Date1 = det_date_from_string("2014-12-04 12:53:00"),
-    Date2 = det_date_from_string("2014-12-04 12:54:00"),
-    Date3 = det_date_from_string("2014-12-05 12:53:00"),
+    Date1 = det_date_time_from_string("2014-12-04 12:53:00"),
+    Date2 = det_date_time_from_string("2014-12-04 12:54:00"),
+    Date3 = det_date_time_from_string("2014-12-05 12:53:00"),
     test_same_date(Date1, Date1, !IO),
     test_same_date(Date1, Date2, !IO),
     test_same_date(Date1, Date3, !IO),
@@ -210,12 +210,13 @@ test_int0_to_month(Int, !IO) :-
     ),
     io.format("%d -> %s\n", [i(Int), s(Result)], !IO).

-:- pred test_same_date(date::in, date::in, io::di, io::uo) is det.
+:- pred test_same_date(date_time::in, date_time::in, io::di, io::uo) is det.

 test_same_date(A, B, !IO) :-
     Result = ( if same_date(A, B) then "==" else "!=" ),
     io.format("%s %s %s\n",
-        [s(date_to_string(A)), s(Result), s(date_to_string(B))], !IO).
+        [s(date_time_to_string(A)), s(Result), s(date_time_to_string(B))],
+            !IO).

 :- func all_months = list(month).

diff --git a/tests/hard_coded/fold_days.m b/tests/hard_coded/fold_days.m
index a4866338d..4f3afa335 100644
--- a/tests/hard_coded/fold_days.m
+++ b/tests/hard_coded/fold_days.m
@@ -17,52 +17,52 @@

 main(!IO) :-
     % Test 1: 1900 was not a leap year.
-    Date1A = det_init_date(1900, february, 25, 0, 0, 0, 0),
-    Date1B = det_init_date(1900, march, 1, 0, 0, 0, 0),
+    Date1A = det_init_date_time(1900, february, 25, 0, 0, 0, 0),
+    Date1B = det_init_date_time(1900, march, 1, 0, 0, 0, 0),
     io.write_string("Test 1:\n", !IO),
-    foldl_days(write_date, Date1A, Date1B, !IO),
+    foldl_days(write_date_time, Date1A, Date1B, !IO),
     io.nl(!IO),

     % Test 2: 2000 was a leap year.
-    Date2A = det_init_date(2000, february, 25, 0, 0, 0, 0),
-    Date2B = det_init_date(2000, march, 1, 0, 0, 0, 0),
+    Date2A = det_init_date_time(2000, february, 25, 0, 0, 0, 0),
+    Date2B = det_init_date_time(2000, march, 1, 0, 0, 0, 0),
     io.write_string("Test 2:\n", !IO),
-    foldl_days(write_date, Date2A, Date2B, !IO),
+    foldl_days(write_date_time, Date2A, Date2B, !IO),
     io.nl(!IO),

     % Test 3: 1977 was not a leap year.
-    Date3A = det_init_date(1977, february, 25, 0, 0, 0, 0),
-    Date3B = det_init_date(1977, march, 1, 0, 0, 0, 0),
+    Date3A = det_init_date_time(1977, february, 25, 0, 0, 0, 0),
+    Date3B = det_init_date_time(1977, march, 1, 0, 0, 0, 0),
     io.write_string("Test 3:\n", !IO),
-    foldl_days(write_date, Date3A, Date3B, !IO),
+    foldl_days(write_date_time, Date3A, Date3B, !IO),
     io.nl(!IO),

     % Test 4: calendar dates of start and end are the same,
     % time of start is less than that of the end.
-    Date4A = det_init_date(1977, february, 17, 0, 0, 0, 0),
-    Date4B = det_init_date(1977, february, 17, 1, 0, 0, 0),
+    Date4A = det_init_date_time(1977, february, 17, 0, 0, 0, 0),
+    Date4B = det_init_date_time(1977, february, 17, 1, 0, 0, 0),
     io.write_string("Test 4:\n", !IO),
-    foldl_days(write_date, Date4A, Date4B, !IO),
+    foldl_days(write_date_time, Date4A, Date4B, !IO),
     io.nl(!IO),

     % Test 5: calendar dates of start and end are the same,
     % time of start is equal to that of the end.
-    Date5A = det_init_date(1977, february, 17, 0, 0, 0, 0),
-    Date5B = det_init_date(1977, february, 17, 0, 0, 0, 0),
+    Date5A = det_init_date_time(1977, february, 17, 0, 0, 0, 0),
+    Date5B = det_init_date_time(1977, february, 17, 0, 0, 0, 0),
     io.write_string("Test 5:\n", !IO),
-    foldl_days(write_date, Date5A, Date5B, !IO),
+    foldl_days(write_date_time, Date5A, Date5B, !IO),
     io.nl(!IO),

     % Test 6: calendar dates of start and end are the same,
     % time of the start is greater than that of the end.
-    Date6A = det_init_date(1977, february, 17, 1, 0, 0, 0),
-    Date6B = det_init_date(1977, february, 17, 0, 0, 0, 0),
+    Date6A = det_init_date_time(1977, february, 17, 1, 0, 0, 0),
+    Date6B = det_init_date_time(1977, february, 17, 0, 0, 0, 0),
     io.write_string("Test 6:\n", !IO),
-    foldl_days(write_date, Date6A, Date6B, !IO),
+    foldl_days(write_date_time, Date6A, Date6B, !IO),
     io.nl(!IO).

-:- pred write_date(date::in, io::di, io::uo) is det.
+:- pred write_date_time(date_time::in, io::di, io::uo) is det.

-write_date(Date, !IO) :-
-    Str = date_to_string(Date),
+write_date_time(DateTime, !IO) :-
+    Str = date_time_to_string(DateTime),
     io.write_string(Str ++ "\n", !IO).
diff --git a/tests/hard_coded/stream_string_writer_types.exp
b/tests/hard_coded/stream_string_writer_types.exp
index f46b01e27..bbf1d83e0 100644
--- a/tests/hard_coded/stream_string_writer_types.exp
+++ b/tests/hard_coded/stream_string_writer_types.exp
@@ -15,7 +15,7 @@ module builtin, name c_pointer, arity 0
 module bitmap, name bitmap, arity 0
 module integer, name integer, arity 0
 module univ, name univ, arity 0
-module calendar, name date, arity 0
+module calendar, name date_time, arity 0
 module calendar, name duration, arity 0
 module type_desc, name type_desc, arity 0
 module type_desc, name type_ctor_desc, arity 0
diff --git a/tests/hard_coded/stream_string_writer_types.m
b/tests/hard_coded/stream_string_writer_types.m
index e34f8af3b..a1c4a84bc 100644
--- a/tests/hard_coded/stream_string_writer_types.m
+++ b/tests/hard_coded/stream_string_writer_types.m
@@ -28,7 +28,7 @@ main(!IO) :-
     BitMap = bitmap.init(10, no),
     IntegerOne = integer.one,
     type_to_univ("xyzzy", Univ),
-    Date = det_init_date(2019, october, 31, 12, 0, 0, 0),
+    DateTime = det_init_date_time(2019, october, 31, 12, 0, 0, 0),
     Duration = init_duration(1, 2, 3, 4, 5, 6, 7),
     TypeDesc = type_of(1),
     TypeCtorDesc = type_ctor(TypeDesc),
@@ -54,7 +54,7 @@ main(!IO) :-
     write_type_ctor_of(BitMap, !IO),
     write_type_ctor_of(IntegerOne, !IO),
     write_type_ctor_of(Univ, !IO),
-    write_type_ctor_of(Date, !IO),
+    write_type_ctor_of(DateTime, !IO),
     write_type_ctor_of(Duration, !IO),
     write_type_ctor_of(TypeDesc, !IO),
     write_type_ctor_of(TypeCtorDesc, !IO),


More information about the reviews mailing list