Whiteknight/Rosella

Merged
merged 1 commit into from Nov 27, 2011
Select commit
+82 −0
18 examples/date.winxed
 @@ -0,0 +1,18 @@ +// Doomsday Algorithm example. + +function main[main]() +{ + var rosella = load_packfile("rosella/core.pbc"); + var(Rosella.initialize_rosella)("date"); + + var d = new Rosella.Date.Doomsday(); + + print("Doomsday for 2011: "); + say(d.get_day_of_week(d.__get_dday(2011))); + + print("11/26/2011 was a... "); + say(d.get_day_of_week(d.get_day(2011, 11, 26))); + + print("9/11/2001 was a... "); + say(d.get_day_of_week(d.get_day(2001, 9, 11))); +}
4 setup.winxed
 @@ -329,6 +329,10 @@ function setup_experimental_libraries(var rosella) "random/randomnumber/BoxMullerNormal", "random/randomnumber/MersenneTwister" ); + + setup_unstable_lib(rosella, "date", [], + "date/Doomsday" + ); } function setup_utilities(var rosella)
60 src/unstable/date/Doomsday.winxed
 @@ -0,0 +1,60 @@ +/* Doomsday Algorithm + This class implements the Doomsday Algorithm, a fast, computationally-simple method + to determine the day of week of any day. +*/ +class Rosella.Date.Doomsday +{ + var doomsdays; + var days; + + function Doomsday() + { + self.doomsdays = [ 3, 28, 7, 4, 9, 6, 11, 8, 5, 10, 7, 12 ]; // doomsdays[N] is the day of month N that falls + // on a doomsday. + self.days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; + } + + function get_day(int year, int month, int day) + { + if (year < 1) + Rosella.Error.invalid(__FUNCTION__, "Bad year"); + if (month < 1 || month > 12) + Rosella.Error.invalid(__FUNCTION__, "Bad month"); + if (day < 1 || day > 31) + Rosella.Error.invalid(__FUNCTION__, "Bad day"); + + // Determine the doomsday for this year. + int dday = self.__get_dday(year); + + int leap = (year % 4) == 0; + int anchor = self.doomsdays[month - 1]; + if (leap && month <= 2) + anchor += 1; // the anchor date for jan/feb is +1 for leap years. + + while (day < anchor) + day += 7; // skip forward weeks if necessary. + while (day >= (anchor + 7)) + day -= 7; // skip backward weeks if necessary. + + // At this point day is during the week of anchor. + __ASSERT__(anchor <= day < anchor + 7); + + int dayoffset = day - anchor; + day = (dday + dayoffset) % 7; + + return day; + } + + function get_day_of_week(int day) + { + if (day < 0 || day > 6) + Rosella.Error.invalid(__FUNCTION__, "Bad day"); + + return self.days[day]; + } + + function __get_dday(int year) + { + return (2 + year + (year / 4) - (year / 100) + (year / 400)) % 7; + } +}