Today in the YOLD

15

The Discordian calendar is an alternative calendar used by Discordians.

  1. The discordian year has 5 seasons, each lasting 73 days: Chaos, Discord, Confusion, Bureaucracy, and The Aftermath.
  2. The discordian week has 5 days: Sweetmorn, Boomtime, Pungenday, Prickle-Prickle, and Setting Orange. Every year begins with Sweetmorn (and in Chaos).
  3. Every fourth year (which happens to align with Gregorian leap years), an extra day is inserted between Chaos 59 and Chaos 60 called St. Tib's Day. It is outside of the Discordian week, meaning the day after St. Tib's Day will be Setting Orange, the day before Prickle-Prickle.
  4. The Gregorian and Discordian calendars line up; both start on the same day, which is called January 1st in the Gregorian calendar, and Chaos 1 in the Discordian one.
  5. The first Year of Our Lady of Discord (YOLD 1) was 1166 BC in the Gregorian calendar, meaning this year (2017 AD) is YOLD 3183.
  6. The Discordian calendar also has holidays, but they are not important for this challenge and you should not output them or anything about them.

Write a program or function that outputs or returns today's date (at the time of execution):

Today is Boomtime, the 16th day of Confusion in the YOLD 3183

The format is "Today is $day_of_the_week, the $ordinal day of $season in the YOLD $year", where $day_of_the_week is the capitalized (title-case) day of the week, $ordinal is the day of the season as an ordinal (1st, 2nd, 3rd, 4th, ...), $season is the capitalized (title-case) season, and $year is the year.

If your program or function is executed on St. Tib's Day, it should instead output or return "Today is St. Tib's Day in the YOLD $year".

Rules:

  • Standard loopholes apply.
  • If your language of choice has no way of getting the current date, it may also take the current Gregorian date in any reasonable format as input.
  • This is , the shortest code (per language) wins.
  • Trailing whitespace is okay.
  • Capitalization matters.
  • Calling ddate in any way is banned
  • Your program should be guaranteed to work from 3067 to 3265 YOLD (1901 to 2099 AD), outside that range it can give incorrect values

See also:

L3viathan

Posted 2017-06-11T08:05:20.817

Reputation: 3 151

4discord is a cool instant messaging client – Okx – 2017-06-11T08:14:22.490

I guess "St. Tib's Day" is not in Chaos either (i.e. the day-of-year mod 73 wont give the seasons accurately year-in-year-out)? – Jonathan Allan – 2017-06-11T08:30:23.287

@JonathanAllan Yes, St. Tib's Day is outside the seasons. – L3viathan – 2017-06-11T08:31:24.463

1I think today is 16th day of Confusion? What date does the example represent? – user202729 – 2017-06-11T08:36:12.203

2unrelated – Jonathan Allan – 2017-06-11T08:36:54.630

1@user202729 Yes, the date in the example is from when I originally wrote the challenge, I will update it to show today's date, which is indeed the 16th day of Confusion. – L3viathan – 2017-06-11T08:47:44.830

Was this sitting in the Sandbox for a while? If not, it may be a dupe; I've definitely seen this before. – Shaggy – 2017-06-11T09:21:02.787

@Shaggy It was in the Sandbox for about a month, and I looked for dupes but couldn't find any. – L3viathan – 2017-06-11T09:21:38.507

That explains it, so; I would have seen it in the Sandbox. – Shaggy – 2017-06-11T09:25:58.463

To be clear, as you require the current date, there is no need to handle gregorian years outside 1901 to 2099? The relevance of this is that turn of the century years such as 1900 and 2100 are not leap years, unless they are divisible by 400 (as 2000 was.) – Level River St – 2017-06-11T11:24:39.037

@LevelRiverSt Your code should be able to run on any date. The only exception I'm willing to make is that it doesn't need to run when your language's native date type (if any) overflows: For example, if your native date type (that you use) uses a signed 32-bit integer, then your program doesn't have to work after 18th of January 2038.

– L3viathan – 2017-06-11T11:27:31.410

1

@L3viathan in that case (for those using a language with large native type) can you clarify a) how to handle turn of the century years that aren't leap years in the gregorian cal as "every 4th year" of the discordian cal contradicts with "aligns with the gregorian" b) how to handle years before introduction of the gregorian cal. I was suggesting the max range which is properly defined by your current spec. If you reject this, you should define what the program should do outside that range. Also you should avoid invalidating the existing answer. https://en.wikipedia.org/wiki/Gregorian_calendar

– Level River St – 2017-06-11T11:53:42.450

1@LevelRiverSt The Principia is a bit unclear on that, but it fully aligns with the Gregorian calendar meaning the full leap-year rules apply. However, I don't want to invalidate the Mathematica answer (which appears to not take this into account), so I'll restrict the required range to 1901–2099.. – L3viathan – 2017-06-11T12:02:06.677

1Bash, 5 bytes: ddate. – Mark – 2017-06-11T18:37:17.780

Answers

5

Mathematica, 403 401 bytes

Version to count number of bytes: (removed spaces and newlines - unfortunately this part is quite hard)

"Setting Orange"["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle"][[#~Mod~5]]<>", the "<>SpokenString@p[[Mod[#,73,1]]]~StringExtract~2<>" day of "<>{"Chaos","Discord","Confusion","Bureaucracy","The Aftermath"}[[⌈#/73⌉]]&;
Row@{"Today is ",#2," in the YOLD ",1166+#}&[#,If[4∣#,If[#2>60,%[#2-1],If[#2<60,%@#2,"St.Tib's Day"]],%@#2]]&@@FromDigits/@DateString@"ISOOrdinalDate"~StringSplit~"-"

Version to read:

"Setting Orange"["Sweetmorn", "Boomtime", "Pungenday", 
     "Prickle-Prickle"][[#~Mod~5]] <>
   ", the " <>
   SpokenString@p[[Mod[#, 73, 1]]]~StringExtract~2 <>
   " day of " <>
   {"Chaos", "Discord", "Confusion", "Bureaucracy", 
     "The Aftermath"}[[Ceiling[#/73]]] &;
Row@{
      "Today is ",
      #2,
      " in the YOLD ",
      1166 + #
      } &[#,
   If[4 ∣ #,
    If[#2 > 60, %[#2 - 1],
     If[#2 < 60, %@#2, "St.Tib's Day"]
     ], %@#2
    ]] & @@ FromDigits /@ DateString@"ISOOrdinalDate"~StringSplit~"-"

The answer can be tested with arbitrary date by replacing DateString@"ISOOrdinalDate" by DateString[{year,month,day},"ISOOrdinalDate"] for year, month and day replaced by numbers.

user202729

Posted 2017-06-11T08:05:20.817

Reputation: 14 620

How can I test Mathematica code? – L3viathan – 2017-06-11T09:23:05.637

6"Wot no builtin?" – Jonathan Allan – 2017-06-11T10:02:44.223

4

Python 2, 423 Bytes

Short version:

import time
y,d=time.gmtime()[0::7]
t="Today is "
o=" in the YOLD "+`y+1166`
if y%4<1 and d>59:
 if d==60:print"%sSt. Tib's Day%s%d"%(t,o);quit()
 d-=1
s,e=divmod(d-1,73)
print t+["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"][(d-1)%5]+", the %d%s day of %s"%(e+1,'tsnrthtddh'[min(e*(e/10-1 and 1)%10,4)::5],["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"][s]+o)

Longer, more readable form:

import time

# now = time.strptime("2017.06.11", "%Y.%m.%d")  # for testing
now = time.gmtime()
year, day_of_year = now[0::7]
leapyear = year % 4 < 1
today = "Today is "
yold = " in the YOLD " + `y+1166`

if leapyear and day_of_year>59:
    if day_of_year==60:
        print "%sSt. Tib's Day%s%d"% (today, yold)
        quit()  # dirty, but ... hey.
    day_of_year -= 1
season, day = divmod(day_of_year-1,73)

print today + \
    ["Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"][(day_of_year-1)%5] + \
    ", the %d%s day of %s" % (
        day+1,
        'tsnrthtddh'[min(day*(day/10-1 and 1)%10,4)::5],
        ["Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"][season] + yold
    )

Update: Fixed with help of the great @Neil and @EriktheOutgolfer. But @Jonathans answer is way shorter.

jammon

Posted 2017-06-11T08:05:20.817

Reputation: 141

2Welcome on Programming Puzzles & Code Golf! – Dada – 2017-06-11T15:41:30.577

3Does this produce the right suffix for 21st, 22nd, 23rd...73rd? @L3viathan y%4<1 would work, but I don't think 1-y%4 would. – Neil – 2017-06-11T17:57:46.097

144-byte trivial golf. – Erik the Outgolfer – 2017-06-11T18:49:49.280

@EriktheOutgolfer Can't you save another 4 bytes by eliminating the e variable? – Neil – 2017-06-11T19:31:11.803

Welcome to PPCG! Nice first post. I was planning to give you a bit off here and there, but noticed and fixed the suffix problem and golfed the code more than I thought I would so I ended up submitting my own version. – Jonathan Allan – 2017-06-12T01:25:54.657

@Neil I'm afraid I can't do that. – Erik the Outgolfer – 2017-06-12T07:20:26.600

@EriktheOutgolfer Sorry, I meant the s variable... no idea why I typed e by mistake. – Neil – 2017-06-12T07:57:41.930

@Neil Hmm, it's only used once so I think I can get away without it. – Erik the Outgolfer – 2017-06-12T08:05:30.013

The suffix generation has off-by-one errors - using (e+1) in place of the two es in the max will work (and may then be golfed). – Jonathan Allan – 2017-06-12T08:50:59.543

2

JavaScript (ES6), 387 380 bytes

f=(d=new Date(),a=d.getDate()-1,y=d.getFullYear()+1166)=>d.getMonth()?f(d,a+d.getDate(d.setDate(0))):`Today is ${y%4-2|a<59||59-a--?`Sweetmorn,Boomtime,Pungenday,Prickle-Prickle,Setting Orange`.split`,`[a%5]+`, the ${d=a%73+1}${[,`st`,`nd`,`rd`][d-10-(d%=10)&&d]||`th`} day of `+`Chaos,Discord,Confusion,Bureaucracy,The Aftermath`.split`,`[a/73|0]:`St. Tib's Day`} in the YOLD `+y

Takes an optional date parameter. Ungolfed:

function discordian(date) {
    var a = date.getDate();
    while (date.getMonth()) {
        date.setDate(0);
        a += date.getDate();
    }
    if (date.getYear() % 4 == 0) {
        if (a == 60) return "Today is St. Tib's day in the YOLD " + (date.getYear() + 1166);
        if (a > 60) a--;
    }
    var weekday = ['Setting Orange', 'Sweetmorn', 'Boomtime', 'Pungenday', 'Prickle-Prickle'][a % 5];
    var seasonday = (a - 1) % 73 + 1;
    var ordinal = seasonday % 10 == 1 && seasonday != 11 ? 'st' : seasonday % 10 == 2 && seasonday != '12' : 'nd' : seasonday % 10 == 3 && seasonday != '13' ? 'rd' : 'th';
    var season = ['Chaos', 'Discord', 'Confusion', 'Bureaucracy', 'The Aftermath'][Math.floor((a - 1) / 73)];
    return "Today is " + weekday + ", the " + seasonday + ordinal + " day of " + season + " in the YOLD " + (date.getYear() + 1166);
}

Neil

Posted 2017-06-11T08:05:20.817

Reputation: 95 035

2

Python 2, 346 bytes

Note: This is a golf (and fix) of jammon's answer - I originally thought I'd submit a comment, but I changed quite a bit in the end (plus the day-suffixes have been fixed).

import time
y,d=time.gmtime()[::7]
t="Today is %s in the YOLD "+`y+1166`
r=y%4<1<59<d
d-=r+1
e=d%73
print t%[["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"][d%5]+", the %d%s day of "%(e+1,'snrttddh'[min(e%10+3*(e/9==1),3)::4])+["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"][d/73],"St. Tib's Day"][(r*d)==58]

Try it online! or see some hard-coded test dates.

Jonathan Allan

Posted 2017-06-11T08:05:20.817

Reputation: 67 804

I don't suppose e%10*(e/9!=1) works? – Neil – 2017-06-12T08:00:26.947

Nope, then it would print 11st, 12st and 13st (when e/9 is 1 it would multiply by zero and the min would pick that zero) – Jonathan Allan – 2017-06-12T08:05:50.830

1

C#, 392 bytes

using System;s=>{var t=DateTime.Now;int d=t.DayOfYear,y=t.Year,m=d%73;return"Today is "+(DateTime.IsLeapYear(y)&d==60?"St. Tib's Day":"Sweetmorn|Boomtime|Pungenday|Prickle-Prickle|Setting Orange".Split('|')[d%5-1]+", the "+ m+(m<2|m==21|m>30?"st":m==2|m==22?"nd":m==3|m==23?"rd":"th")+" day of "+"Chaos|Discord|Confusion|Bureaucracy|The Aftermath".Split('|')[d/73])+" in the YOLD "+(y+1166);}

Full/Formatted version:

using System;

class P
{
    static void Main()
    {
        Func<string, string> f = s =>
        {
            var t = DateTime.Now;
            int d = t.DayOfYear, y = t.Year, m = d % 73;

            return "Today is " + (DateTime.IsLeapYear(y) & d == 60
                   ? "St. Tib's Day"
                   : "Sweetmorn|Boomtime|Pungenday|Prickle-Prickle|Setting Orange".Split('|')[d % 5 - 1] +
                     ", the " +
                     m +
                     (m < 2 | m == 21 | m > 30 ? "st" : m == 2 | m == 22 ? "nd" : m == 3 | m == 23 ? "rd" : "th") +
                     " day of " +
                     "Chaos|Discord|Confusion|Bureaucracy|The Aftermath".Split('|')[d / 73])
                   + " in the YOLD " + (y + 1166);
        };

        Console.WriteLine(f(null));

        Console.ReadLine();
    }
}

TheLethalCoder

Posted 2017-06-11T08:05:20.817

Reputation: 6 930

1

Pyth, 295 bytes

J.d2A<J2Kt+s<+,31 28*2t*3,30 31tH@J2=Y&&!%G4<58K!qH3=N%K73%"Today is %s in the YOLD %d",@,++@c"SweetmornZBoomtimeZPungendayZPrickle-PrickleZSetting Orange"\Z%K5%", the %d%s day of ",+N1@c"stndrdth"2h.mb,3+%NT*3q1/N9@c." yNlSFk.»&ô?Z#u!%ô6'mçM«_ôvëû¹)+¬<"\Z/K73"St. Tib's Day"q*YK59+G1166

Note: contains binary, may not be safe to copy-paste from here. Copy-pasting from TIO should work.

Try it online!

You can test arbitrary dates by replacing .d2 at the start with a 3-tuple of (year, month, day) like this: (2020 2 29).

This one was a bit annoying since Pyth doesn't have any way to get "day of year" so I had to compute it myself.

randomdude999

Posted 2017-06-11T08:05:20.817

Reputation: 789