program DaysToCalendar;
// Calendar‑accurate (real month lengths)
type
TYMD = record
Years : Integer;
Months : Integer;
Days : Integer;
end;
const
MonthLen : array[1..12] of Integer =
(31,28,31,30,31,30,31,31,30,31,30,31);
function IsLeap(Y : Integer) : Boolean;
begin
IsLeap := (Y mod 4 = 0) and ((Y mod 100 <> 0) or (Y mod 400 = 0));
end;
function SplitDaysCalendar(TotalDays : LongInt) : TYMD;
var
Y, M, ML : Integer;
begin
Y := 1970;
M := 1;
{ subtract whole years }
while True do
begin
if IsLeap(Y) then ML := 366 else ML := 365;
if TotalDays < ML then Break;
Dec(TotalDays, ML);
Inc(Y);
end;
{ subtract whole months }
while True do
begin
ML := MonthLen[M];
if (M = 2) and IsLeap(Y) then Inc(ML); { February in leap year }
if TotalDays < ML then Break;
Dec(TotalDays, ML);
Inc(M);
if M > 12 then
begin
M := 1;
Inc(Y);
end;
end;
SplitDaysCalendar.Years := Y - 1970;
SplitDaysCalendar.Months := M - 1;
SplitDaysCalendar.Days := TotalDays;
end;
var
R : TYMD;
begin
R := SplitDaysCalendar(452);
WriteLn(R.Years, ' years, ', R.Months, ' months, ', R.Days, ' days');
end.
(*
run:
1 years, 2 months, 28 days
*)