#!/usr/bin/perl

use strict;
use warnings;
use Test::More qw(no_plan);
use DateTime;

my @MONTH = qw(0 3 3 6 1 4 6 2 5 0 3 5);
my %ADJ   = qw(1700 4 1800 2 1900 0 2000 6 
               2100 4 2200 2 2300 0);

my $dt = DateTime->new(
    year  => 1700,
    month => 1,
    day   => 1,
);

while(1) {
  my $calc = wday_mindcal(
         $dt->year, $dt->month, $dt->day);

  is($calc, $dt->wday() % 7, "$dt");

  $dt->add(days => 1);

  last if $dt->year() > 2399;
}

###########################################
sub wday_mindcal {
###########################################
    my($year, $month, $day) = @_;

    use integer;

    my $year2 = $year % 100;
    my $cent  = $year / 100;
    my $y     = ($year2 + ($year2 / 4)) % 7;

    my $m     = $MONTH[$month-1];
    my $d     = $day;

    my $adj   = $ADJ{$cent * 100};

    $adj-- if leap_year($year) and
              $month <= 2;

    return( ($y+$m+$d+$adj) % 7 );
}

###########################################
sub leap_year {
###########################################
    my($year) = @_;

    return 0 if $year % 4;
    return 1 if $year % 100;
    return 0 if $year % 400;
    return 1;
}
