program LastSundays;
{$mode objfpc}{$H+}
uses
SysUtils;
(* Simple date structure *)
type
TDate = record
Year: Integer;
Month: Integer;
Day: Integer;
end;
(* Check if a year is leap year *)
function IsLeap(y: Integer): Boolean;
begin
if (y mod 400 = 0) then Exit(True);
if (y mod 100 = 0) then Exit(False);
Exit(y mod 4 = 0);
end;
(* Days in each month *)
function DaysInMonth(y, m: Integer): Integer;
const
mdays: array[1..12] of Integer =
(31,28,31,30,31,30,31,31,30,31,30,31);
begin
if (m = 2) and IsLeap(y) then
Exit(29)
else
Exit(mdays[m]);
end;
(*
Pure arithmetic weekday:
Returns:
0 = Monday
1 = Tuesday
2 = Wednesday
3 = Thursday
4 = Friday
5 = Saturday
6 = Sunday
Algorithm:
Count days since 0001‑01‑01 (which was a Monday).
*)
function WeekdayMonday0(y, m, d: Integer): Integer;
var
days, yr, mo: LongInt;
begin
days := 0;
(* Add days for all previous years *)
for yr := 1 to y - 1 do
if IsLeap(yr) then Inc(days, 366)
else Inc(days, 365);
(* Add days for previous months in this year *)
for mo := 1 to m - 1 do
Inc(days, DaysInMonth(y, mo));
(* Add days in this month *)
Inc(days, d - 1);
(* Monday = 0 *)
Result := days mod 7;
end;
(*
// Return the last Sunday of a specific month
*)
function LastSundayOfMonth(y: Integer; m: Integer): TDate;
var
last, d, w: Integer;
resultDate: TDate;
begin
last := DaysInMonth(y, m);
(* Walk backward to Sunday *)
for d := last downto 1 do
begin
w := WeekdayMonday0(y, m, d);
(* Sunday = 6 *)
if w = 6 then
begin
resultDate.Year := y;
resultDate.Month := m;
resultDate.Day := d;
Exit(resultDate);
end;
end;
(* Should never happen *)
resultDate.Year := y;
resultDate.Month := m;
resultDate.Day := 1;
Result := resultDate;
end;
(*
// Print all last Sundays of each month in a given year
*)
procedure ListOfLastSundaysOfEachMonthIn(year: Integer);
var
m: Integer;
d: TDate;
begin
for m := 1 to 12 do
begin
d := LastSundayOfMonth(year, m);
WriteLn(Format('%.2d/%.2d/%d', [d.Month, d.Day, d.Year]));
end;
end;
var
year: Integer;
begin
year := 2026;
if ParamCount > 0 then
year := StrToInt(ParamStr(1));
ListOfLastSundaysOfEachMonthIn(year);
end.
(*
run:
01/25/2026
02/22/2026
03/29/2026
04/26/2026
05/31/2026
06/28/2026
07/26/2026
08/30/2026
09/27/2026
10/25/2026
11/29/2026
12/27/2026
*)