Discordian date: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Haskell}}: correct for leap year)
(→‎{{header|Haskell}}: no ifthenelse + another leapyear exanple)
Line 14: Line 14:
let doy = monthAndDayToDayOfYear (isLeapYear y) m d
let doy = monthAndDayToDayOfYear (isLeapYear y) m d
(season, dday) = divMod doy 73
(season, dday) = divMod doy 73
dom = if isLeapYear y && m >2 then dday-1 else dday
dos = dday - fromEnum (isLeapYear y && m >2)
dDate
dDate
| isLeapYear y && m==2 && d==29 = "St. Tib's Day, " ++ show (y+1166) ++ " YOLD"
| isLeapYear y && m==2 && d==29 = "St. Tib's Day, " ++ show (y+1166) ++ " YOLD"
| otherwise = seasons!!season ++ " " ++ show dom ++ ", " ++ show (y+1166) ++ " YOLD"
| otherwise = seasons!!season ++ " " ++ show dos ++ ", " ++ show (y+1166) ++ " YOLD"
putStrLn dDate</lang>

putStrLn dDate
</lang>
Examples:
Examples:
<pre>*Main> mapM_ discordianDate [(2012,2,28),(2012,2,29),(2010,9,2),(2010,12,6)]
<pre>*Main> mapM_ discordianDate [(2012,2,28),(2012,2,29),(2012,3,1),(2010,9,2),(2010,12,6)]
Chaos 59, 3178 YOLD
Chaos 59, 3178 YOLD
St. Tib's Day, 3178 YOLD
St. Tib's Day, 3178 YOLD
Chaos 60, 3178 YOLD
Bureaucracy 26, 3176 YOLD
Bureaucracy 26, 3176 YOLD
The_Aftermath 48, 3176 YOLD</pre>
The_Aftermath 48, 3176 YOLD</pre>

In GHCi we can also execute shell commands.
In GHCi we can also execute shell commands.
* Using Linux utility ddate
* Using Linux utility ddate

Revision as of 18:22, 2 September 2010

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

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

See Also

Haskell

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

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

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>

PureBasic

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