How to find the dates of the last Sunday of each month of a given year in Pascal

1 Answer

0 votes
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

*)

 



answered 14 hours ago by avibootz
edited 11 hours ago by avibootz

Related questions

...