Discordian date

Revision as of 16:58, 16 August 2010 by Rdm (talk | contribs) (J: bug fix)

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

Task
Discordian date
You are encouraged to solve this task according to the task description, using any language you may know.

See Also

J

<lang j>leap=: _1j1 * 0 -/@:= 4 100 400 |/ {.@] bs=: ((#:{.) + 0 j. *@[ * {:@]) +. disc=: ((1+0 73 bs[ +^:(58<]) -/@todayno@(,: 1 1,~{.)@]) ,~1166+{.@])~ leap</lang>

Example use:

<lang> disc 2012 2 29 3178 1 59j1</lang>

see talk page.

PicoLisp

Translation of: Python

<lang 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) ) ) ) ) )</lang>

Python

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

</lang>

Scala

Translation of: Python

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

}</lang>

Tcl

<lang 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"

}</lang> Demonstrating: <lang tcl>puts [disdate 2010 7 22]; # Today puts [disdate 2012 2 28] puts [disdate 2012 2 29] puts [disdate 2012 3 1]</lang> Output:

Confusion 57, 3176 YOLD
Chaos 59, 3178 YOLD
St. Tib's Day, 3178 YOLD
Chaos 60, 3178 YOLD


F#

<lang 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</lang>