Discordian date
You are encouraged to solve this task according to the task description, using any language you may know.
See Also
Contents |
[edit] Ada
discordian.adb:
with Ada.Calendar.Arithmetic;
with Ada.Text_IO;
procedure Discordian is
use Ada.Calendar;
subtype Year_Number is Integer range 3067 .. 3565;
type Seasons is (Chaos, Discord, Confusion, Bureaucracy, The_Aftermath);
subtype Day_Number is Integer range 1 .. 73;
type Discordian_Date is record
Year : Year_Number;
Season : Seasons;
Day : Day_Number;
Is_Tibs_Day : Boolean := False;
end record;
procedure Convert (From : Time; To : out Discordian_Date) is
use Ada.Calendar.Arithmetic;
First_Day : Time;
Number_Days : Day_Count;
begin
First_Day := Time_Of (Year => Year (From), Month => 1, Day => 1);
Number_Days := From - First_Day;
To.Year := Year (Date => From) + 1166;
To.Is_Tibs_Day := False;
if (To.Year - 2) mod 4 = 0 then
if Number_Days > 59 then
Number_Days := Number_Days - 1;
elsif Number_Days = 59 then
To.Is_Tibs_Day := True;
end if;
end if;
To.Day := Day_Number (Number_Days mod 73 + 1);
case Number_Days / 73 is
when 0 => To.Season := Chaos;
when 1 => To.Season := Discord;
when 2 => To.Season := Confusion;
when 3 => To.Season := Bureaucracy;
when 4 => To.Season := The_Aftermath;
when others => raise Constraint_Error;
end case;
end Convert;
procedure Put (Item : Discordian_Date) is
begin
Ada.Text_IO.Put ("YOLD" & Integer'Image (Item.Year));
if Item.Is_Tibs_Day then
Ada.Text_IO.Put (", St. Tib's Day");
else
Ada.Text_IO.Put (", " & Seasons'Image (Item.Season));
Ada.Text_IO.Put (" " & Integer'Image (Item.Day));
end if;
Ada.Text_IO.New_Line;
end Put;
Test_Day : Time;
Test_DDay : Discordian_Date;
begin
Test_Day := Clock;
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2012, Month => 2, Day => 28);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2012, Month => 2, Day => 29);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2012, Month => 3, Day => 1);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2010, Month => 7, Day => 22);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2012, Month => 9, Day => 2);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
Test_Day := Time_Of (Year => 2012, Month => 12, Day => 31);
Convert (From => Test_Day, To => Test_DDay);
Put (Test_DDay);
end Discordian;
Output:
YOLD 3177, CHAOS 21 YOLD 3178, CHAOS 59 YOLD 3178, St. Tib's Day YOLD 3178, CHAOS 60 YOLD 3176, CONFUSION 56 YOLD 3178, BUREAUCRACY 25 YOLD 3178, THE_AFTERMATH 73
[edit] AWK
# DDATE.AWK - Gregorian to Discordian date contributed by Dan Nielsen
# syntax: GAWK -f DDATE.AWK [YYYYMMDD | YYYY-MM-DD | MM-DD-YYYY | DDMMMYYYY | YYYY] ...
# examples:
# GAWK -f DDATE.AWK today
# GAWK -f DDATE.AWK 20110722 one date
# GAWK -f DDATE.AWK 20110722 20120229 two dates
# GAWK -f DDATE.AWK 2012 yearly calendar
BEGIN {
split("Chaos,Discord,Confusion,Bureaucracy,The Aftermath",season_arr,",")
split("Sweetmorn,Boomtime,Pungenday,Prickle-Prickle,Setting Orange",weekday_arr,",")
split("Mungday,Mojoday,Syaday,Zaraday,Maladay",apostle_holyday_arr,",")
split("Chaoflux,Discoflux,Confuflux,Bureflux,Afflux",season_holyday_arr,",")
split("31,28,31,30,31,30,31,31,30,31,30,31",days_in_month,",") # days per month in non leap year
split("0 31 59 90 120 151 181 212 243 273 304 334",rdt," ") # relative day table
mmm = "JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC"
# 1 2 3 4 5 6 7 8 9 10 11 12
if (ARGV[1] == "") { # use current date
ARGV[ARGC++] = strftime("%Y%m%d") # GAWK only
# ARGV[ARGC++] = dos_date() # any AWK
# timetab(arr); ARGV[ARGC++] = sprintf("%04d%02d%02d",arr["YEAR"],arr["MONTH"],arr["DAY"]) # TAWK only
}
for (argno=1; argno<=ARGC-1; argno++) { # validate command line arguments
print("")
x = toupper(ARGV[argno])
if (x ~ /^[0-9][0-9][0-9][0-9][01][0-9][0-3][0-9]$/) { # YYYYMMDD
main(x)
}
else if (x ~ /^[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$/) { # YYYY-MM-DD
gsub(/-/,"",x)
main(x)
}
else if (x ~ /^[01][0-9]-[0-3][0-9]-[0-9][0-9][0-9][0-9]$/) { # MM-DD-YYYY
main(substr(x,7,4) substr(x,1,2) substr(x,4,2))
}
else if (x ~ /^[0-3][0-9](JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[0-9][0-9][0-9][0-9]$/) { # DDMMMYYYY
main(sprintf("%04d%02d%02d",substr(x,6,4),int((match(mmm,substr(x,3,3))/4)+1),substr(x,1,2)))
}
else if (x ~ /^[0-9][0-9][0-9][0-9]$/) { # YYYY
yearly_calendar(x)
}
else {
error("begin")
}
}
if (errors == 0) { exit(0) } else { exit(1) }
}
function main(x, d,dyear,m,season_day,season_nbr,text,weekday_nbr,y,year_day) {
y = substr(x,1,4) + 0
m = substr(x,5,2) + 0
d = substr(x,7,2) + 0
days_in_month[2] = (leap_year(y) == 1) ? 29 : 28
if (m < 1 || m > 12 || d < 1 || d > days_in_month[m]+0) {
error("main")
return
}
year_day = rdt[m] + d
dyear = y + 1166 # Discordian year
season_nbr = int((year_day - 1 ) / 73) + 1
season_day = ((year_day - 1) % 73) + 1
weekday_nbr = ((year_day - 1 ) % 5) + 1
if (season_day == 5) {
text = ", " apostle_holyday_arr[season_nbr]
}
else if (season_day == 50) {
text = ", " season_holyday_arr[season_nbr]
}
if (leap_year(y) && m == 2 && d == 29) {
printf("%04d-%02d-%02d is St. Tib's day, Year of Our Lady of Discord %s\n",y,m,d,dyear)
}
else {
printf("%04d-%02d-%02d is %s, %s %s, Year of Our Lady of Discord %s%s\n",
y,m,d,weekday_arr[weekday_nbr],season_arr[season_nbr],season_day,dyear,text)
}
}
function leap_year(y) { # leap year: 0=no, 1=yes
return (y % 400 == 0 || (y % 4 == 0 && y % 100)) ? 1 : 0
}
function yearly_calendar(y, d,m) {
days_in_month[2] = (leap_year(y) == 1) ? 29 : 28
for (m=1; m<=12; m++) {
for (d=1; d<=days_in_month[m]; d++) {
main(sprintf("%04d%02d%02d",y,m,d))
}
}
}
function dos_date( cmd,x) { # under Microsoft Windows XP
cmd = "DATE <NUL"
cmd | getline x # The current date is: MM/DD/YYYY
close(cmd) # close pipe
return sprintf("%04d%02d%02d",substr(x,28,4),substr(x,22,2),substr(x,25,2))
}
function error(x) {
printf("error: argument %d is invalid, %s, in %s\n",argno,ARGV[argno],x)
errors++
}
output:
GAWK -f DDATE.AWK 2011-08-22 is Prickle-Prickle, Bureaucracy 15, Year of Our Lady of Discord 3177 GAWK -f DDATE.AWK 20110722 20120229 2011-07-22 is Pungenday, Confusion 57, Year of Our Lady of Discord 3177 2012-02-29 is St. Tib's day, Year of Our Lady of Discord 3178
[edit] BASIC
#INCLUDE "datetime.bi"
DECLARE FUNCTION julian(AS DOUBLE) AS INTEGER
SeasonNames:
DATA "Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"
Weekdays:
DATA "Setting Orange", "Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle"
DaysPreceding1stOfMonth:
' jan feb mar apr may jun jul aug sep oct nov dec
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
DIM dyear AS INTEGER, dseason AS STRING, dday AS INTEGER, dweekday AS STRING
DIM tmpdate AS DOUBLE, jday AS INTEGER, result AS STRING
DIM L0 AS INTEGER
IF LEN(COMMAND$) THEN
tmpdate = DATEVALUE(COMMAND$)
ELSE
tmpdate = FIX(NOW())
END IF
dyear = YEAR(tmpdate) + 1166
IF (2 = MONTH(tmpdate)) AND (29 = DAY(tmpdate)) THEN
result = "Saint Tib's Day, " & STR$(dyear) & " YOLD"
ELSE
jday = julian(tmpdate)
RESTORE SeasonNames
FOR L0 = 1 TO (jday \ 73) + 1
READ dseason
NEXT
dday = (jday MOD 73)
IF 0 = dday THEN dday = 73
RESTORE Weekdays
FOR L0 = 1 TO (jday MOD 5) + 1
READ dweekday
NEXT
result = dweekday & ", " & dseason & " " & TRIM$(STR$(dday)) & ", " & TRIM$(STR$(dyear)) & " YOLD"
END IF
? result
END
FUNCTION julian(d AS DOUBLE) AS INTEGER
'doesn't account for leap years (not needed for ddate)
DIM tmp AS INTEGER, L1 AS INTEGER
RESTORE DaysPreceding1stOfMonth
FOR L1 = 1 TO MONTH(d)
READ tmp
NEXT
FUNCTION = tmp + DAY(d)
END FUNCTION
[edit] BBC BASIC
INSTALL @lib$+"DATELIB"
PRINT "01/01/2011 -> " FNdiscordian("01/01/2011")
PRINT "05/01/2011 -> " FNdiscordian("05/01/2011")
PRINT "28/02/2011 -> " FNdiscordian("28/02/2011")
PRINT "01/03/2011 -> " FNdiscordian("01/03/2011")
PRINT "22/07/2011 -> " FNdiscordian("22/07/2011")
PRINT "31/12/2011 -> " FNdiscordian("31/12/2011")
PRINT "01/01/2012 -> " FNdiscordian("01/01/2012")
PRINT "05/01/2012 -> " FNdiscordian("05/01/2012")
PRINT "28/02/2012 -> " FNdiscordian("28/02/2012")
PRINT "29/02/2012 -> " FNdiscordian("29/02/2012")
PRINT "01/03/2012 -> " FNdiscordian("01/03/2012")
PRINT "22/07/2012 -> " FNdiscordian("22/07/2012")
PRINT "31/12/2012 -> " FNdiscordian("31/12/2012")
END
DEF FNdiscordian(date$)
LOCAL Season$(), Weekday$(), mjd%, year%, day%
DIM Season$(4), Weekday$(4)
Season$() = "Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"
Weekday$() = "Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"
mjd% = FN_readdate(date$, "dmy", 2000)
year% = FN_year(mjd%)
IF FN_month(mjd%)=2 AND FN_day(mjd%)=29 THEN
= "St. Tib's Day, YOLD " + STR$(year% + 1166)
ENDIF
IF FN_month(mjd%) < 3 THEN
day% = mjd% - FN_mjd(1, 1, year%)
ELSE
day% = mjd% - FN_mjd(1, 3, year%) + 59
ENDIF
= Weekday$(day% MOD 5) + ", " + STR$(day% MOD 73 + 1) + " " + \
\ Season$(day% DIV 73) + ", YOLD " + STR$(year% + 1166)
Output:
01/01/2011 -> Sweetmorn, 1 Chaos, YOLD 3177 05/01/2011 -> Setting Orange, 5 Chaos, YOLD 3177 28/02/2011 -> Prickle-Prickle, 59 Chaos, YOLD 3177 01/03/2011 -> Setting Orange, 60 Chaos, YOLD 3177 22/07/2011 -> Pungenday, 57 Confusion, YOLD 3177 31/12/2011 -> Setting Orange, 73 The Aftermath, YOLD 3177 01/01/2012 -> Sweetmorn, 1 Chaos, YOLD 3178 05/01/2012 -> Setting Orange, 5 Chaos, YOLD 3178 28/02/2012 -> Prickle-Prickle, 59 Chaos, YOLD 3178 29/02/2012 -> St. Tib's Day, YOLD 3178 01/03/2012 -> Setting Orange, 60 Chaos, YOLD 3178 22/07/2012 -> Pungenday, 57 Confusion, YOLD 3178 31/12/2012 -> Setting Orange, 73 The Aftermath, YOLD 3178
[edit] C
For the source code of ddate in util-linux package, see [[1]].
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define season( x ) ((x) == 0 ? "Chaos" :\
(x) == 1 ? "Discord" :\
(x) == 2 ? "Confusion" :\
(x) == 3 ? "Bureaucracy" :\
"The Aftermath")
#define date( x ) ((x)%73 == 0 ? 73 : (x)%73)
#define leap_year( x ) ((x) % 400 == 0 || (((x) % 4) == 0 && (x) % 100))
char * ddate( int y, int d ){
int dyear = 1166 + y;
char * result = malloc( 100 * sizeof( char ) );
if( leap_year( y ) ){
if( d == 60 ){
sprintf( result, "St. Tib's Day, YOLD %d", dyear );
return result;
} else if( d >= 60 ){
-- d;
}
}
sprintf( result, "%s %d, YOLD %d", season( d/73 ), date( d ), dyear );
return result;
}
int day_of_year( int y, int m, int d ){
int month_lengths[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
for( ; m > 1; m -- ){
d += month_lengths[ m - 2 ];
if( m == 3 && leap_year( y ) ){
++ d;
}
}
return d;
}
int main( int argc, char * argv[] ){
time_t now;
struct tm * now_time;
int year, doy;
if( argc == 1 ){
now = time( NULL );
now_time = localtime( &now );
year = now_time->tm_year + 1900; doy = now_time->tm_yday + 1;
} else if( argc == 4 ){
year = atoi( argv[ 1 ] ); doy = day_of_year( atoi( argv[ 1 ] ), atoi( argv[ 2 ] ), atoi( argv[ 3 ] ) );
}
char * result = ddate( year, doy );
puts( result );
free( result );
return 0;
}
Demonstration:
$ ./ddate #today is Jan 7th, 2011 Chaos 7, YOLD 3177 $ ./ddate 2011 1 7 Chaos 7, YOLD 3177 $ ./ddate 2012 2 28 Chaos 59, YOLD 3178 $ ./ddate 2012 2 29 St. Tib's Day, YOLD 3178 $ ./ddate 2012 3 1 Chaos 60, YOLD 3178 $ ./ddate 2010 7 22 Confusion 57, YOLD 3176
[edit] C++
#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
//--------------------------------------------------------------------------------------------------
using namespace std;
//--------------------------------------------------------------------------------------------------
class myTuple
{
public:
void set( int a, int b, string c ) { t.first.first = a; t.first.second = b; t.second = c; }
bool operator == ( pair<int, int> p ) { return p.first == t.first.first && p.second == t.first.second; }
string second(){ return t.second; }
private:
pair<pair<int, int>, string> t;
};
//--------------------------------------------------------------------------------------------------
class discordian
{
public:
discordian()
{
myTuple t;
t.set( 5, 1, "Mungday" ); holyday.push_back( t ); t.set( 19, 2, "Chaoflux" ); holyday.push_back( t );
t.set( 29, 2, "St. Tib's Day" ); holyday.push_back( t ); t.set( 19, 3, "Mojoday" ); holyday.push_back( t );
t.set( 3, 5, "Discoflux" ); holyday.push_back( t ); t.set( 31, 5, "Syaday" ); holyday.push_back( t );
t.set( 15, 7, "Confuflux" ); holyday.push_back( t ); t.set( 12, 8, "Zaraday" ); holyday.push_back( t );
t.set( 26, 9, "Bureflux" ); holyday.push_back( t ); t.set( 24, 10, "Maladay" ); holyday.push_back( t );
t.set( 8, 12, "Afflux" ); holyday.push_back( t );
seasons.push_back( "Chaos" ); seasons.push_back( "Discord" ); seasons.push_back( "Confusion" );
seasons.push_back( "Bureaucracy" ); seasons.push_back( "The Aftermath" );
wdays.push_back( "Setting Orange" ); wdays.push_back( "Sweetmorn" ); wdays.push_back( "Boomtime" );
wdays.push_back( "Pungenday" ); wdays.push_back( "Prickle-Prickle" );
}
void convert( int d, int m, int y )
{
if( d == 0 || m == 0 || m > 12 || d > getMaxDay( m, y ) ) { cout << "\nThis is not a date!"; return; }
pair <int, int> p; p.first = d, p.second = m; vector<myTuple>::iterator f;
f = find( holyday.begin(), holyday.end(), p ); int dd = 0, day, wday, mon, yr = y + 1166;
if( d == 29 && m == 2 && isLeap( y ) )
{ cout << ( *f ).second() << ", Year of Our Lady of Discord " << yr; return; }
for( int x = 1; x < m; x++ ) dd += getMaxDay( x, 1 ); dd += d; day = dd % 73; wday = dd % 5; mon = dd / 73;
cout << wdays[wday] << ", " << seasons[mon] << " " << day << ", Year of Our Lady of Discord " << yr;
if( f != holyday.end() ) cout << " - " << ( *f ).second();
}
private:
int getMaxDay( int m, int y )
{ int dd[] = { 0, 31, isLeap( y ) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; return dd[m]; }
bool isLeap( int y )
{ bool l = false; if( !( y % 4 ) ) { if( y % 100 ) l = true; else if( !( y % 400 ) ) l = true; } return l; }
vector<myTuple> holyday; vector<string> seasons, wdays;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
string date; discordian disc;
while( true )
{
cout << "Enter a date (dd mm yyyy) or 0 to quit: "; getline( cin, date ); if( date == "0" ) break;
if( date.length() == 10 )
{
istringstream iss( date ); vector<string> vc;
copy( istream_iterator<string>( iss ), istream_iterator<string>(), back_inserter<vector<string> >( vc ) );
disc.convert( atoi( vc[0].c_str() ), atoi( vc[1].c_str() ), atoi( vc[2].c_str() ) ); cout << "\n\n\n";
}
else cout << "\nIs this a date?!\n\n";
}
return 0;
}
//--------------------------------------------------------------------------------------------------
- Output:
Enter a date (dd mm yyyy) or 0 to quit: 22 07 2010 Pungenday, Confusion 57, Year of Our Lady of Discord 3176
Enter a date (dd mm yyyy) or 0 to quit: 07 01 2011 Boomtime, Chaos 7, Year of Our Lady of Discord 3177
Enter a date (dd mm yyyy) or 0 to quit: 29 02 2012 St. Tib's Day, Year of Our Lady of Discord 3178
Enter a date (dd mm yyyy) or 0 to quit: 04 06 2013 Setting Orange, Confusion 9, Year of Our Lady of Discord 3179
[edit] D
import std.stdio, std.datetime, std.conv, std.string;
immutable seasons = ["Chaos", "Discord", "Confusion", "Bureaucracy",
"The Aftermath"];
immutable weekday = ["Sweetmorn", "Boomtime", "Pungenday",
"Prickle-Prickle", "Setting Orange"];
immutable apostle = ["Mungday", "Mojoday", "Syaday", "Zaraday",
"Maladay"];
immutable holiday = ["Chaoflux", "Discoflux", "Confuflux",
"Bureflux", "Afflux"];
string discordianDate(in Date date) {
auto dyear = text(date.year + 1166);
auto isLeapYear = date.isLeapYear;
if (isLeapYear && date.month == 2 && date.day == 29)
return "St. Tib's Day, in the YOLD " ~ dyear;
auto doy = date.dayOfYear;
if (isLeapYear && doy >= 60)
doy--;
auto dsday = doy % 73; // season day
if (dsday == 5) return apostle[doy / 73] ~ ", in the YOLD " ~ dyear;
if (dsday == 50) return holiday[doy / 73] ~ ", in the YOLD " ~ dyear;
auto dseas = seasons[doy / 73];
auto dwday = weekday[(doy-1) % 5];
return format("%s, day %s of %s in the YOLD %s", dwday, dsday, dseas,
dyear);
}
void main() {
auto today = cast(Date)Clock.currTime();
writeln(discordianDate(today));
}
unittest {
assert(discordianDate(Date(2010,7,22)) ==
"Pungenday, day 57 of Confusion in the YOLD 3176");
assert(discordianDate(Date(2012,2,28)) ==
"Prickle-Prickle, day 59 of Chaos in the YOLD 3178");
assert(discordianDate(Date(2012,2,29)) ==
"St. Tib's Day, in the YOLD 3178");
assert(discordianDate(Date(2012,3, 1)) ==
"Setting Orange, day 60 of Chaos in the YOLD 3178");
assert(discordianDate(Date(2010,1, 5)) ==
"Mungday, in the YOLD 3176");
assert(discordianDate(Date(2011,5, 3)) ==
"Discoflux, in the YOLD 3177");
}
- Output:
Setting Orange, day 42 of Discord in the YOLD 3178
[edit] Euphoria
function isLeapYear(integer year)
return remainder(year,4)=0 and remainder(year,100)!=0 or remainder(year,400)=0
end function
constant YEAR = 1, MONTH = 2, DAY = 3, DAY_OF_YEAR = 8
constant month_lengths = {31,28,31,30,31,30,31,31,30,31,30,31}
function dayOfYear(sequence Date)
integer d
if length(Date) = DAY_OF_YEAR then
d = Date[DAY_OF_YEAR]
else
d = Date[DAY]
for i = Date[MONTH]-1 to 1 by -1 do
d += month_lengths[i]
if i = 2 and isLeapYear(Date[YEAR]) then
d += 1
end if
end for
end if
return d
end function
constant seasons = {"Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"}
constant weekday = {"Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"}
constant apostle = {"Mungday", "Mojoday", "Syaday", "Zaraday", "Maladay"}
constant holiday = {"Chaoflux", "Discoflux", "Confuflux", "Bureflux", "Afflux"}
function discordianDate(sequence Date)
sequence dyear, dseas, dwday
integer leap, doy, dsday
dyear = sprintf("%d",Date[YEAR]+1166)
leap = isLeapYear(Date[YEAR])
if leap and Date[MONTH] = 2 and Date[DAY] = 29 then
return "St. Tib's Day, in the YOLD " & dyear
end if
doy = dayOfYear(Date)
if leap and doy >= 60 then
doy -= 1
end if
dsday = remainder(doy,73)
if dsday = 5 then
return apostle[doy/73+1] & ", in the YOLD " & dyear
elsif dsday = 50 then
return holiday[doy/73+1] & ", in the YOLD " & dyear
end if
dseas = seasons[doy/73+1]
dwday = weekday[remainder(doy-1,5)+1]
return sprintf("%s, day %d of %s in the YOLD %s", {dwday, dsday, dseas, dyear})
end function
sequence today
today = date()
today[YEAR] += 1900
puts(1, discordianDate(today))
[edit] F#
open System
let seasons = [| "Chaos"; "Discord"; "Confusion"; "Bureaucracy"; "The Aftermath" |]
let ddate (date:DateTime) =
let dyear = date.Year + 1166
let leapYear = DateTime.IsLeapYear(date.Year)
if leapYear && date.Month = 2 && date.Day = 29 then
sprintf "St. Tib's Day, %i YOLD" dyear
else
// compensate for St. Tib's Day
let dayOfYear = if leapYear && date.DayOfYear >= 60 then date.DayOfYear - 1 else date.DayOfYear
let season, dday = Math.DivRem(dayOfYear, 73)
sprintf "%s %i, %i YOLD" seasons.[season] dday dyear
[edit] Go
A package modeled after the time package in the Go standard library
package ddate
import (
"strconv"
"strings"
"time"
)
// Predefined formats for DiscDate.Format
const (
DefaultFmt = "Pungenday, Discord 5, 3131 YOLD"
OldFmt = `Today is Pungenday, the 5th day of Discord in the YOLD 3131
Celebrate Mojoday`
)
// Formats passed to DiscDate.Format are protypes for formated dates.
// Format replaces occurrences of prototype elements (the constant strings
// listed here) with values corresponding to the date being formatted.
// If the date is St. Tib's Day, the string from the first date element
// through the last is replaced with "St. Tib's Day".
const (
protoLongSeason = "Discord"
protoShortSeason = "Dsc"
protoLongDay = "Pungenday"
protoShortDay = "PD"
protoOrdDay = "5"
protoCardDay = "5th"
protoHolyday = "Mojoday"
protoYear = "3131"
)
var (
longDay = []string{"Sweetmorn", "Boomtime", "Pungenday",
"Prickle-Prickle", "Setting Orange"}
shortDay = []string{"SM", "BT", "PD", "PP", "SO"}
longSeason = []string{
"Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"}
shortSeason = []string{"Chs", "Dsc", "Cfn", "Bcy", "Afm"}
holyday = [][]string{{"Mungday", "Chaoflux"}, {"Mojoday", "Discoflux"},
{"Syaday", "Confuflux"}, {"Zaraday", "Bureflux"}, {"Maladay", "Afflux"}}
)
type DiscDate struct {
StTibs bool
Dayy int // zero based day of year, meaningless if StTibs is true
Year int // gregorian + 1166
}
func New(eris time.Time) DiscDate {
t := time.Date(eris.Year(), 1, 1, eris.Hour(), eris.Minute(),
eris.Second(), eris.Nanosecond(), eris.Location())
bob := int(eris.Sub(t).Hours()) / 24
raw := eris.Year()
hastur := DiscDate{Year: raw + 1166}
if raw%4 == 0 && (raw%100 != 0 || raw%400 == 0) {
if bob > 59 {
bob--
} else if bob == 59 {
hastur.StTibs = true
return hastur
}
}
hastur.Dayy = bob
return hastur
}
func (dd DiscDate) Format(f string) (r string) {
var st, snarf string
var dateElement bool
f6 := func(proto, wibble string) {
if !dateElement {
snarf = r
dateElement = true
}
if st > "" {
r = ""
} else {
r += wibble
}
f = f[len(proto):]
}
f4 := func(proto, wibble string) {
if dd.StTibs {
st = "St. Tib's Day"
}
f6(proto, wibble)
}
season, day := dd.Dayy/73, dd.Dayy%73
for f > "" {
switch {
case strings.HasPrefix(f, protoLongDay):
f4(protoLongDay, longDay[dd.Dayy%5])
case strings.HasPrefix(f, protoShortDay):
f4(protoShortDay, shortDay[dd.Dayy%5])
case strings.HasPrefix(f, protoCardDay):
funkychickens := "th"
if day/10 != 1 {
switch day % 10 {
case 0:
funkychickens = "st"
case 1:
funkychickens = "nd"
case 2:
funkychickens = "rd"
}
}
f4(protoCardDay, strconv.Itoa(day+1)+funkychickens)
case strings.HasPrefix(f, protoOrdDay):
f4(protoOrdDay, strconv.Itoa(day+1))
case strings.HasPrefix(f, protoLongSeason):
f6(protoLongSeason, longSeason[season])
case strings.HasPrefix(f, protoShortSeason):
f6(protoShortSeason, shortSeason[season])
case strings.HasPrefix(f, protoHolyday):
if day == 4 {
r += holyday[season][0]
} else if day == 49 {
r += holyday[season][1]
}
f = f[len(protoHolyday):]
case strings.HasPrefix(f, protoYear):
r += strconv.Itoa(dd.Year)
f = f[4:]
default:
r += f[:1]
f = f[1:]
}
}
if st > "" {
r = snarf + st + r
}
return
}
Example program using above package
package main
import (
"ddate"
"fmt"
"os"
"strings"
"time"
)
func main() {
pi := 1
fnord := ddate.DefaultFmt
if len(os.Args) > 1 {
switch os.Args[1][0] {
case '+':
pi++
fnord = os.Args[1][1:]
case '-':
usage()
}
}
var eris time.Time
switch len(os.Args) - pi {
case 0:
eris = time.Now()
case 3:
var err error
eris, err = time.Parse("2 1 2006", strings.Join(os.Args[pi:pi+3], " "))
if err != nil {
fmt.Println(err)
usage()
}
default:
usage()
}
fmt.Println(ddate.New(eris).Format(fnord))
}
func usage() {
fmt.Fprintf(os.Stderr, "usage: %s [+format] [day month year]\n", os.Args[0])
os.Exit(1)
}
Example output:
> ddate Pungenday, Confusion 62, 3177 YOLD > ddate 29 2 2012 St. Tib's Day, 3178 YOLD
[edit] Haskell
import Data.List
import Data.Time
import Data.Time.Calendar.MonthDay
seasons = words "Chaos Discord Confusion Bureaucracy The_Aftermath"
discordianDate (y,m,d) = do
let doy = monthAndDayToDayOfYear (isLeapYear y) m d
(season, dday) = divMod doy 73
dos = dday - fromEnum (isLeapYear y && m >2)
dDate
| isLeapYear y && m==2 && d==29 = "St. Tib's Day, " ++ show (y+1166) ++ " YOLD"
| otherwise = seasons!!season ++ " " ++ show dos ++ ", " ++ show (y+1166) ++ " YOLD"
putStrLn dDate
Examples:
*Main> mapM_ discordianDate [(2012,2,28),(2012,2,29),(2012,3,1),(2010,9,2),(2010,12,6)] Chaos 59, 3178 YOLD St. Tib's Day, 3178 YOLD Chaos 60, 3178 YOLD Bureaucracy 26, 3176 YOLD The_Aftermath 48, 3176 YOLD
In GHCi we can also execute shell commands.
- Using Linux utility ddate
*Main> :! ddate Today is Setting Orange, the 26th day of Bureaucracy in the YOLD 3176 *Main> :! ddate 29 2 2012 Sint Tibs *Main> :! ddate 2 9 2010 Setting Orange, Bureaucracy 26, 3176 YOLD
[edit] Icon and Unicon
This version is loosely based on a modified translation of the original ddate.c and like the original the leap year functionality is Julian not Gregorian.
link printfOutput:
procedure main()
Demo(2010,1,1)
Demo(2010,7,22)
Demo(2012,2,28)
Demo(2012,2,29)
Demo(2012,3,1)
Demo(2010,1,5)
Demo(2011,5,3)
Demo(2012,2,28)
Demo(2012,2,29)
Demo(2012,3,1)
Demo(2010,7,22)
Demo(2012,12,22)
end
procedure Demo(y,m,d) #: demo display
printf("%i-%i-%i = %s\n",y,m,d,DiscordianDateString(DiscordianDate(y,m,d)))
end
record DiscordianDateRecord(year,yday,season,sday,holiday)
procedure DiscordianDate(year,month,day) #: Convert normal date to Discordian
static cal
initial cal := [31,28,31,30,31,30,31,31,30,31,30,31]
ddate := DiscordianDateRecord(year+1166)
every (ddate.yday := day - 1) +:= cal[1 to month-1] # zero origin
ddate.sday := ddate.yday
if ddate.year % 4 = 2 & month = 2 & day = 29 then
ddate.holiday := 1 # Note: st tibs is outside of weekdays
else {
ddate.season := (ddate.yday / 73) + 1
ddate.sday := (ddate.yday % 73) + 1
ddate.holiday := 1 + ddate.season * case ddate.sday of { 5 : 1; 50 : 2}
}
return ddate
end
procedure DiscordianDateString(ddate) #: format a Discordian Date String
static days,seasons,holidays
initial {
days := ["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"]
seasons := ["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"]
holidays := ["St. Tib's Day","Mungday","Chaoflux","Mojoday","Discoflux",
"Syaday","Confuflux","Zaraday","Bureflux","Maladay","Afflux"]
}
return (( holidays[\ddate.holiday] || "," ) |
( days[1+ddate.yday%5] || ", day " ||
ddate.sday || " of " || seasons[ddate.season])) ||
" in the YOLD " || ddate.year
end
2010-1-1 = Sweetmorn, day 1 of Chaos in the YOLD 3176 2010-7-22 = Pungenday, day 57 of Confusion in the YOLD 3176 2012-2-28 = Prickle-Prickle, day 59 of Chaos in the YOLD 3178 2012-2-29 = St. Tib's Day, in the YOLD 3178 2012-3-1 = Setting Orange, day 60 of Chaos in the YOLD 3178 2010-1-5 = Mungday, in the YOLD 3176 2011-5-3 = Discoflux, in the YOLD 3177 2012-2-28 = Prickle-Prickle, day 59 of Chaos in the YOLD 3178 2012-2-29 = St. Tib's Day, in the YOLD 3178 2012-3-1 = Setting Orange, day 60 of Chaos in the YOLD 3178 2010-7-22 = Pungenday, day 57 of Confusion in the YOLD 3176 2012-12-22 = Sweetmorn, day 64 of The Aftermath in the YOLD 3178
[edit] J
require'dates'
leap=: _1j1 * 0 -/@:= 4 100 400 |/ {.@]
bs=: ((#:{.) + 0 j. *@[ * {:@]) +.
disc=: ((1+0 73 bs[ +^:(58<]) -/@todayno@(,: 1 1,~{.)@]) ,~1166+{.@])~ leap
Example use:
disc 2012 2 28
3178 1 59
disc 2012 2 29
3178 1 59j1
disc 2012 3 1
3178 1 60j1
disc 2012 12 31
3178 5 73j1
disc 2013 1 1
3179 1 1
see talk page. But, in essence, this version uses season ordinals with a single imaginary day after the 59th of the first season, on leap years. This is implemented so that that imaginary day has been passed for all remaining days of a leap year.
[edit] JavaScript
/**
* All Hail Discordia! - this script prints Discordian date using system date.
* author: s1w_, lang: JavaScript
*/
function print_ddate(mod) {
var p;
switch(mod || 0) {// <--choose display pattern or pass option by parameter
default:
case 0:/* Sweetmorn, Day 57 of the Season of Confusion, Anno Mung 3177 */ p="{0}, [Day {1} of the Season of {2}], Anno Mung {3}"; break;
case 1:/* Sweetmorn, The 57th Day of Confusion, 3177 YOLD */ p="{0}, [The {1}th Day of {2}], {3} YOLD"; break;
case 2:/* Sweetmorn, the 57th day of Confusion, AM 3177 */ p="{0}, [the {1}th day of {2}], AM {3}"; break;
case 3:/* Sweetmorn / Confusion 57th / AM 3177 */ p="{0} / [{2} {1}th] / AM {3}"; break;
}
var ddateStr, curr, sum, extra, today, day, month, year, dSeason, dDay, season, ddate, dyear;
format = function(s, $1, $2, $3, $4) {
if ($2 != undefined) {
var postfix;
switch(parseInt($2.charAt($2.length-1))) {
case 1: postfix = '}st'; break;
case 2: postfix = '}nd'; break;
case 3: postfix = '}rd'; break;
default:postfix = '}th';
}
return p.replace(/\}th/, postfix).replace(/(\[|\])/g, '').format($1, $2, $3, $4);
}
else return p.replace(/\[.*?\]/,"<span style='color:green'>{2}</span>").format($1, $2, $3, $4);
}
String.prototype.format = function() {
var pattern = /\{\d+\}/g;
var args = arguments;
return this.replace(pattern, function(capture){ return args[capture.match(/\d+/)]; });
}
dDay = new Array("Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange");
dSeason = new Array("Chaos", "Discord", "Confusion", "Bureaucracy", "Aftermath");
curr = new Date(); extra = new Array(0,3,0,3,2,3,2,3,3,2,3,2);
today = curr.getDate(); month = curr.getMonth(); year = curr.getFullYear();
sum = month * 28;
for(var i=0; i<=month; i++)
sum += extra[i];
sum += today;
day = (sum - 1) % 5; ddate = sum % 73;
season = (month==1)&&(today==29) ? "St. Tib\'s Day" : dSeason[Math.floor(sum/73)];
dyear = year+1166;
ddateStr = ""+dDay[day]+ddate+season+dyear;
document.write(ddateStr.replace(/(\D+)(?:(\d+)(?!St)|(?:\d+))(\D+)(\d+)/i, format));
}
Example use:
print_ddate()
"Sweetmorn, Day 57 of the Season of Confusion, Anno Mung 3177"
print_ddate(1)
"Sweetmorn, The 57th Day of Confusion, 3177 YOLD"
print_ddate(2)
"Sweetmorn, the 57th day of Confusion, AM 3177"
print_ddate(3)
"Sweetmorn / Confusion 57th / AM 3177"
look at calendar; lern about holydays
[edit] Mathematica
DiscordianDate[y_, m_, d_] := Module[{year = ToString[y + 1166], month = m, day = d},
DMONTHS = {"Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"};
DDAYS = {"Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"};
DayOfYear = DateDifference[{y} ,{y, m, d}] + 1;
LeapYearQ = (Mod[#, 4]== 0 && (Mod[#, 100] != 0 || Mod[#, 400] == 0))&@ y;
If [ LeapYearQ && month == 2 && day == 29,
Print["Today is St. Tib's Day, YOLD ", ]
,
If [ LeapYearQ && DayOfYear >= 60, DayOfYear -= 1 ];
{season, dday} = {Quotient[DayOfYear, 73], Mod[DayOfYear, 73]};
Print["Today is ", DDAYS[[Mod[dday,4] + 1]],", ",DMONTHS[[season+1]]," ",dday,", YOLD ",year]
];
]
Example output:
DiscordianDate[2012,2,28] -> Today is Prickle-Prickle, Chaos 59, YOLD 3178 DiscordianDate[2012,2,29] -> Today is St. Tib's Day, YOLD 3178 DiscordianDate[2012,3,1] -> Today is Setting Orange, Chaos 60, YOLD 3178
[edit] Perl 6
my @seasons = < Chaos Discord Confusion Bureaucracy >, 'The Aftermath';Output:
my @days = < Sweetmorn Boomtime Pungenday Prickle-Prickle >, 'Setting Orange';
sub ordinal ( Int $n ) { $n ~ ( $n % 100 == 11|12|13
?? 'th' !! < th st nd rd th th th th th th >[$n % 10] ) }
sub ddate ( Str $ymd ) {
my $d = DateTime.new: "{$ymd}T00:00:00Z" or die;
my $yold = 'in the YOLD ' ~ $d.year + 1166;
my $day_of_year0 = $d.day-of-year - 1;
if $d.is-leap-year {
return "St. Tib's Day, $yold" if $d.month == 2 and $d.day == 29;
$day_of_year0-- if $day_of_year0 >= 60; # Compensate for St. Tib's Day
}
my $weekday = @days[ $day_of_year0 mod 5 ];
my $season = @seasons[ $day_of_year0 div 73 ];
my $season_day = ordinal( $day_of_year0 mod 73 + 1 );
return "$weekday, the $season_day day of $season $yold";
}
say "$_ is {.&ddate}" for < 2010-07-22 2012-02-28 2012-02-29 2012-03-01 >;
2010-07-22 is Pungenday, the 57th day of Confusion in the YOLD 3176 2012-02-28 is Prickle-Prickle, the 59th day of Chaos in the YOLD 3178 2012-02-29 is St. Tib's Day, in the YOLD 3178 2012-03-01 is Setting Orange, the 60th day of Chaos in the YOLD 3178
[edit] PHP
<?phpOutput:
// Discordian dating machine. Accepts date from PHP function date() or from the URL.
// The Discordian calendar has 5 days in a week, 73 days in a month and 5 months in a year.
// Ex. ddate.php will generate todays date according to your computer
// Ex. ddate.php?y=2012&m=2&y=29 will generate the date for Feb. 29, 2012
$DAYS = array("Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange");
$MONTHS = array("Chaos","Discord","Confusion","Bureaucracy","The Aftermath");
// If user passed year, month and day variables in URL
if(isset($_GET['y']) && isset($_GET['m']) && isset($_GET['d'])) {
// Get year, month and day from URL
$usery = $_GET['y']; $userm = $_GET['m']; $userd = $_GET['d'];
// Use unix time to calculate day of year starting at zero
$userdate = mktime(0,0,0,$userm,$userd,$usery);
$ddays = ($userdate - mktime(0,0,0,1,1,$usery)) / 86400;
// Calculates the Discordian year, month and day
$dyear = ($usery) + 1166; $dmonth = $MONTHS[$dday/73]; $dday = $ddays%73 + 1;
}
// If user didn't pass year, get date from PHP function
else {
// Create array containing current Gregorian year, month, day,
// days of year starting at zero and whether or not year is a leap
$date = explode(" ",date('Y n j z L'));
// Calculates the Discordian year, month and day
$dyear = $date[0]+1166; $dmonth = $MONTHS[$date[3]/73]; $dday = $date[3]%73 +1;
}
// Determine the name of the day
if ($ddays === NULL) { $ddayname= $DAYS[$date[3]%5]; }
else { $ddayname= $DAYS[$ddays%5]; }
// Leap year exception for date from PHP
if ($ddays === NULL) {
if ($date[4]) {
if ($date[1] == 2 && $date[2] == 29) { echo "Today is St. Tib's Day, YOLD " . $dyear; }
if ($date[3] >= 60) { //offset day by one if leap year
$dday -= 1;
if($dday % 5 == 0) $ddayname = $DAYS[4];
else $ddayname = $DAYS[($dday%5)];
}
}
// Display Discordian date
echo "Today is " . $ddayname . ", " . $dmonth . " " . $dday . ", YOLD " . $dyear;
}
else { // Leap year exception for date from URL
if ($usery % 100 == 0) { // leap year exception for years that are divisible by one hundred
if ($usery % 400 == 0 && $userm == 2 && $userd == 29) { echo "Today is St. Tib's Day, YOLD " . $dyear; }
}
else if ($usery % 4 == 0) { // if the year is a leap year
if ($userm == 2 && $userd == 29) { echo "Today is St. Tib's Day, YOLD " . $dyear; }
elseif ($ddays >= 60) { // offset day by one if leap year
$dday -=1;
if($dday % 5 == 0) $ddayname = $DAYS[4];
else $ddayname=$DAYS[($dday%5-1)];
echo "Today is " . $ddayname . ", " . $dmonth . " " . $dday . ", YOLD " . $dyear;
}
else { echo "Today is " . $ddayname . ", " . $dmonth . " " . $dday . ", YOLD " . $dyear; }
}
// Display Discordian date
else { echo "Today is " . $ddayname . ", " . $dmonth . " " . $dday . ", YOLD " . $dyear; }
}
?>
ddate.php #23 November 2011 Today is Boomtime, The Aftermath 35, YOLD 3177 ddate.php?y=2012&m=2&y=28 Today is Prickle-Prickle, Chaos 59, YOLD 3178 ddate.php?y=2012&m=2&y=29 Today is St. Tib's Day, YOLD 3178 ddate.php?y=2012&m=3&y=1 Today is Setting Orange, Chaos 60, YOLD 3178
[edit] PicoLisp
(de disdate (Year Month Day)
(let? Date (date Year Month Day)
(let (Leap (date Year 2 29) D (- Date (date Year 1 1)))
(if (and Leap (= 2 Month) (= 29 Day))
(pack "St. Tib's Day, YOLD " (+ Year 1166))
(and Leap (>= D 60) (dec 'D))
(pack
(get
'("Chaos" "Discord" "Confusion" "Bureaucracy" "The Aftermath")
(inc (/ D 73)) )
" "
(inc (% D 73))
", YOLD "
(+ Year 1166) ) ) ) ) )
[edit] Pike
Pike includes a Discordian calendar. dates can be converted from any calendar to any other.
> Calendar.Discordian.now()->format_ext_ymd();
Result: "Pungenday, 59 Bureaucracy 3177"
> Calendar.Discordian.Day(Calendar.Day(2011,11,11))->format_ext_ymd();
Result: "Setting Orange, 23 The Aftermath 3177"
> Calendar.Discordian.Day(Calendar.Badi.Day(168,13,9))->format_ext_ymd();
Result: "Setting Orange, 23 The Aftermath 3177"
> Calendar.Day((Calendar.Discordian.Month()+1)->day(1));
Result: Day(Thu 20 Oct 2011)
[edit] PowerBASIC
#COMPILE EXE
#DIM ALL
'change this for systems that use a different character
$DATESEP = "-"
FUNCTION day(date AS STRING) AS LONG
'date is same format as date$
DIM tmpdash1 AS LONG, tmpdash2 AS LONG
tmpdash1 = INSTR(date, $DATESEP)
tmpdash2 = INSTR(-1, date, $DATESEP)
FUNCTION = VAL(MID$(date, tmpdash1 + 1, tmpdash2 - tmpdash1 - 1))
END FUNCTION
FUNCTION month(date AS STRING) AS LONG
'date is same format as date$
DIM tmpdash AS LONG
tmpdash = INSTR(date, $DATESEP)
FUNCTION = VAL(LEFT$(date, tmpdash - 1))
END FUNCTION
FUNCTION year(date AS STRING) AS LONG
'date is same format as date$
DIM tmpdash AS LONG
tmpdash = INSTR(-1, date, $DATESEP)
FUNCTION = VAL(MID$(date, tmpdash + 1))
END FUNCTION
FUNCTION julian(date AS STRING) AS LONG
'date is same format as date$
'doesn't account for leap years (not needed for ddate)
'days preceding 1st of month
' jan feb mar apr may jun jul aug sep oct nov dec
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
FUNCTION = VAL(READ$(month(date))) + day(date)
END FUNCTION
FUNCTION PBMAIN () AS LONG
'Season names
DATA "Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"
'Weekdays
DATA "Setting Orange", "Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle"
DIM dyear AS LONG, dseason AS STRING, dday AS LONG, dweekday AS STRING
DIM tmpdate AS STRING, jday AS LONG, result AS STRING
IF LEN(COMMAND$) THEN
tmpdate = COMMAND$
ELSE
tmpdate = DATE$
END IF
dyear = year(tmpdate) + 1166
IF (2 = month(tmpdate)) AND (29 = day(tmpdate)) THEN
result = "Saint Tib's Day, " & STR$(dyear) & " YOLD"
ELSE
jday = julian(tmpdate)
dseason = READ$((jday \ 73) + 1)
dday = (jday MOD 73)
IF 0 = dday THEN dday = 73
dweekday = READ$((jday MOD 5) + 6)
result = dweekday & ", " & dseason & " " & TRIM$(STR$(dday)) & ", " & TRIM$(STR$(dyear)) & " YOLD"
END IF
? result
END FUNCTION
[edit] PureBasic
Procedure.s Discordian_Date(Y, M, D)
Protected DoY=DayOfYear(Date(Y,M,D,0,0,0)), Yold$=Str(Y+1166)
Dim S.s(4)
S(0)="Chaos": S(1)="Discord": S(2)="Confusion": S(3)="Bureaucracy"
S(4)="The Aftermath"
If (Y%4=0 And Y%100) Or Y%400=0
If M=2 And D=29
ProcedureReturn "St. Tib's Day, YOLD " + Yold$
ElseIf DoY>=2*30
DoY-1
EndIf
EndIf
ProcedureReturn S(DoY/73)+" "+Str(DoY%73)+", Yold "+Yold$
EndProcedure
[edit] Python
import datetime, calendar
DISCORDIAN_SEASONS = ["Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"]
def ddate(year, month, day):
today = datetime.date(year, month, day)
is_leap_year = calendar.isleap(year)
if is_leap_year and month == 2 and day == 29:
return "St. Tib's Day, YOLD " + (year + 1166)
day_of_year = today.timetuple().tm_yday - 1
if is_leap_year and day_of_year >= 60:
day_of_year -= 1 # Compensate for St. Tib's Day
season, dday = divmod(day_of_year, 73)
return "%s %d, YOLD %d" % (DISCORDIAN_SEASONS[season], dday + 1, year + 1166)
[edit] REXX
/*REXX program converts mm/dd/yyyy Gregorian date ───> Discordian date. */
/*Gregorian date may be m/d/yy ──or── m/d format. */
day.1='Sweetness' /*define 1st day-of-Discordian-week.*/
day.2='Boomtime' /*define 2nd day-of-Discordian-week.*/
day.3='Pungenday' /*define 3rd day-of-Discordian-week.*/
day.4='Prickle-Prickle' /*define 4th day-of-Discordian-week.*/
day.5='Setting Orange' /*define 5th day-of-Discordian-week.*/
seas.0="St. Tib's day," /*define the leap-day of Discordian yr.*/
seas.1='Chaos' /*define 1st season-of-Discordian-year.*/
seas.2='Discord' /*define 2nd season-of-Discordian-year.*/
seas.3='Confusion' /*define 3rd season-of-Discordian-year.*/
seas.4='Bureaucracy' /*define 4th season-of-Discordian-year.*/
seas.5='The Aftermath' /*define 5th season-of-Discordian-year.*/
parse arg gM '/' gD "/" gY . /*get the date specified. */
gY=left(right(date(),4),4-length(Gy))gY /*adjust for a 2-dig yr or none*/
/*below:get day-of-year,adj LeapY*/
doy=date('d',gY||right(gM,2,0)right(gD,2,0),"s")-(leapyear(gY) & gM>2)
dW=doy//5;if dW==0 then dW=5 /*compute the Discordian weekday.*/
dS=(doy-1)%73+1 /*compute the Discordian season. */
dD=doy//73;if dD==0 then dD=73; dD=dD',' /*Discordian day-of-month.*/
if leapyear(gY) & gM==02 & gD==29 then do; dD=''; ds=0; end /*St. Tib's?*/
say space(day.dW',' seas.dS dD gY+1166) /*show and tell Discordian date*/
exit /*stick a fork in it, we're done.*/
/*─────────────────────────────────────LEAPYEAR subroutine──────────────*/
leapyear: procedure; arg y
if y//4\==0 then return 0 /* not ≈ by 4? Not a leapyear.*/
return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */
output when using the inputs of:
2/28/2012
2/29/2012
3/1/2012
7/22/2010
9/2/2012
12/31/2011
Prickle-Prickle, Chaos 59, 3178 Setting Orange, St. Tib's day, 3178 Setting Orange, Chaos 60, 3178 Pungenday, Confusion 57, 3176 Setting Orange, Bureaucracy 26, 3178 Setting Orange, The Aftermath 73, 3177
[edit] Ruby
require 'date'
class DiscordianDate
SEASON_NAMES = ["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"]
DAY_NAMES = ["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"]
YEAR_OFFSET = 1166
DAYS_PER_SEASON = 73
DAYS_PER_WEEK = 5
ST_TIBS_DAY_OF_YEAR = 60
def initialize(year, month, day)
gregorian_date = Date.new(year, month, day)
@day_of_year = gregorian_date.yday
@st_tibs = false
if gregorian_date.leap?
if @day_of_year == ST_TIBS_DAY_OF_YEAR
@st_tibs = true
elsif @day_of_year > ST_TIBS_DAY_OF_YEAR
@day_of_year -= 1
end
end
@season, @day = @day_of_year.divmod(DAYS_PER_SEASON)
@year = gregorian_date.year + YEAR_OFFSET
end
attr_reader :year, :day
def season
SEASON_NAMES[@season]
end
def weekday
if @st_tibs
"St. Tib's Day"
else
DAY_NAMES[(@day_of_year - 1) % DAYS_PER_WEEK]
end
end
def to_s
%Q{#{@st_tibs ? "St. Tib's Day" : "%s, %s %d" % [weekday, season, day]}, #{year} YOLD}
end
end
Testing:
[[2012, 2, 28], [2012, 2, 29], [2012, 3, 1], [2011, 10, 5]].each do |date|
dd = DiscordianDate.new(*date)
puts "#{"%4d-%02d-%02d" % date} => #{dd}"
end
Outputs:
2012-02-28 => Prickle-Prickle, Chaos 59, 3178 YOLD 2012-02-29 => St. Tib's Day, 3178 YOLD 2012-03-01 => Setting Orange, Chaos 60, 3178 YOLD 2011-10-05 => Pungenday, Bureaucracy 59, 3177 YOLD
[edit] Scala
import java.util.{GregorianCalendar, Calendar}
val DISCORDIAN_SEASONS=Array("Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath")
def ddate(year:Int, month:Int, day:Int):String={
val date=new GregorianCalendar(year, month-1, day)
val dyear=year+1166
val isLeapYear=date.isLeapYear(year)
if(isLeapYear && month==2 && day==29)
return "St. Tib's Day "+dyear+" YOLD"
var dayOfYear=date.get(Calendar.DAY_OF_YEAR)
if(isLeapYear && dayOfYear>=60)
dayOfYear-=1 // compensate for St. Tib's Day
val dday=dayOfYear%73
val season=dayOfYear/73
"%s %d, %d YOLD".format(DISCORDIAN_SEASONS(season), dday, dyear)
}
[edit] Seed7
$ include "seed7_05.s7i";
include "time.s7i";
const array string: seasons is [0] ("Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath");
const array string: weekday is [0] ("Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange");
const array string: apostle is [0] ("Mungday", "Mojoday", "Syaday", "Zaraday", "Maladay");
const array string: holiday is [0] ("Chaoflux", "Discoflux", "Confuflux", "Bureflux", "Afflux");
const func string: discordianDate (in time: date) is func
result
var string: discordianDate is "";
local
var integer: dyear is 0;
var integer: doy is 0;
var integer: dsday is 0;
begin
dyear := date.year + 1166;
if isLeapYear(date.year) and date.month = 2 and date.day = 29 then
discordianDate := "St. Tib's Day, in the YOLD " <& dyear;
else
doy := dayOfYear(date);
if isLeapYear(date.year) and doy >= 60 then
decr(doy);
end if;
dsday := doy rem 73; # season day
if dsday = 5 then
discordianDate := apostle[doy div 73] <& ", in the YOLD " <& dyear;
elsif dsday = 50 then
discordianDate := holiday[doy div 73] <& ", in the YOLD " <& dyear;
else
discordianDate := weekday[pred(doy) rem 5] <&
", day " <& dsday <&
" of " <& seasons[doy div 73] <&
" in the YOLD " <& dyear;
end if;
end if;
end func;
const proc: main is func
local
var time: today is time.value;
begin
today := time(NOW);
writeln(strDate(today) <& " as Discordian date: " <& discordianDate(today));
if discordianDate(date(2010, 7, 22)) = "Pungenday, day 57 of Confusion in the YOLD 3176" and
discordianDate(date(2012, 2, 28)) = "Prickle-Prickle, day 59 of Chaos in the YOLD 3178" and
discordianDate(date(2012, 2, 29)) = "St. Tib's Day, in the YOLD 3178" and
discordianDate(date(2012, 3, 1)) = "Setting Orange, day 60 of Chaos in the YOLD 3178" and
discordianDate(date(2010, 1, 5)) = "Mungday, in the YOLD 3176" and
discordianDate(date(2011, 5, 3)) = "Discoflux, in the YOLD 3177" then
writeln("Discordian date computation works.");
end if;
end func;
- Output:
2013-05-12 as Discordian date: Boomtime, day 59 of Discord in the YOLD 3179 Discordian date computation works.
[edit] Tcl
package require Tcl 8.5
proc disdate {year month day} {
# Get the day of the year
set now [clock scan [format %02d-%02d-%04d $day $month $year] -format %d-%m-%Y]
scan [clock format $now -format %j] %d doy
# Handle leap years
if {!($year%4) && (($year%100) || !($year%400))} {
if {$doy == 60} {
return "St. Tib's Day, [expr {$year + 1166}] YOLD"
} elseif {$doy > 60} {
incr doy -1
}
}
# Main conversion to discordian format now that special cases are handled
incr doy -1; # Allow div/mod to work right
set season [lindex {Chaos Discord Confusion Bureaucracy {The Aftermath}} \
[expr {$doy / 73}]]
set dos [expr {$doy % 73 + 1}]
incr year 1166
return "$season $dos, $year YOLD"
}
Demonstrating:
puts [disdate 2010 7 22]; # Today
puts [disdate 2012 2 28]
puts [disdate 2012 2 29]
puts [disdate 2012 3 1]
Output:
Confusion 57, 3176 YOLD Chaos 59, 3178 YOLD St. Tib's Day, 3178 YOLD Chaos 60, 3178 YOLD