Doomsday rule: Difference between revisions

Add C# implementation
(Added Algol 68 and fixed Algol W type and changed extra test case)
(Add C# implementation)
 
(29 intermediate revisions by 17 users not shown)
Line 1:
{{draft task}}
 
[[Category:Date and time]]
 
Line 64 ⟶ 65:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F isleap(year)
R year % 4 == 0 & (year % 100 != 0 | year % 400 == 0)
 
Line 85 ⟶ 86:
L(year, month, day) [(1800, 1, 6), (1875, 3, 29), (1915, 12, 7),
(1970, 12, 23), (2043, 5, 14), (2077, 2, 12), (2101, 4, 2)]
print(‘#.-#02-#02 -> #.’.format(year, month, day, weekday(year, month, day)))</langsyntaxhighlight>
 
{{out}}
Line 99 ⟶ 100:
 
=={{header|ALGOL 68}}==
{{TRansTrans|ALGOL W}}
<langsyntaxhighlight lang="algol68">BEGIN # find the day of the week of dates using John Conway's Doomsday rule #
# returns the day of the week (Sunday = 0, Monday = 1,...) for the date #
# specified by ccyy, mm and dd #
Line 146 ⟶ 147:
test dow( 2022, 6, 19 )
END
END</langsyntaxhighlight>
{{out}}
<pre>
Line 160 ⟶ 161:
 
=={{header|ALGOL W}}==
<langsyntaxhighlight lang="algolw">begin % find the day of the week of dates using John Conway's Doomsday rule %
% returns the day of the week (Sunday = 0, Monday = 1,...) for the date %
% specified by ccyy, mm and dd %
Line 202 ⟶ 203:
testDow( 2022, 6, 19 )
end
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 217 ⟶ 218:
=={{header|APL}}==
{{works with|Dyalog APL}}
<langsyntaxhighlight lang="apl">weekday←{⎕IO←1
days←'Sunday' 'Monday' 'Tuesday' 'Wednesday' 'Thursday' 'Friday' 'Saturday'
leap←4 7∊⍨2⊥0=4 100 400∘|
Line 229 ⟶ 230:
anchor←m⊃(1+leap y)⊃nd ld
(1+7|7+doom+d-anchor)⊃days
}</langsyntaxhighlight>
{{out}}
<pre> weekday 1800 1 6
Line 245 ⟶ 246:
weekday 2101 4 2
Saturday</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">on dayOfWeek(yyyymmdd)
tell yyyymmdd to set {y, m, d} to {word 1 as integer, word 2 as integer, word 3 as integer}
set doomsdayForYear to (y + y div 4 - y div 100 + y div 400 + 2) -- (mod 7 further down anyway)
if ((m < 3) and ((y mod 4 = 0) and (y mod 100 > 0) or (y mod 400 = 0))) then set m to m + 12
set doomsdayInMonth to item m of {3, 28, 7, 4, 2, 6, 4, 8, 5, 10, 7, 12, 4, 29}
return item ((doomsdayForYear + d - doomsdayInMonth + 28) mod 7 + 1) of ¬
{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
end dayOfWeek
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
on task()
set dateStrings to {"1800-01-06", "1875-03-29", "1915-12-07", "1970-12-23", "2043-05-14", "2077-02-12", "2101-04-02"}
set output to {}
repeat with yyyymmdd in dateStrings
set end of output to yyyymmdd & " --> " & dayOfWeek(yyyymmdd)
end repeat
return join(output, linefeed)
end task
 
task()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"1800-01-06 --> Monday
1875-03-29 --> Monday
1915-12-07 --> Tuesday
1970-12-23 --> Wednesday
2043-05-14 --> Thursday
2077-02-12 --> Friday
2101-04-02 --> Saturday"</syntaxhighlight>
 
=={{header|BASIC}}==
Note that 1/6/1800 is actually a Monday, not a Sunday. As far as I can tell this is actually the correct day.
 
<langsyntaxhighlight BASIClang="basic">10 DIM D$(7): FOR I=1 TO 7: READ D$(I): NEXT I
20 DIM D(12,1): FOR I=0 TO 1: FOR J=1 TO 12: READ D(J,I): NEXT J,I
30 READ Y: IF Y=0 THEN END ELSE READ M,D
Line 263 ⟶ 303:
130 DATA 4,1,7,4,2,6,4,1,5,3,7,5
140 DATA 1800,1,6, 1875,3,29, 1915,12,7, 1970,12,23
150 DATA 2043,5,14, 2077,2,12, 2101,4,2, 0</langsyntaxhighlight>
{{out}}
<pre> 1/ 6/1800: Monday
Line 276 ⟶ 316:
Note that 1/6/1800 is actually a Monday, not a Sunday. As far as I can tell this is actually the correct day.
 
<langsyntaxhighlight lang="bcpl">get "libhdr"
 
let dayname(n) =
Line 312 ⟶ 352:
writef("February 12, 2077 will be on a %S.*N", dayname(weekday(2077, 2, 12)))
writef("April 2, 2101 will be on a %S.*N", dayname(weekday(2101, 4, 2)))
$)</langsyntaxhighlight>
{{out}}
<pre>January 6, 1800 was on a Monday.
Line 325 ⟶ 365:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
Line 377 ⟶ 417:
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>January 6, 1800 was on a Monday.
Line 386 ⟶ 426:
February 12, 2077 will be on a Friday.
April 2, 2101 will be on a Saturday.</pre>
 
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
 
class Doom {
public static void Main(string[] args) {
Date[] dates = {
new Date(1800,1,6),
new Date(1875,3,29),
new Date(1915,12,7),
new Date(1970,12,23),
new Date(2043,5,14),
new Date(2077,2,12),
new Date(2101,4,2)
};
foreach (Date d in dates)
Console.WriteLine($"{d.Format()}: {d.Weekday()}");
}
}
 
class Date {
private int year, month, day;
private static readonly int[] leapDoom = {4,1,7,4,2,6,4,1,5,3,7,5};
private static readonly int[] normDoom = {3,7,7,4,2,6,4,1,5,3,7,5};
public static readonly string[] weekdays = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public bool IsLeapYear() {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
public string Format() {
return $"{month:00}/{day:00}/{year:0000}";
}
public string Weekday() {
int c = year / 100;
int r = year % 100;
int s = r / 12;
int t = r % 12;
int cAnchor = (5 * (c % 4) + 2) % 7;
int doom = (s + t + t / 4 + cAnchor) % 7;
int anchor =
IsLeapYear() ? leapDoom[month - 1] : normDoom[month - 1];
return weekdays[(doom + day - anchor + 7) % 7];
}
}
</syntaxhighlight>
{{out}}
<pre>
01/06/1800: Monday
03/29/1875: Monday
12/07/1915: Tuesday
12/23/1970: Wednesday
05/14/2043: Thursday
02/12/2077: Friday
04/02/2101: Saturday
 
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <cstdint>
 
Line 437 ⟶ 551:
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>January 6, 1800 was on a Monday
Line 448 ⟶ 562:
 
=={{header|CLU}}==
<langsyntaxhighlight lang="clu">leap_year = proc (year: int) returns (bool)
return(year//4=0 & (year//100=0 | year//400=0))
end leap_year
Line 494 ⟶ 608:
stream$putl(po, weekday(d))
end
end start_up</langsyntaxhighlight>
{{out}}
<pre>1 June 1800 was on a Sunday
Line 505 ⟶ 619:
 
=={{header|Cowgol}}==
<langsyntaxhighlight lang="cowgol">include "cowgol.coh";
 
record Date is
Line 557 ⟶ 671:
print_date(&dates[i]);
i := i + 1;
end loop;</langsyntaxhighlight>
{{out}}
<pre>1/6/1800: Monday
Line 566 ⟶ 680:
2/12/2077: Friday
4/2/2101: Saturday</pre>
 
=={{header|EasyLang}}==
{{trans|C}}
<syntaxhighlight>
func leap year .
return if year mod 4 = 0 and (year mod 100 <> 0 or year mod 400 = 0)
.
func weekday year month day .
normdoom[] = [ 3 7 7 4 2 6 4 1 5 3 7 5 ]
c = year div 100
r = year mod 100
s = r div 12
t = r mod 12
c_anchor = (5 * (c mod 4) + 2) mod 7
doom = (s + t + (t div 4) + c_anchor) mod 7
anchor = normdoom[month]
if leap year = 1 and month <= 2
anchor = (anchor + 1) mod1 7
.
return (doom + day - anchor + 7) mod 7 + 1
.
wkdays$[] = [ "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" ]
dates$[] = [ "1800-01-06" "1875-03-29" "1915-12-07" "1970-12-23" "2043-05-14" "2077-02-12" "2101-04-02" ]
for d$ in dates$[]
write d$ & " -> "
a[] = number strsplit d$ "-"
print wkdays$[weekday a[1] a[2] a[3]]
.
</syntaxhighlight>
 
=={{header|Factor}}==
{{works with|Factor|0.99 2021-02-05}}
<langsyntaxhighlight lang="factor">USING: accessors calendar calendar.english formatting
generalizations kernel math math.order math.vectors sequences ;
 
Line 601 ⟶ 744:
2077 2 12
2101 4 2
[ <date> test ] 3 7 mnapply</langsyntaxhighlight>
{{out}}
<pre>
Line 614 ⟶ 757:
 
=={{header|FOCAL}}==
<langsyntaxhighlight lang="focal">01.10 S X(1)=3;S X(2)=7;S X(3)=7;S X(4)=4;S X(5)=2;S X(6)=6
01.15 S X(7)=4;S X(8)=1;S X(9)=5;S X(10)=3;S X(11)=7;S X(12)=5
01.20 S Y=1800;S M= 1;S D= 6;D 2;D 3
Line 651 ⟶ 794:
04.50 I (E-2)4.6;T "TUESDAY";R
04.60 I (E-1)4.7;T "MONDAY";R
04.70 T "SUNDAY"</langsyntaxhighlight>
{{out}}
<pre>M= 1 D= 6 Y= 1800 DAY=MONDAY
Line 660 ⟶ 803:
M= 2 D= 12 Y= 2077 DAY=FRIDAY
M= 4 D= 2 Y= 2101 DAY=SATURDAY</pre>
 
=={{header|Fortran}}==
<syntaxhighlight lang="FORTRAN">
program someday ! Calculates the day that a week falls on
use datestuff
implicit none
!
! PARAMETER definitions
!
integer , parameter :: numdates = 7
!
! Local variable declarations
!
character(30) , dimension(numdates) , save :: date_string
integer , dimension(numdates) , save :: day
character(9) , dimension(numdates) , save :: days
integer :: j
integer :: k
integer , dimension(numdates) , save :: month
integer , dimension(numdates) , save :: year
!
data days/'Monday ' , 'Tuesday ' , 'Wednesday' , 'Thursday ' , &
&'Friday ' , 'Saturday ' , 'Sunday '/
data month/01 , 03 , 12 , 12 , 05 , 02 , 04/
data day/06 , 29 , 07 , 23 , 14 , 12 , 02/
data year/1800 , 1875 , 1915 , 1970 , 2043 , 2077 , 2101/
data date_string/'1800-01-06 (January 6, 1800)' , &
&'1875-03-29 (March 29, 1875)' , '1915-12-07 (December 7, 1915)' ,&
&'1970-12-23 (December 23, 1970)' , '2043-05-14 (May 14, 2043)' , &
&'2077-02-12 (February 12, 2077)' , '2101-04-02 (April 2, 2101)'/ !
!*Code
 
print *
do j = 1 , numdates
k = get_the_day(day(j) , month(j) , year(j))
print '(a, t31,1a1,1x,a)' , date_string(j) , ':' , days(k)
end do
end program someday
module datestuff
implicit none
public :: get_the_day
private :: get_anchor_day , gregorian_leap_year
!
enum , bind(c) ! Use enums to get greater clarity in the code
enumerator :: january = 1 , february , march , april , may , &
& june , july , august , september , october , november ,&
& december
end enum
enum , bind(c)
enumerator :: sunday = 0 , monday , tuesday , wednesday , &
& thursday , friday , saturday
end enum
contains
!
pure function gregorian_leap_year(year) result(answer) ! Tests if the year is a leap year
!
! Function and Dummy argument declarations
!
logical :: answer
integer , intent(in) :: year
!
answer = .false. ! Set default to not a leap year
if( mod(year , 4)==0 )answer = .true. ! Year divisible by 4 = leap year
if( mod(year , 100)==0 )then
if( mod(year , 400)==0 )then ! Year divisible by 400 = century year that is leap year
answer = .true.
else
answer = .false. ! Century years are not leap years
end if
end if
end function gregorian_leap_year
!
pure function get_anchor_day(year) result(answer) ! Returns Anchor Days in doomsday calculation
!Note: The days start as Monday = 1, Tuesday =2, etc until Sunday = 7
!The Doomsday rule, Doomsday algorithm or Doomsday method is an algorithm of determination of the day of the week for a given date.
!It provides a perpetual calendar because the Gregorian calendar moves in cycles of 400 years.
!It takes advantage of each year having a certain day of the week upon which certain easy-to-remember dates,
!called the doomsdays, fall; for example, the last day of February, 4/4, 6/6, 8/8, 10/10, and 12/12 all occur
! on the same day of the week in any year. Applying the Doomsday algorithm involves three steps: Determination of the anchor day
! for the century, calculation of the anchor day for the year from the one for the century, and selection of the closest date
! out of those that always fall on the doomsday, e.g., 4/4 and 6/6, and count of the number of days (modulo 7) between that
! date and the date in question to arrive at the day of the week. The technique applies to both the Gregorian calendar and the
! Julian calendar, although their doomsdays are usually different days of the week.
!
! Function and Dummy argument declarations
!
integer :: answer
integer , intent(in) :: year
!
! Local variable declarations
!
integer :: diffyear
integer :: div12
integer :: numyears
integer :: temp1
!
! End of declarations
!*Code
numyears = mod(year , 100) ! Get number of years greater than century
 
temp1 = year - numyears ! Turn into a century year
temp1 = mod(temp1 , 400) ! Now mod 400 to get base year for anchor day
select case(temp1) ! Select the base day
case(0)
answer = tuesday
case(100)
answer = sunday
case(200)
answer = friday
case(300)
answer = wednesday
case default ! Anything else is an error
ERROR Stop 'Bad Anchor Day' ! Finish with error
end select
!
!Calculate the doomsday of any given year
!
div12 = int(numyears/12) ! Get number of times 12 goes into year
temp1 = mod(numyears , 12) ! Get the remainer
diffyear = int(temp1/4) ! Div 4 (magic algorithm)
answer = diffyear + div12 + answer + temp1
answer = mod(answer , 7)
end function get_anchor_day ! Note: The days start as Sunday = 0, Monday = 1, Tuesday =2, etc until Saturda
!
pure function get_the_day(day , month , year) result(answer)
! Note: The days start as Sunday = 0, Monday = 1, Tuesday =2, etc until Saturday = 6
!
! Function and Dummy argument declarations
integer :: answer
integer , intent(in) :: day
integer , intent(in) :: month
integer , intent(in) :: year
!
! Local variable declarations
integer :: closest
integer :: doomsday
integer :: temp1
integer :: temp2
integer :: up_or_down
!
! End of declarations
!
! There are doomsdays in every month, so we know what month it is ...
! We need to find the doomsday in the relevant month
select case(month) ! Scratch Variables
case(january)
closest = merge(4,3,gregorian_leap_year(year)) ! Use merge as a ternary
case(february)
closest = merge(29,28,gregorian_leap_year(year)) ! Use merge as a ternary
case(march)
closest = 7
case(april)
closest = 4
case(may)
closest = 9
case(june)
closest = 6
case(july)
temp1 = abs(4 - day)
temp2 = abs(11 - day)
closest = merge(4,11,temp1<temp2) ! Use merge as a ternary
case(august)
closest = 8
case(september)
closest = 5
case(october)
temp1 = abs(10 - day)
temp2 = abs(31 - day)
closest = merge(10,31,temp1<temp2) ! Use merge as a ternary
case(november)
closest = 7
case(december)
closest = 12
case default
ERROR Stop 'Error in get the day' ! Stop on error
end select
!
! Ok now we get the doomsday in question - i.e. Monday, Tuesday for this year
doomsday = get_anchor_day(year) ! Get this years doomsday
! If closest day is less we need to count down, if it is bigger we count up
 
if( closest>day )then
up_or_down = -7
else if( closest<day )then
up_or_down = 7
else
up_or_down = 0 ! The days are equal. Set to zero so no counting needed
end if
temp1 = closest ! Set temp var to closest doomsday
if( up_or_down>0 )then
do while ( temp1<=day )
temp2 = temp1
temp1 = temp1 + up_or_down ! Count in sevens to the final
end do
temp1 = day - temp2
temp1 = (doomsday + 7) + temp1
else if( up_or_down<0 )then
do while ( temp1>=day )
temp2 = temp1
temp1 = temp1 + up_or_down ! Count in sevens to the final
end do
temp1 = temp2 - day ! See how far away I am from this day
temp1 = (doomsday + 7) - temp1 ! Subtract the difference in days from the known doomsday
else
temp1 = doomsday ! It fell on the doomsday
end if
answer = mod(temp1 , 7) ! Turn Sundays into Zeros
end function get_the_day
!
end module datestuff
!
</syntaxhighlight>
{{out}}
<pre>
1800-01-06 (January 6, 1800) : Monday
1875-03-29 (March 29, 1875) : Monday
1915-12-07 (December 7, 1915) : Tuesday
1970-12-23 (December 23, 1970): Wednesday
2043-05-14 (May 14, 2043) : Thursday
2077-02-12 (February 12, 2077): Friday
2101-04-02 (April 2, 2101) : Saturday
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">dim shared as ubyte fdoom(0 to 1, 1 to 12) = {_
{ 3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5 }, _
{ 4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5 } } 'the first doomsday in
Line 696 ⟶ 1,061:
print get_day( 2043, 05, 14 )
print get_day( 2077, 02, 12 )
print get_day( 2101, 04, 02 )</langsyntaxhighlight>
{{out}}
<pre>Monday
Line 705 ⟶ 1,070:
Friday
Saturday</pre>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn IsLeapYear( year as NSUInteger ) as BOOL
BOOL result = YES
if ( year mod 4 > 0 ) then result = NO : exit fn
if ( year mod 100 = 0 ) and ( year mod 400 > 0 ) then result = NO : exit fn
end fn = result
 
local fn DoomsdayWeekdayForDate( month as NSUInteger, day as NSUInteger, year as NSUInteger ) as CFStringRef
CFArrayRef weekdayNames = @[@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"]
CFArrayRef normalYearDays = @[@4, @1, @7, @4, @2, @6, @4, @1, @5, @3, @7, @5]
CFArrayRef leapYearDays = @[@3, @7, @7, @4, @2, @6, @4, @1, @5, @3, @7, @5]
CFStringRef dayOfWeek = @""
NSUInteger anchorday
NSUInteger doomsday = ( 2 + 5 * ( year mod 4 ) + 4 * ( year mod 100 ) + 6 * ( year mod 400) ) mod 7
if ( fn IsLeapYear( year ) ) then anchorday = intVal( normalYearDays[month-1] ) else anchorday = intVal( leapYearDays[month-1] )
NSUInteger weekday = ( doomsday + day - anchorday + 7 ) mod 7
if ( weekday == 0 ) then dayOfWeek = @"Sunday" else dayOfWeek = weekdayNames[weekday]
end fn = dayOfWeek
 
printf @"01-06-1800 : %@", fn DoomsdayWeekdayForDate( 1, 6, 1800 )
printf @"03-29-1875 : %@", fn DoomsdayWeekdayForDate( 3, 29, 1875 )
printf @"12-07-1915 : %@", fn DoomsdayWeekdayForDate( 12, 7, 1915 )
printf @"12-23-1970 : %@", fn DoomsdayWeekdayForDate( 12, 23, 1970 )
printf @"05-14-2043 : %@", fn DoomsdayWeekdayForDate( 5, 14, 2043 )
printf @"02-12-2077 : %@", fn DoomsdayWeekdayForDate( 2, 12, 2077 )
printf @"04-02-2101 : %@", fn DoomsdayWeekdayForDate( 4, 2, 2101 )
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
01-06-1800 : Monday
03-29-1875 : Monday
12-07-1915 : Tuesday
12-23-1970 : Wednesday
05-14-2043 : Thursday
02-12-2077 : Friday
04-02-2101 : Saturday
</pre>
 
 
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 755 ⟶ 1,164:
fmt.Printf("%s -> %s\n", date, days[dow])
}
}</langsyntaxhighlight>
 
{{out}}
Line 770 ⟶ 1,179:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Text.Printf
 
data Date = Date {year :: Int, month :: Int, day :: Int}
Line 813 ⟶ 1,222:
 
main :: IO ()
main = putStr $ unlines $ map dateAndDay dates</langsyntaxhighlight>
{{out}}
<pre>1800-01-06: Monday
Line 822 ⟶ 1,231:
2077-02-12: Friday
2101-04-02: Saturday</pre>
 
=={{header|J}}==
 
To find the doomsday for a month, find the number of days for each month in that year, and compute the running sum from right to left. Then add 1 to each of those numbers, find the mod 7 remainder and add 1 again
<syntaxhighlight lang="j"> 1+7|1++/\.31 28 31 30 31 30 31 31 30 31 30 31
3 7 7 4 2 6 4 1 5 3 7 5
1+7|1++/\.31 29 31 30 31 30 31 31 30 31 30 31
4 1 7 4 2 6 4 1 5 3 7 5</syntaxhighlight>
 
Also note that adding 7 is like adding 0 in modulo 7 arithmetic.
 
Thus:
 
<syntaxhighlight lang="j">get_weekday=: {{ 'Y M D'=. y
Y0=. todayno Y,1 1
Y1=. todayno 1+Y,0 0
aday=. M{_,1+7|1++/\.>.//./}.|:todate Y0+i.Y1-Y0
dday=. 7|2 5 4 6+/ .*1,4 100 400|/Y
'day',~;(7|D+dday-aday){;:'Sun Mon Tues Wednes Thurs Fri Satur'
}}</syntaxhighlight>
 
That said, it's more concise to look up these anchor days. We can use the nonleap year sequence and adjust january and february's values for leap years by adding 1 or 2 (under 1 offset 7 modulo arithmetic).
 
<syntaxhighlight lang="j">get_weekday=: {{ 'Y M D'=. y
leap=. 0~:/ .=4 100 400|/Y
aday=. 1+7|(M*leap*3>M)+M{_ 2 6 6 3 1 5 3 0 4 2 6 4
dday=. 7|2 5 4 6+/ .*1,4 100 400|/Y
'day',~;(7|D+dday-aday){;:'Sun Mon Tues Wednes Thurs Fri Satur'
}}</syntaxhighlight>
 
These two implementations produce equivalent results.
 
Task examples:
 
<syntaxhighlight lang="j"> get_weekday 1800 1 6
Monday
get_weekday 1875 3 29
Monday
get_weekday 1915 12 7
Tuesday
get_weekday 1970 12 23
Wednesday
get_weekday 2043 5 14
Thursday
get_weekday 2077 2 12
Friday
get_weekday 2101 4 2
Saturday</syntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">class Doom {
public static void main(String[] args) {
final Date[] dates = {
Line 879 ⟶ 1,336:
return weekdays[(doom + day - anchor + 7) % 7];
}
}</langsyntaxhighlight>
{{out}}
<pre>01/06/1800: Monday
Line 895 ⟶ 1,352:
 
Note that the assertions as defined here are only checked if the environment variable JQ_ASSERT is set.
<syntaxhighlight lang="jq">
<lang jq>
def weekdaynames: ["Sunday", "Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
 
Line 934 ⟶ 1,391:
("February 12, 2077 will be on a "+ get_weekday(2077; 2; 12)),
("April 2, 2101 will be on a " + get_weekday(2101; 4; 2)),
("April 2, 21011 will be on a " + get_weekday(21011; 4; 2))</langsyntaxhighlight>
{{out}}
<pre>
Line 948 ⟶ 1,405:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">module DoomsdayRule
export get_weekday
 
Line 987 ⟶ 1,444:
println("February 12, 2077 will be on a ", get_weekday(2077, 2, 12))
println("April 2, 2101 will be on a ", get_weekday(2101, 4, 2))
</langsyntaxhighlight>{{out}}
<pre>
January 6, 1800 was on a Monday
Line 1,002 ⟶ 1,459:
We use also the “WeekDay” type of this module which is an enumeration starting with “dMon” for Monday and ending with “dSun” for Sunday.
 
<langsyntaxhighlight Nimlang="nim">import strformat, times
 
const
Line 1,023 ⟶ 1,480:
echo &"For {date}, expected {dt.weekday}, found {wday}."
else:
echo date, " → ", wday</langsyntaxhighlight>
 
{{out}}
Line 1,036 ⟶ 1,493:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl"># 20210602 Perl programming solution
 
use strict;
Line 1,056 ⟶ 1,513:
for (qw( 1800-01-06 1875-03-29 1915-12-07 1970-12-23 2043-05-14 2077-02-12 2101-04-02 )) {
print $_, " is a : ", dow $_, "\n";
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,069 ⟶ 1,526:
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 1,107 ⟶ 1,564:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n%-30s (%d = %d ? %s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bis</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">drd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ok</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,127 ⟶ 1,584:
 
=={{header|PL/M}}==
<langsyntaxhighlight lang="plm">100H:
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
Line 1,208 ⟶ 1,665:
END;
CALL EXIT;
EOF</langsyntaxhighlight>
{{out}}
<pre>1/6/1800: MONDAY
Line 1,219 ⟶ 1,676:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from datetime import date
from calendar import isleap
 
Line 1,247 ⟶ 1,704:
for d in dates:
tense = "was" if d < date.today() else "is" if d == date.today() else "will be"
print("{} {} a {}".format(d.strftime("%B %d, %Y"), tense, weekday(d)))</langsyntaxhighlight>
{{out}}
<pre>January 06, 1800 was a Monday
Line 1,259 ⟶ 1,716:
=={{header|Raku}}==
 
<syntaxhighlight lang="raku" perl6line>my @dow = < Sunday Monday Tuesday Wednesday Thursday Friday Saturday >;
 
my %doomsday = False => [3,7,7,4,2,6,4,1,5,3,7,5], True => [4,1,7,4,2,6,4,1,5,3,7,5];
Line 1,283 ⟶ 1,740:
say "Builtin - $_ is a: ", @dow[Date.new($_).day-of-week];
say '';
}</langsyntaxhighlight>
{{out}}
<pre>Conway - 1800-01-06 is a: Monday
Line 1,308 ⟶ 1,765:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program finds the day─of─week for a specified date using Conway's Doomsday rule. */
parse arg $ /*obtain optional arguments from the CL*/
if $='' | $="," then $= , /*Not specified? Then use the default.*/
Line 1,325 ⟶ 1,782:
/*──────────────────────────────────────────────────────────────────────────────────────*/
doomsday: parse arg ?; return (2 + 5 * (?//4) + 4 * (?//100) + 6 * (?//400) ) // 7
leapyear: arg #; ly= #//4==0; if ly==0 then return 0; return ((#//100\==0) | #//400==0)</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 1,335 ⟶ 1,792:
04/02/2077 falls on Friday
04/02/2101 falls on Saturday
</pre>
 
=={{header|RPL}}==
{{works with|HP|48G}}
« IP LASTARG FP 100 * IP LASTARG FP 10000 *
→ d m y
« y DUP 100 MOD 4 400 IFTE MOD
{ 3 7 } { 4 1 } IFTE { 7 4 2 6 4 1 5 3 7 5 } + +
m GET d SWAP - 7 MOD
2 5 y 4 MOD * + 4 y 100 MOD * + 6 y 400 MOD * + 7 MOD
+ 7 MOD
{ "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Satursday" }
SWAP 1 + GET
» » '<span style="color:blue">WKDAY</span>' STO
 
{ 6.011800 29.031875 7.121915 23.12197 14.052043 12.022077 2.042101 } 1 « <span style="color:blue">WKDAY</span> » DOLIST
{{out}}
<pre>
1: { "Monday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Satursday" }
</pre>
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">fn day_of_week(year: u32, month: u32, day: u32) -> u32 {
const LEAPYEAR_FIRSTDOOMSDAYS: [u32; 12] = [4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5];
const NONLEAPYEAR_FIRSTDOOMSDAYS: [u32; 12] = [3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5];
Line 1,380 ⟶ 1,856:
print_day_of_week(2077, 2, 12);
print_day_of_week(2101, 4, 2);
}</langsyntaxhighlight>
 
{{out}}
Line 1,391 ⟶ 1,867:
2077-02-12: Friday
2101-04-02: Saturday
</pre>
 
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="Scala">
object Doom extends App {
val dates = Array(
new Date(1800, 1, 6),
new Date(1875, 3, 29),
new Date(1915, 12, 7),
new Date(1970, 12, 23),
new Date(2043, 5, 14),
new Date(2077, 2, 12),
new Date(2101, 4, 2)
)
 
dates.foreach(d => println(s"${d.format}: ${d.weekday}"))
}
 
class Date(val year: Int, val month: Int, val day: Int) {
import Date._
 
def isLeapYear: Boolean = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
 
def format: String = f"$month%02d/$day%02d/$year%04d"
 
def weekday: String = {
val c = year / 100
val r = year % 100
val s = r / 12
val t = r % 12
 
val cAnchor = (5 * (c % 4) + 2) % 7
val doom = (s + t + t / 4 + cAnchor) % 7
val anchor = if (isLeapYear) leapdoom(month - 1) else normdoom(month - 1)
 
weekdays((doom + day - anchor + 7) % 7)
}
}
 
object Date {
private val leapdoom = Array(4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5)
private val normdoom = Array(3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5)
val weekdays = Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
}
</syntaxhighlight>
{{out}}
<pre>
01/06/1800: Monday
03/29/1875: Monday
12/07/1915: Tuesday
12/23/1970: Wednesday
05/14/2043: Thursday
02/12/2077: Friday
04/02/2101: Saturday
 
</pre>
 
=={{header|uBasic/4tH}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="uBasic/4tH">Dim @f(24)
Push 3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5 ' the first doomsday in each
Push 4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5 ' month for common and leap years
For x = 23 to 0 Step -1 : @f(x) = Pop() : Next
Dim @d(7)
Push "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
For x = 6 To 0 Step -1 : @d(x) = Pop() : Next
 
Print Show(FUNC(_get_day(1800, 01, 06)))
Print Show(FUNC(_get_day(1875, 03, 29)))
Print Show(FUNC(_get_day(1915, 12, 07)))
Print Show(FUNC(_get_day(1970, 12, 23)))
Print Show(FUNC(_get_day(2043, 05, 14)))
Print Show(FUNC(_get_day(2077, 02, 12)))
Print Show(FUNC(_get_day(2101, 04, 02)))
 
End
 
_doomsday ' John Conway's doomsday formula
Param (1) : Return ((2 + 5*(a@ % 4) + 4*(a@ % 100) + 6*(a@ % 400)) % 7)
_leap ' is it a leap year?
Param (1)
If (a@ % 4 > 0) Then Return (0) ' return 0 for common years
If (a@ % 100 = 0) * (a@ % 400 > 0) Then Return (0)
Return (1) ' 1 for leap years
 
_get_day
Param (3)
Local (2)
 
d@ = FUNC(_doomsday(a@))
e@ = (7 + c@ - @f(FUNC(_leap(a@)) * 2 + (b@-1))) % 7
Return (@d((d@+e@) % 7))</syntaxhighlight>
{{Out}}
<pre>Monday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
 
0 OK, 0:711</pre>
 
=={{header|UNIX Shell}}==
{{trans|raku}}
{{works with|Bash}}
<syntaxhighlight lang=bash>#!/usr/bin/env bash
 
day-of-the-week()
if [[ "$1" =~ ([0-9]{4})-([0-9]{2})-([0-9]{2}) ]]
then
local -ra names=({Sun,Mon,Tues,Wednes,Thurs,Fri,Satur}day) doomsday=({37,41}7426415375)
local -i i c s t a b
local -i {year,month,day}=${BASH_REMATCH[++i]}
echo ${names[
c=year/100,
s=(year%100)/12,
t=(year % 100) % 12,
a=(5*(c%4)+2) % 7,
b=(s + t + (t / 4) + a ) % 7,
(b + day - ${doomsday[(year%4 == 0) && ((year%100) || (year%400 == 0))]:month-1:1} + 7) % 7
]}
else return 1
fi
 
for date in 1800-01-06 1875-03-29 1915-12-07 1970-12-23 2043-05-14 2077-02-12 2101-04-02
do day-of-the-week "$date"
done</syntaxhighlight>
 
{{out}}
<pre>Monday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">
const
(
days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
first_days_common = [3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5]
first_days_leap = [4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5]
)
 
fn main() {
dates := [
"1800-01-06",
"1875-03-29",
"1915-12-07",
"1970-12-23",
"2043-05-14",
"2077-02-12",
"2101-04-02"
]
mut y, mut m, mut d, mut a, mut f, mut w, mut dow := 0,0,0,0,0,0,0
println("Days of week given by Doomsday rule:")
for date in dates {
y = date[0..4].int()
m = date[5..7].int()
m--
d = date[8..10].int()
a = anchor_day(y)
f = first_days_common[m]
if is_leap_year(y) {
f = first_days_leap[m]
}
w = d - f
if w < 0 {
w = 7 + w
}
dow = (a + w) % 7
println('$date -> ${days[dow]}')
}
}
 
fn anchor_day(y int) int {
return (2 + 5 *(y % 4) + 4 * (y % 100) + 6 *(y % 400)) % 7
}
 
fn is_leap_year(y int) bool {
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)
}
</syntaxhighlight>
 
{{out}}
<pre>
Days of week given by Doomsday rule:
1800-01-06 -> Monday
1875-03-29 -> Monday
1915-12-07 -> Tuesday
1970-12-23 -> Wednesday
2043-05-14 -> Thursday
2077-02-12 -> Friday
2101-04-02 -> Saturday
</pre>
 
Line 1,396 ⟶ 2,075:
{{libheader|Wren-date}}
We only use the above module to check the dates of the week given by Conway's method. The latter are worked out from scratch.
<langsyntaxhighlight ecmascriptlang="wren">import "./date" for Date
 
var days = ["Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"]
Line 1,433 ⟶ 2,112:
var d = Date.parse(date, Date.isoDate)
System.print("%(date) -> %(d.weekDay)")
}</langsyntaxhighlight>
 
{{out}}
Line 1,456 ⟶ 2,135:
</pre>
 
=={{header|XPL0}}==
{{trans|ALGOL W}}
<syntaxhighlight lang "XPL0">
\Finds the day of the week of a date using John Conway's Doomsday rule.
\Returns the day of the week (Sunday = 0, Monday = 1,...) for the date
\ specified by CCYY, MM and DD.
function DOW ( CCYY, MM, DD );
integer CCYY, MM, DD;
integer Doomsday, AnchorDay, LeapYear, Dooms;
begin
Doomsday := rem(( \Tuesday \2
+ 5 * rem( CCYY/4 )
+ 4 * rem( CCYY/100 )
+ 6 * rem( CCYY/400 )
) / 7);
LeapYear := rem(CCYY/4) = 0 and ( rem(CCYY/100) # 0 or rem(CCYY/ 400) = 0 );
Dooms := [[4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5],
[3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5]];
AnchorDay := Dooms(if LeapYear then 0 else 1, MM-1);
return rem( ( Doomsday + ( DD - AnchorDay ) + 7 ) / 7);
end; \DOW
 
\Prints a test date and its day of the week
procedure TestDOW ( CCYY, MM, DD );
integer CCYY, MM, DD;
integer DayName;
begin
DayName := ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday"];
IntOut(0, CCYY);
ChOut(0, ^-); IntOut(0, MM/10); IntOut(0, rem(0));
ChOut(0, ^-); IntOut(0, DD/10); IntOut(0, rem(0));
Text(0, ": "); Text(0, DayName( DOW( CCYY, MM, DD ) ));
CrLf(0);
end;
 
begin \task test cases
TestDOW( 1800, 1, 6 );
TestDOW( 1875, 3, 29 );
TestDOW( 1915, 12, 7 );
TestDOW( 1970, 12, 23 );
TestDOW( 2043, 5, 14 );
TestDOW( 2077, 2, 12 );
TestDOW( 2101, 4, 2 );
TestDOW( 2022, 6, 19 )
end</syntaxhighlight>
{{out}}
<pre>
1800-01-06: Monday
1875-03-29: Monday
1915-12-07: Tuesday
1970-12-23: Wednesday
2043-05-14: Thursday
2077-02-12: Friday
2101-04-02: Saturday
2022-06-19: Sunday
</pre>
 
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="yabasic">dim fdoom(1, 12)
for x = 0 to arraysize(fdoom(),1)
for y = 1 to arraysize(fdoom(),2)
Line 1,502 ⟶ 2,238:
data 3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5
data 4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5
data "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"</langsyntaxhighlight>
{{out}}
<pre>
337

edits