{$mode objfpc}{$H-}{$R+}{$T+}{$Q+}{$V+}{$D+}{$X-}{$warnings on}
program fecha_valida_v04;

// Equivalente a la versión anterior, pero más clara porque
// ya no hay if then else anidados.

function anyo_ok(anyo: integer): boolean;
const
	MinAnyo = 1900;
	MaxAnyo = 2123;
begin
    if  (anyo >= MinAnyo) and (anyo <= MaxAnyo) then 
        result := True
    else
        result := False;   // Funciona, pero no tiene
                           // mucho sentido
   
end;

function mes_ok(mes: integer): boolean;
const
	Ene = 1;
	Dic = 12;
begin
	if  (mes >= Ene) and (mes <= Dic) then
        result := True
    else
        result := False;  // Funciona, pero...
  
end;

function es_bisiesto(anyo: integer): boolean;
begin
	if  (Anyo mod 4 = 0) and (Anyo mod 100 <> 0) or (Anyo mod 400 = 0) then
        result := True
    else
        result := False;  // Funciona, pero...
end;


function dias_en_mes(anyo, mes: integer): integer;
begin
    result := 30;  // valor por defecto. Si no se cumple ninguna
        // de las condiciones posteriores, esto será lo devuelto

    if (mes = 1) or (mes = 3) or (mes = 5) or (mes = 7) or (mes = 8)
       or (mes = 10) or (mes = 12) then
        result := 31;

    if (mes = 2) and es_bisiesto(anyo) then
        result := 29;

    if (mes = 2) and not es_bisiesto(anyo) then
        result := 28;
end;


function dia_ok(anyo, mes, dia: integer): boolean;
begin
	if (dia >= 1) and (dia <= dias_en_mes(anyo, mes)) then
	    result := True
    else
	    result := False;  // Funciona, pero...

end;

function fecha_ok(anyo, mes, dia: integer): boolean;
begin
	result := anyo_ok(anyo) and mes_ok(mes) and dia_ok(anyo, mes, dia);
end;

const
	Anyo = 2018;
	Mes = 11;
	Dia = 31;

begin
	writeln(fecha_ok(Anyo, Mes, Dia));
end.


