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

1 Answer

0 votes
program LastFridays;

{$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
  yr, mo: Integer;
  days: Int64;
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);

  Result := days mod 7;  { Monday = 0 }
end;

(*
    // Return the last Friday of a specific month
    // First day of next month
    // Last day of this month
    // Walk backward to Friday
*)
function LastFridayOfMonth(y: Integer; m: Integer): TDate;
var
  last, d, w: Integer;
  resultDate: TDate;
begin
  { Last day of this month }
  last := DaysInMonth(y, m);

  { Walk backward to Friday }
  for d := last downto 1 do
  begin
    w := WeekdayMonday0(y, m, d);

    { Friday = 4 }
    if w = 4 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 Fridays of each month in a given year
procedure ListOfLastFridaysOfEachMonthIn(year: Integer);
var
  m: Integer;
  d: TDate;
begin
  for m := 1 to 12 do
  begin
    d := LastFridayOfMonth(year, m);
    WriteLn(d.year, '-', d.month, '-', d.day);
  end;
end;

begin
  ListOfLastFridaysOfEachMonthIn(2026);
end.



(*
run:

2026-1-30
2026-2-27
2026-3-27
2026-4-24
2026-5-29
2026-6-26
2026-7-31
2026-8-28
2026-9-25
2026-10-30
2026-11-27
2026-12-25

*)

 



answered 10 hours ago by avibootz

Related questions

...