[m-rev.] diff: fix a bug in calendar.duration_between/2

Julien Fischer jfischer at opturion.com
Thu Jun 11 15:50:49 AEST 2026


Fix a bug in calendar.duration_between/2.

library/calendar.m:
     Fix a spot where we were accidentally subtracting one day from a
     date_time instead of one month.

tests/hard_coded/calendar_test.{m,exp}:
     Add some tests for duration_between/2 that exercise the branch
     where the bug occurs.

Julien.

diff --git a/library/calendar.m b/library/calendar.m
index d9b8d6548..762d3bdce 100644
--- a/library/calendar.m
+++ b/library/calendar.m
@@ -1326,7 +1326,7 @@ greedy_subtract_descending(OriginalOrder, DateA,
DateB, Duration) :-
         subtract_ints_with_borrow(24, HourA, HourB, Hours, !:Borrow),
         (
             OriginalOrder = descending,
-            add_duration(duration(0, -1, 0, 0), DateA, DateAMinus1Month),
+            add_duration(duration(-1, 0, 0, 0), DateA, DateAMinus1Month),
             DaysToBorrow = max_day_in_month_for(DateAMinus1Month ^ dt_year,
                 DateAMinus1Month ^ dt_month),
             DateAEndOfMonth = max_day_in_month_for(DateA ^ dt_year,
diff --git a/tests/hard_coded/calendar_test.exp
b/tests/hard_coded/calendar_test.exp
index 4419237d2..1dfda1725 100644
--- a/tests/hard_coded/calendar_test.exp
+++ b/tests/hard_coded/calendar_test.exp
@@ -89,6 +89,26 @@ G: 1980-03-01 13:01:01.000007 -> 1977-10-09
12:00:00 = -P2Y4M23DT1H1M1.000007S c
 D: 1977-10-09 12:00:00 -> 1980-03-01 13:01:01.000007 =
P874DT1H1M1.000007S checked ok
 D: 1980-03-01 13:01:01.000007 -> 1977-10-09 12:00:00 =
-P874DT1H1M1.000007S checked ok

+G: 2001-01-20 00:00:00 -> 2001-03-10 00:00:00 = P1M18D checked ok
+G: 2001-03-10 00:00:00 -> 2001-01-20 00:00:00 = -P1M21D checked ok
+D: 2001-01-20 00:00:00 -> 2001-03-10 00:00:00 = P49D checked ok
+D: 2001-03-10 00:00:00 -> 2001-01-20 00:00:00 = -P49D checked ok
+
+G: 2000-01-20 00:00:00 -> 2000-03-10 00:00:00 = P1M19D checked ok
+G: 2000-03-10 00:00:00 -> 2000-01-20 00:00:00 = -P1M21D checked ok
+D: 2000-01-20 00:00:00 -> 2000-03-10 00:00:00 = P50D checked ok
+D: 2000-03-10 00:00:00 -> 2000-01-20 00:00:00 = -P50D checked ok
+
+G: 2001-03-25 00:00:00 -> 2001-04-10 00:00:00 = P16D checked ok
+G: 2001-04-10 00:00:00 -> 2001-03-25 00:00:00 = -P16D checked ok
+D: 2001-03-25 00:00:00 -> 2001-04-10 00:00:00 = P16D checked ok
+D: 2001-04-10 00:00:00 -> 2001-03-25 00:00:00 = -P16D checked ok
+
+G: 2001-02-20 18:30:00 -> 2001-04-10 06:00:00 = P1M20DT11H30M checked ok
+G: 2001-04-10 06:00:00 -> 2001-02-20 18:30:00 = -P1M17DT11H30M checked ok
+D: 2001-02-20 18:30:00 -> 2001-04-10 06:00:00 = P48DT11H30M checked ok
+D: 2001-04-10 06:00:00 -> 2001-02-20 18:30:00 = -P48DT11H30M checked ok
+

 Day of the week:
 2008-01-15 23:59:00 : tuesday
diff --git a/tests/hard_coded/calendar_test.m b/tests/hard_coded/calendar_test.m
index 68bfc4065..a4b423d77 100644
--- a/tests/hard_coded/calendar_test.m
+++ b/tests/hard_coded/calendar_test.m
@@ -63,6 +63,10 @@ main(!IO) :-
     test_diff("1977-10-09 12:00:00", "1980-01-05 11:11:11", !IO),
     test_diff("1977-10-09 12:00:00", "1980-03-01 12:00:00", !IO),
     test_diff("1977-10-09 12:00:00", "1980-03-01 13:01:01.000007", !IO),
+    test_diff("2001-01-20 00:00:00", "2001-03-10 00:00:00", !IO),
+    test_diff("2000-01-20 00:00:00", "2000-03-10 00:00:00", !IO),
+    test_diff("2001-03-25 00:00:00", "2001-04-10 00:00:00", !IO),
+    test_diff("2001-02-20 18:30:00", "2001-04-10 06:00:00", !IO),
     io.nl(!IO),
     io.write_string("Day of the week:\n", !IO),
     test_day_of_week("2008-01-15 23:59:00", !IO),


More information about the reviews mailing list