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);