

Task

Convert a given date from the   Gregorian calendar   to the   Discordian calendar.




convertDiscordian := proc(year, month, day)
	local days31, days30, daysThisYear, i, dYear, dMonth, dDay, seasons, week, dayOfWeek;
	days31 := [1, 3, 5, 7, 8, 10, 12];
	days30 := [4, 6, 9, 11];
	if month < 1 or month >12 then
		error "Invalid month: %1", month;
	end if;
	if (member(month, days31) and day > 31) or (member(month, days30) and day > 30) or (month = 2 and day > 29) or day < 1 then
		error "Invalid date: %1", day;
	end if;
	dYear := year + 1166;
	if month = 2 and day = 29 then
		printf("The date is St. Tib's Day, YOLD %a.\n", dYear);
	else
		seasons := ["Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"];
		week := ["Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"];
		daysThisYear := 0;
		for i to month-1 do
			if member(i, days31) then
				daysThisYear := daysThisYear + 31;
			elif member(i, days30) then
				daysThisYear := daysThisYear + 30;
			else
				daysThisYear := daysThisYear + 28;
			end if;
		end do;
		daysThisYear := daysThisYear + day -1;
		dMonth := seasons[trunc((daysThisYear) / 73)+1];
		dDay := daysThisYear mod 73 +1;
		dayOfWeek := week[daysThisYear mod 5 +1];
		printf("The date is %s %s %s, YOLD %a.\n", dayOfWeek, dMonth, convert(dDay, ordinal), dYear);
	end if;
end proc:
 
convertDiscordian (2016, 1, 1);
convertDiscordian (2016, 2, 29);
convertDiscordian (2016, 12, 31);