Discordian date: Difference between revisions
(→{{header|Haskell}}: remove module import) |
(→{{header|Haskell}}: correct for leap year) |
||
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 |
|||
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 |
| otherwise = seasons!!season ++ " " ++ show dom ++ ", " ++ show (y+1166) ++ " YOLD" |
||
putStrLn dDate |
putStrLn dDate |
||
</lang> |
</lang> |
Revision as of 14:42, 2 September 2010
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 dom = if isLeapYear y && m >2 then dday-1 else dday dDate
| isLeapYear y && m==2 && d==29 = "St. Tib's Day, " ++ show (y+1166) ++ " YOLD" | otherwise = seasons!!season ++ " " ++ show dom ++ ", " ++ show (y+1166) ++ " YOLD"
putStrLn dDate
</lang> Examples:
*Main> mapM_ discordianDate [(2012,2,28),(2012,2,29),(2010,9,2),(2010,12,6)] Chaos 59, 3178 YOLD St. Tib's Day, 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
<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
<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>