class DoomsDay { static var _instance : DoomsDay; static function main () : Void { var args = neko.Sys.args(); neko.Lib.println( DoomsDay.weekdates( Std.parseInt( args.shift() ), Std.parseInt( args.shift() ), Std.parseInt( args.shift() ) ) ); } public static function weekdates ( year : Int, month : Int, weekday : Int ) : Array { var dd = new DoomsDay( year ); var dayOfFirst = dd.weekday( month, 1 ); var first = 1 + ((weekday - dayOfFirst + 7) % 7); var lim = dd.daysPerMonth[ month - 1 ]; var day = first; var result = new Array(); result.push( first ); while( (day += 7) <= lim ) { result.push( day ); } return result; } public static function dayOfWeek ( year : Int, month : Int, day : Int ) : Int { var dd = new DoomsDay( year ); return dd.weekday( month, day ); } public static function daysInMonth ( year : Int, month : Int ) : Int { return (new DoomsDay( year )).daysPerMonth[ month -1 ]; } static var anchorDays : Array = [ 1, 6, 4, 2 ]; var doomsday : Int; var doomsdayInMonth : Array; var daysPerMonth : Array; private function new ( year : Int ) { // anchor day var anchorDay = anchorDays[ Math.floor( year / 100 ) % 4 ]; // doomsday var centYear = year % 100; doomsday = ((Math.floor( centYear / 12 ) + (centYear % 12) + Math.floor( (centYear % 12) / 4 )) % 7 + anchorDay) % 7; // leap year? var leapYear : Bool; if( year % 4 == 0 ) { if( year % 100 == 0 ) { if( year % 400 == 0 ) { leapYear = true; } else { leapYear = false; } } else { leapYear = true; } } else { leapYear = false; } // doomsday in a given month if( leapYear ) { doomsdayInMonth = [ 3, 0, 6, 3, 1, 5, 3, 0, 4, 2, 6, 4, 1, 5 ]; daysPerMonth = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; } else { doomsdayInMonth = [ 2, 6, 6, 3, 1, 5, 3, 0, 4, 2, 6, 4, 1, 5 ]; daysPerMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; } } function weekday ( month : Int, day : Int ) : Int { var dim = doomsdayInMonth[ month - 1 ]; var offset = (day - dim + 6) % 7; return (offset + doomsday) % 7; } }