Day of the week: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add CLU)
(Applesoft BASIC)
Line 570: Line 570:
Dec 25, 2118</lang>
Dec 25, 2118</lang>


==={{header|Applesoft BASIC}}===
{{trans|Commodore BASIC}}
<lang gwbasic> 1 DEF FN D7(N) = N - 7 * INT (N / 7)
2 DEF FN RD(Y) = 365 * Y + INT (Y / 4) - INT (Y / 100) + INT (Y / 400)
3 PRINT "YEARS WITH CHRISTMAS ON A SUNDAY" CHR$ (13)
4 FOR Y = 2008 TO 2121
5 IF NOT FN D7( FN RD(Y) - 6) THEN PRINT Y,
6 NEXT Y</lang>
==={{header|Atari BASIC}}===
==={{header|Atari BASIC}}===
{{trans|Commodore BASIC}}
{{trans|Commodore BASIC}}

Revision as of 07:07, 27 July 2022

Task
Day of the week
You are encouraged to solve this task according to the task description, using any language you may know.

A company decides that whenever Xmas falls on a Sunday they will give their workers all extra paid holidays so that, together with any public holidays, workers will not have to work the following week (between the 25th of December and the first of January).


Task

In what years between 2008 and 2121 will the 25th of December be a Sunday?

Using any standard date handling libraries of your programming language; compare the dates calculated with the output of other languages to discover any anomalies in the handling of dates which may be due to, for example, overflow in types used to represent dates/times similar to   y2k   type problems.

11l

<lang 11l>print((2008..2121).filter(y -> Time(y, 12, 25).strftime(‘%w’) == ‘0’))</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

360 Assembly

Translation of: REXX

The program uses two ASSIST macro (XDECO,XPRNT) to keep the code as short as possible. <lang 360asm>* Day of the week 06/07/2016 DOW CSECT

        USING  DOW,R15            base register
        LA     R6,2008            year=2008

LOOP C R6,=F'2121' do year=2008 to 2121

        BH     ELOOP              .
        LR     R7,R6              y=year
        LA     R8,12              m=12
        LA     R9,25              d=25
        C      R8,=F'3'           if m<3
        BNL    MGE3               then
        LA     R8,12(R8)            m=m+12
        BCTR   R7,0                 y=y-1

MGE3 LR R10,R7 y

        SRDA   R10,32             .
        D      R10,=F'100'        r=y//100 ; l=y/100
        LR     R3,R8              m
        LA     R3,1(R3)           m+1
        M      R2,=F'26'          *26
        D      R2,=F'10'          /10
        AR     R3,R9              +d
        AR     R3,R10             +r
        LR     R2,R10             r
        SRA    R2,2               /4
        AR     R2,R3              (d+(m+1)*26/10+r+r/4
        LR     R3,R11             l
        SRA    R3,2               /4
        AR     R2,R3              (d+(m+1)*26/10+r+r/4+l/4
        LA     R5,5               5
        MR     R4,R11             *l
        AR     R2,R5              (d+(m+1)*26/10+r+r/4+l/4+5*l)
        SRDA   R2,32              .
        D      R2,=F'7'           w=(d+(m+1)*26/10+r+r/4+l/4+5*l)//7
        C      R2,=F'1'           if w=1  (sunday)
        BNE    WNE1               then
        XDECO  R6,PG                edit year
        XPRNT  PG,12                print year

WNE1 LA R6,1(R6) year=year+1

        B      LOOP               next year

ELOOP BR R14 exit PG DS CL12 buffer

        YREGS
        END    DOW</lang>
Output:
        2011
        2016
        2022
        2033
        2039
        2044
        2050
        2061
        2067
        2072
        2078
        2089
        2095
        2101
        2107
        2112
        2118

ABAP

<lang ABAP>report zday_of_week data: lv_start type i value 2007,

     lv_n type i value 114,
     lv_date type sy-datum,
     lv_weekday type string,
     lv_day type c,
     lv_year type n length 4.

write 'December 25 is a Sunday in: '. do lv_n times.

  lv_year = lv_start + sy-index.
  concatenate lv_year '12' '25' into lv_date.
  call function 'DATE_COMPUTE_DAY'
   exporting date = lv_date
   importing day  = lv_day.
  select single langt from t246 into lv_weekday
    where sprsl = sy-langu and
    wotnr = lv_day.
  if lv_weekday eq 'Sunday'.
    write / lv_year.
  endif.

enddo. </lang>

Output:
December 25 is a Sunday in:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Action!

Action! does not have a standard library providing a day of week function, therefore an adaptation of Sakamoto's method to determine the day of week for a given date using integer arithmetic is used. <lang Action!> Byte FUNC DayOfWeek(BYTE day, month CARD year BYTE century) CARD weekday BYTE ARRAY index=[0 3 2 5 0 3 5 1 4 6 2 4]

IF year < 100 THEN

  year = year + century * 100 

FI

IF year < 1753 THEN RETURN(7) FI

IF month < 3 THEN

  year==-1    

FI

month = index(month-1) weekday=year + year/4 - year/100 + year/400 + month + day weekday = weekday MOD 7 RETURN (weekday)

PROC main() CARD y PrintE("December 25 is a Sunday in:") FOR y = 2008 to 2121 DO IF DayOfWeek(25, 12, y)=0 THEN PrintCE(y) FI OD RETURN </lang>

Output:
December 25 is a Sunday in:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Ada

<lang ada>with Ada.Calendar.Formatting; use Ada.Calendar.Formatting; with Ada.Text_IO; use Ada.Text_IO;

procedure Yuletide is begin

  for Year in 2008..2121 loop
     if Day_Of_Week (Time_Of (Year, 12, 25)) = Sunday then
        Put_Line (Image (Time_Of (Year, 12, 25)));
     end if;
  end loop;

end Yuletide;</lang>

Output:
2011-12-25 00:00:00
2016-12-25 00:00:00
2022-12-25 00:00:00
2033-12-25 00:00:00
2039-12-25 00:00:00
2044-12-25 00:00:00
2050-12-25 00:00:00
2061-12-25 00:00:00
2067-12-25 00:00:00
2072-12-25 00:00:00
2078-12-25 00:00:00
2089-12-25 00:00:00
2095-12-25 00:00:00
2101-12-25 00:00:00
2107-12-25 00:00:00
2112-12-25 00:00:00
2118-12-25 00:00:00

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d

<lang algol68># example from: http://www.xs4all.nl/~jmvdveer/algol.html - GPL # INT sun=0 # , mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 #;

PROC day of week = (INT year, month, day) INT: (

 # Day of the week by Zeller’s Congruence algorithm from 1887 #
 INT y := year, m := month, d := day, c;
 IF m <= 2 THEN
   m +:= 12; y -:= 1
 FI;
 c := y OVER 100;
 y %*:= 100;
 (d - 1 + ((m + 1) * 26) OVER 10 + y + y OVER 4 + c OVER 4 - 2 * c) MOD 7

);

test:(

 print("December 25th is a Sunday in:");
 FOR year FROM 2008 TO 2121 DO
   INT wd = day of week(year, 12, 25);
   IF wd = sun THEN print(whole(year,-5)) FI
 OD;
 new line(stand out)

) </lang>

Output:
December 25th is a Sunday in: 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

ALGOL W

Translation of: Fortran

<lang algolw>begin % find years where Christmas day falls on a Sunday %

   integer procedure Day_of_week ( integer value d, m, y );
       begin
           integer j, k, mm, yy;
           mm := m;
           yy := y;
           if mm <= 2 then begin
               mm := mm + 12;
               yy := yy - 1;
           end if_m_le_2;
           j := yy div 100;
           k := yy rem 100;
           (d + ( ( mm + 1 ) * 26 ) div 10 + k + k div 4 + j div 4 + 5 * j ) rem 7
       end Day_of_week;
   write( "25th of December is a Sunday in" );
   for year := 2008 until 2121 do begin
       integer day;
       day := Day_of_week( 25, 12, year );
       if day = 1 then writeon( I_W := 5, S_W := 0, year );
   end for_year

end.</lang>

Output:
25th of December is a Sunday in 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

ALGOL-M

<lang algol> BEGIN

% CALCULATE P MOD Q % INTEGER FUNCTION MOD(P, Q); INTEGER P, Q; BEGIN

  MOD := P - Q * (P / Q);

END;

COMMENT

 RETURN DAY OF WEEK (SUN=0, MON=1, ETC.) FOR A GIVEN
 GREGORIAN CALENDAR DATE USING ZELLER'S CONGRUENCE;

INTEGER FUNCTION DAYOFWEEK(MO, DA, YR); INTEGER MO, DA, YR; BEGIN

 INTEGER Y, C, Z;
 IF MO < 3 THEN
   BEGIN
     MO := MO + 10;
     YR := YR - 1;
   END
 ELSE MO := MO - 2;
 Y := MOD(YR, 100);
 C := YR / 100;
 Z := (26 * MO - 2) / 10;
 Z := Z + DA + Y + (Y / 4) + (C /4) - 2 * C + 777;
 DAYOFWEEK := MOD(Z, 7);

END;

% MAIN PROGRAM STARTS HERE % INTEGER YEAR, SUNDAY; SUNDAY := 0; WRITE("CHRISTMAS WILL FALL ON A SUNDAY IN THESE YEARS:"); FOR YEAR := 2008 STEP 1 UNTIL 2121 DO

 BEGIN
   IF DAYOFWEEK(12, 25, YEAR) = SUNDAY THEN
      WRITE(YEAR);
 END;

END </lang>

Output:
CHRISTMAS WILL FALL ON A SUNDAY IN THESE YEARS:
  2011
  2016
  2022
  2033
  2039
  2044
  2050
  2061
  2067
  2072
  2078
  2089
  2095
  2101
  2107
  2112
  2118

APL

<lang apl>⍝ Based on the simplified calculation of Zeller's congruence, since Christmas is after March 1st, no adjustment is required. ⎕IO ← 0 ⍝ Indices are 0-based y ← 2008 + ⍳114 ⍝ Years from 2008 to 2121 ⍝ Simplified Zeller function operating on table of dates formatted as 114 rows and 3 columns of (day, month, year) ⍝ 0 = Saturday, 1 = Sunday, 2 = Monday, 3 = Tuesday, 4 = Wednesday, 5 = Thursday, 6 = Friday zeller ← { 7 | +/ (((1↑⍴⍵),6)⍴1 1 1 1 ¯1 1) × ⌊(((⍴⍵)⍴1 13 1)×⍵+(⍴⍵)⍴0 1 0)[;0 1 2 2 2 2]÷((1↑⍴⍵),6)⍴1 5 1 4 100 400 } result ← (1 = zeller 25,[1]12,[0.5]y) / y </lang>

Output:
  result
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

AppleScript

<lang applescript>set ChristmasSundays to {} set Christmas to (current date) set month of Christmas to December set day of Christmas to 25 repeat with |year| from 2008 to 2121 set year of Christmas to |year| if weekday of Christmas is Sunday then set end of ChristmasSundays to |year| end repeat ChristmasSundays</lang>


Or, composing generic functions: <lang applescript> -- xmasIsSunday :: Int -> Bool on xmasIsSunday(y)

   tell (current date)
       set {its year, its month, its day, its time} to {y, 12, 25, 0}
       its weekday is Sunday
   end tell

end xmasIsSunday



TEST ---------------------------

on run

   filter(xmasIsSunday, enumFromTo(2008, 2121))
   

end run



GENERIC FUNCTIONS --------------------

-- enumFromTo :: Int -> Int -> [Int] on enumFromTo(m, n)

   if m ≤ n then
       set lst to {}
       repeat with i from m to n
           set end of lst to i
       end repeat
       lst
   else
       {}
   end if

end enumFromTo


-- filter :: (a -> Bool) -> [a] -> [a] on filter(f, xs)

   tell mReturn(f)
       set lst to {}
       set lng to length of xs
       repeat with i from 1 to lng
           set v to item i of xs
           if |λ|(v, i, xs) then set end of lst to v
       end repeat
       return lst
   end tell

end filter


-- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Script on mReturn(f)

   if class of f is script then
       f
   else
       script
           property |λ| : f
       end script
   end if

end mReturn</lang>

Output:

<lang AppleScript>{2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118}</lang>

Arc

<lang arc> (= day-names '(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)) (= get-weekday-num (fn (year month day)

  (= helper '(0 3 2 5 0 3 5 1 4 6 2 4))
  (if (< month 3) (= year (- year 1)))
  (mod (+ year (helper (- month 1)) day
       (apply + (map [trunc (/ year _)] '(4 -100 400))))
  7)))

(= get-weekday-name (fn (weekday-num) (day-names weekday-num))) </lang> test: <lang arc>(up i 2008 2121

 (when (is 0 (get-weekday-num i 12 25))
   (prn i)))

2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

</lang>

Arturo

<lang rebol>print select 2008..2121 'year [

   "Sunday" = get to :date.format:"dd-MM-YYYY" ~"25-12-|year|" 'Day

]</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118 

AutoHotkey

<lang autohotkey>year = 2008 stop = 2121

While year <= stop {

FormatTime, day,% year 1225, dddd
If day = Sunday
 out .= year "`n"
year++

} MsgBox,% out</lang>

AutoIt

<lang AutoIt>#include <date.au3> Const $iSunday = 1 For $iYear = 2008 To 2121 Step 1

  If $iSunday = _DateToDayOfWeek($iYear, 12, 25) Then
    ConsoleWrite(StringFormat($iYear & "\n"))
  EndIf

Next</lang>

AWK

<lang AWK>

  1. syntax: GAWK -f DAY_OF_THE_WEEK.AWK
  2. runtime does not support years > 2037 on my 32-bit Windows XP O/S

BEGIN {

   for (i=2008; i<=2121; i++) {
     x = strftime("%Y/%m/%d %a",mktime(sprintf("%d 12 25 0 0 0",i)))
     if (x ~ /Sun/) { print(x) }
   }

} </lang>

BASIC

Works with: FreeBASIC
This program needs the modulo function because there is a bug in the built in modulo function.

<lang BASIC>Declare Function modulo(x As Double, y As Double) As Double Declare Function wd(m As Double, d As Double, y As Double) As Integer

Cls Dim yr As Double For yr = 2008 To 2121 If wd(12,25,yr) = 1 Then Print "Dec " & 25 & ", " & yr EndIf Next Sleep

Function modulo(x As Double, y As Double) As Double If y = 0 Then Return x Else Return x - y * Int(x / y) End If End Function

Function wd(m As Double, d As Double, y As Double) As Integer If m = 1 Or m = 2 Then m += 12 y-= 1 End If Return modulo(365 * y + Fix(y / 4) - Fix(y / 100) + Fix(y / 400) + d + Fix((153 * m + 8) / 5), 7) + 1 End Function

Dec 25, 2011 Dec 25, 2016 Dec 25, 2022 Dec 25, 2033 Dec 25, 2039 Dec 25, 2044 Dec 25, 2050 Dec 25, 2061 Dec 25, 2067 Dec 25, 2072 Dec 25, 2078 Dec 25, 2089 Dec 25, 2095 Dec 25, 2101 Dec 25, 2107 Dec 25, 2112 Dec 25, 2118</lang>

Applesoft BASIC

Translation of: Commodore BASIC

<lang gwbasic> 1 DEF FN D7(N) = N - 7 * INT (N / 7)

2  DEF  FN RD(Y) = 365 * Y +  INT (Y / 4) -  INT (Y / 100) +  INT (Y / 400)
3  PRINT "YEARS WITH CHRISTMAS ON A SUNDAY" CHR$ (13)
4  FOR Y = 2008 TO 2121
5      IF  NOT  FN D7( FN RD(Y) - 6) THEN  PRINT Y,
6  NEXT Y</lang>

Atari BASIC

Translation of: Commodore BASIC

<lang basic>100 REM FIND YEARS WITH SUNDAY CHRISTMAS 110 PRINT CHR$(125);"SUNDAY CHRISTMASES 2008-2121:":PRINT 120 FOR Y=2008 TO 2121 130 EOY=Y*365+INT(Y/4)-INT(Y/100)+INT(Y/400) 140 XMAS=EOY-6 150 DOW=XMAS-7*INT(XMAS/7) 160 IF DOW THEN 220 170 PRINT Y; 180 FOUND=FOUND+1 190 IF FOUND<3 THEN PRINT ,:GOTO 220 200 FOUND=0 210 PRINT 220 NEXT Y 230 IF FOUND THEN PRINT</lang>

Output:
  SUNDAY CHRISTMASES 2008-2121

  2011          2016          2022
  2033          2039          2044
  2050          2061          2067
  2072          2078          2089
  2095          2101          2107
  2112          2118

BaCon

<lang freebasic>' Sunday Christmas PRINT "Years with Christmas on a Sunday" FOR y = 2008 TO 2121

   tv = TIMEVALUE(y, 12, 25, 0, 0, 0)
   IF WEEKDAY$(tv) = "Sunday" THEN PRINT y

NEXT</lang>

Output:
prompt$ ./sunday-christmas
Years with Christmas on a Sunday
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Commodore BASIC

This takes advantage of the dynamic scope of arguments to DEF FN functions to nest definitions and ultimately turn the question "Does Christmas fall on a Sunday in year Y?" into a single Boolean function of the year number. It's easy to run afoul of stack limitations in Microsoft BASICs doing this, especially on older versions that just use the processor's 256-byte stack instead of giving BASIC its own, but this program runs fine even on an unexpanded VIC-20.

<lang basic>100 REM FIND OUT WHAT YEARS HAVE CHRISTMAS ON A SUNDAY 110 REM MODULO FUNCTION (USES CALLER'S N AS DIVIDEND) 120 DEF FNNM(D) = N - D * INT(N/D) 130 REM RATA DIE OF 31 DEC Y (CAN BE TAKEN MODULO 7 TO GET DAY OF WEEK) 140 DEF FNRD(Y) = 365 * Y + INT(Y/4) - INT(Y/100) + INT(Y/400) 150 REM TRUE IF THE GIVEN RD IS A SUNDAY 160 DEF FND7(N) = 0 = FNNM(7) 170 REM TRUE IF CHRISTMAS FALLS ON A SUNDAY IN THE GIVEN YEAR 180 DEF FNXS(Y) = FND7(FNRD(Y) - 6):REM 6 DAYS BEFORE THE END OF THE YEAR 190 REM TRY OUR TARGET YEARS AND OUTPUT THE ONES THAT MATCH 200 Y1 = 2008: Y2 = 2121 210 PRINT CHR$(147);"CHRISTMASES ON SUNDAY";Y1;"-";Y2;CHR$(13) 220 FOR Y=Y1 TO Y2 230 : IF FNXS(Y) THEN PRINT Y,:REM PRINT YEARS IN COLUMNS 240 NEXT Y 250 PRINT</lang>

Output:
CHRISTMASES ON SUNDAY 2008 - 2121:

 2011      2016      2022      2033
 2039      2044      2050      2061
 2067      2072      2078      2089
 2095      2101      2107      2112
 2118

FreeBASIC

<lang FreeBASIC>' version 17-06-2015 ' compile with: fbc -s console

Function wd(m As Integer, d As Integer, y As Integer) As Integer

 If m < 3 Then        ' If m = 1 Or m = 2 Then
   m += 12
   y -= 1
 End If
 Return (y + (y \ 4) - (y \ 100) + (y \ 400) + d + ((153 * m + 8) \ 5)) Mod 7

End Function

' ------=< MAIN >=------

For yr As Integer = 2008 To 2121

 If wd(12, 25, yr) = 0 Then
   Print "Dec 25 "; yr
 EndIf

Next

' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End</lang>

Output:
Dec 25  2011
Dec 25  2016
Dec 25  2022
Dec 25  2033
Dec 25  2039
Dec 25  2044
Dec 25  2050
Dec 25  2061
Dec 25  2067
Dec 25  2072
Dec 25  2078
Dec 25  2089
Dec 25  2095
Dec 25  2101
Dec 25  2107
Dec 25  2112
Dec 25  2118

<lang FreeBASIC>' version 17-06-2015 ' Weekday And DateSerial only works with #Include "vbcompat.bi" ' compile with: fbc -s console

  1. Include Once "vbcompat.bi"

Dim As Double a

For yr As Integer = 2008 To 2121

 a = DateSerial (yr, 12, 25)
 If Weekday(a) = 1 Then Print Format(a, "dd-mm-yyyy")   ' 1 = sunday, 2 = monday ...

Next

' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End</lang>

Output:
25-12-2011
25-12-2016
25-12-2022
25-12-2033
25-12-2039
25-12-2044
25-12-2050
25-12-2061
25-12-2067
25-12-2072
25-12-2078
25-12-2089
25-12-2095
25-12-2101
25-12-2107
25-12-2112
25-12-2118

GW-BASIC

<lang gwbasic>10 M = 12 20 D = 25 30 FOR Y = 2007 TO 2122 40 GOSUB 100 50 IF Z = 0 THEN PRINT Y 60 NEXT Y 70 END 100 REM CALCULATE DAY OF WEEK Z GIVEN 110 REM YEAR Y, MONTH M AND DAY D 120 REM SUNDAY = 0, SATURDAY = 6 130 IF M < 3 THEN Y = Y - 1 : M = M + 12 140 Z = Y + INT(Y/4) - INT(Y/100) + INT(Y/400) 150 Z = Z + D + INT((153*M + 8)/5) 160 Z = Z MOD 7 170 RETURN</lang>

IS-BASIC

<lang IS-BASIC>100 PROGRAM "Dayweek.bas" 110 PRINT "The years between 2008 and 2121 will the 25th of December be a Sunday:" 120 FOR Y=2008 TO 2121 130 IF DAYWEEK(Y,12,25)=0 THEN PRINT "Dec 25,";Y 140 NEXT 150 DEF DAYWEEK(Y,M,D) 160 LET A=INT((14-M)/12):LET Y=Y-A 170 LET W=D+INT((13*(M+12*A-2)-1)/5)+Y+INT(Y/4)-INT(Y/100)+INT(Y/400) 180 LET DAYWEEK=W-7*INT(W/7) 190 END DEF</lang>

Minimal BASIC

<lang gwbasic> 10 REM Find years with Sunday Christmas 20 LET F = 2008 30 LET T = 2121 40 PRINT "Sunday Christmases"; F; "-"; T 50 PRINT 60 FOR Y = F TO T 70 LET E = Y*365+INT(Y/4)-INT(Y/100)+INT(Y/400) 80 LET X = E-6 90 LET D = X-7*INT(X/7) 100 IF D <> 0 THEN 120 110 PRINT Y, 120 NEXT Y 130 PRINT 140 END </lang>

Sinclair ZX81 BASIC

Translation of: C

Works with 1k of RAM. Follows the C code quite closely: the only factors that perhaps make it less readable are (a) the absence of a modulo operator and (b) the need for continual calls to INT because we don't have an integer type. The performance is pretty acceptable; seconds rather than minutes. <lang zxbasic> 10 LET M=12

20 LET D=25
30 FOR Y=2008 TO 2121
40 GOSUB 80
50 IF W=0 THEN PRINT Y
60 NEXT Y
70 STOP
80 LET A=INT ((14-M)/12)
90 LET MM=M+12*A-2

100 LET YY=Y-A 110 LET W=D+INT ((13*MM-1)/5)+YY+INT (YY/4)-INT (YY/100)+INT (YY/400) 120 LET W=W-7*INT (W/7) 130 RETURN</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

QL SuperBASIC

Works with: Sinclair QL
...having a structured BASIC with MOD and quite unlike the ZX81's "first-generation" BASIC that's rather like using a calculator (also without an integer type). Even so, it's worth the minor effort to optimise the code for the task at hand, as done below - which if implemented for the ZX81's routine would make it finish in a fraction of a second, even in SLOW mode, as multiplying by 13 with a division by 5 is slower than by 256 alone, as well as that two divisions by multiples of 100 are much slower than one by 16 as at the link. N.B. by relying on strings to have 4-digit years, this routine is not y10k-compliant <lang qbasic>

AUTO 100,10

 DEF PROC Iso(S,O)
  REM passing starting & ending years via integers S & O
  LOCal y$,m%,d%,i$,n%,w%

  LET m%=12 : d%=25
  REM m% & d% are constants, so avoid recalculating n% (=48) each iteration
  LET i$=m%*256+ 19300 : n%=i$(2 TO 3)+ d%
  FOR count=S TO O
   LET y$=count : w%=(y$(1 TO 2)&"32"DIV 16+ count DIV 4+ count+ n%)MOD 7
   REM otherwise w%=(y$(1 TO 2)&"16"DIV 16+ count DIV 4+ count)MOD 7 
   REM = further optimisation beyond skipping irrelevant years:
   IF w%=0 THEN PRINT count : count = count+ 4
  END FOR count
 END DEF Iso

ctrl+space </lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Tiny BASIC

<lang tinybasic>

   LET Y = 2007
   LET M = 12
   LET D = 25
10 IF Y = 2122 THEN END
   LET Y = Y + 1
   GOSUB 100
   IF Z = 0 THEN PRINT Y
   GOTO 10 

100 REM CALCULATE DAY OF WEEK Z GIVEN

   REM YEAR Y, MONTH M AND DAY D
   REM SUNDAY = 0, SATURDAY = 6
   IF M < 3 THEN LET Y = Y - 1
   IF M < 3 THEN LET M = M + 12
   LET Z = Y + Y/4 - Y/100 + Y/400
   LET Z = Z + D + (153*M + 8)/5
   LET Z = Z - 7*(Z/7)
   RETURN</lang>
Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Batch File

<lang dos>:: Day of the Week task from Rosetta Code

Batch File Implementation
Question: In what years between 2008 and 2121 will the 25th of December be a Sunday?
Method: Zeller's Rule

@echo off rem set month code for December set mon=33 rem set day number set day=25

for /L %%y in (2008,1,2121) do (

  setlocal enabledelayedexpansion
  set /a "a=%%y/100"
  set /a "b=%%y-(a*100)"
  set /a "weekday=(day+mon+b+(b/4)+(a/4)+(5*a))%%7"
  if "!weekday!"=="1" echo(Dec 25, %%y is a Sunday.
  endlocal

) pause exit /b 0</lang>

Output:
Dec 25, 2011 is a Sunday.
Dec 25, 2016 is a Sunday.
Dec 25, 2022 is a Sunday.
Dec 25, 2033 is a Sunday.
Dec 25, 2039 is a Sunday.
Dec 25, 2044 is a Sunday.
Dec 25, 2050 is a Sunday.
Dec 25, 2061 is a Sunday.
Dec 25, 2067 is a Sunday.
Dec 25, 2072 is a Sunday.
Dec 25, 2078 is a Sunday.
Dec 25, 2089 is a Sunday.
Dec 25, 2095 is a Sunday.
Dec 25, 2101 is a Sunday.
Dec 25, 2107 is a Sunday.
Dec 25, 2112 is a Sunday.
Dec 25, 2118 is a Sunday.
Press any key to continue . . .

BBC BASIC

<lang bbcbasic> INSTALL @lib$+"DATELIB"

     FOR year% = 2008 TO 2121
       IF FN_dow(FN_mjd(25, 12, year%)) = 0 THEN
         PRINT "Christmas Day is a Sunday in "; year%
       ENDIF
     NEXT</lang>

bc

Because bc has no date library, this program uses Zeller's rule, also known as Zeller's congruence, to calculate day of week.

<lang bc>scale = 0

/*

* Returns day of week (0 to 6) for year, month m, day d in proleptic
* Gregorian calendar. Sunday is 0. Assumes y >= 1, scale = 0.
*/

define w(y, m, d) { auto a

/* Calculate Zeller's congruence. */ a = (14 - m) / 12 m += 12 * a y -= a return ((d + (13 * m + 8) / 5 + \ y + y / 4 - y / 100 + y / 400) % 7) }

for (y = 2008; y <= 2121; y++) { /* If December 25 is a Sunday, print year. */ if (w(y, 12, 25) == 0) y } quit</lang>

BCPL

<lang bcpl>get "libhdr"

let weekday(y, m, d) =

   m<3 -> wd((y-1)/100, (y-1) rem 100, m + 10, d),
          wd(y/100, y rem 100, m - 2, d)

and wd(c, y, m, d) =

   ((26*m-2)/10 + d + y + y/4 + c/4 - 2 * c + 777) rem 7

let start() be

   for year = 2008 to 2121
       if weekday(year, 12, 25) = 0
           do writef("%N*N", year)</lang>
Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Befunge

Befunge doesn't have any standard date-handling functionality, so we calculate the day of the week directly using a simple variation of the Zeller rule.

<lang befunge>8 >:"2("*+::::4/+\"d"/-\45v @_^#`"y": +1$<_v#%7+1+/*:*< >:#,_>$:.55+,^ >0" ,52 ceD"</lang>

Output:
Dec 25, 2011
Dec 25, 2016
Dec 25, 2022
Dec 25, 2033
Dec 25, 2039
Dec 25, 2044
Dec 25, 2050
Dec 25, 2061
Dec 25, 2067
Dec 25, 2072
Dec 25, 2078
Dec 25, 2089
Dec 25, 2095
Dec 25, 2101
Dec 25, 2107
Dec 25, 2112
Dec 25, 2118

Bracmat

Translation of: C

<lang bracmat>{ Calculate day of week in proleptic Gregorian calendar. Sunday == 0. }

   ( wday
   =   year month day adjustment mm yy
     .   !arg:(?year,?month,?day)
       & div$(14+-1*!month,12):?adjustment
       & !month+12*!adjustment+-2:?mm
       & !year+-1*!adjustment:?yy
       &   mod
         $ (   !day
             + div$(13*!mm+-1,5)
             + !yy
             + div$(!yy,4)
             + -1*div$(!yy,100)
             + div$(!yy,400)
           , 7
           )
   )

& 2008:?y & whl

 ' ( !y:~>2121
   & (   wday$(!y,12,25):0
       & put$(str$(!y "-12-25\n"))
     | 
     )
   & 1+!y:?y
   )

& done;</lang>

Output:
2011-12-25
2016-12-25
2022-12-25
2033-12-25
2039-12-25
2044-12-25
2050-12-25
2061-12-25
2067-12-25
2072-12-25
2078-12-25
2089-12-25
2095-12-25
2101-12-25
2107-12-25
2112-12-25
2118-12-25

C

Because of problems with various C libraries (such as time_t overflowing during 2038, or strptime() or mktime() not filling in tm_wday), this program uses Zeller's Rule to calculate day of week.

<lang c>#include <stdio.h>

/* Calculate day of week in proleptic Gregorian calendar. Sunday == 0. */ int wday(int year, int month, int day) { int adjustment, mm, yy;

adjustment = (14 - month) / 12; mm = month + 12 * adjustment - 2; yy = year - adjustment; return (day + (13 * mm - 1) / 5 + yy + yy / 4 - yy / 100 + yy / 400) % 7; }

int main() { int y;

for (y = 2008; y <= 2121; y++) { if (wday(y, 12, 25) == 0) printf("%04d-12-25\n", y); }

return 0; }</lang>

C#

<lang csharp>using System;

class Program {

   static void Main(string[] args)
   {
       for (int i = 2008; i <= 2121; i++)
       {
           DateTime date = new DateTime(i, 12, 25);
           if (date.DayOfWeek == DayOfWeek.Sunday)
           {
               Console.WriteLine(date.ToString("dd MMM yyyy"));
           }
       }
   }

}</lang>

Using LINQ: <lang csharp>using System; using System.Linq;

class Program {

   static void Main(string[] args)
   {
       string[] days = Enumerable.Range(2008, 2121 - 2007)
           .Select(year => new DateTime(year, 12, 25))
           .Where(day => day.DayOfWeek == DayOfWeek.Sunday)
           .Select(day => day.ToString("dd MMM yyyy")).ToArray();
       foreach (string day in days) Console.WriteLine(day);
   }

}</lang>Lambda expressions FTW: <lang csharp>using System; using System.Linq;

class Program {

   static void Main(string[] args)
   {
       Enumerable.Range(2008, 113).ToList()
       .ConvertAll(ent => new DateTime(ent, 12, 25))
       .Where(ent => ent.DayOfWeek.Equals(DayOfWeek.Sunday)).ToList()
       .ForEach(ent => Console.WriteLine(ent.ToString("dd MMM yyyy")));
   }

}</lang>

Output:
25 Dec 2011
25 Dec 2016
25 Dec 2022
25 Dec 2033
25 Dec 2039
25 Dec 2044
25 Dec 2050
25 Dec 2061
25 Dec 2067
25 Dec 2072
25 Dec 2078
25 Dec 2089
25 Dec 2095
25 Dec 2101
25 Dec 2107
25 Dec 2112
25 Dec 2118

C++

<lang cpp>#include <boost/date_time/gregorian/gregorian.hpp>

  1. include <iostream>

int main( ) {

  using namespace boost::gregorian ;
  std::cout
     << "Yuletide holidays must be allowed in the following years:\n" ;
  for ( int i = 2008 ; i < 2121 ; i++ ) {
     greg_year gy = i ;
     date d  ( gy, Dec , 25 ) ;
     if ( d.day_of_week( ) == Sunday ) {

std::cout << i << std::endl ;

     }
  }
  std::cout << "\n" ;
  return 0 ;

}</lang>

Output:
Yuletide holidays must be allowed in the following years:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Clojure

Utilizing Java interop

<lang clojure> (import '(java.util GregorianCalendar)) (defn yuletide [start end] (filter #(= (. (new GregorianCalendar % (. GregorianCalendar DECEMBER) 25) get (. GregorianCalendar DAY_OF_WEEK)) (. GregorianCalendar SUNDAY)) (range start (inc end))))

(yuletide 2008 2121) </lang>

(2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118)

CLU

<lang clu>weekday = proc (d: date) returns (int)

   y: int := d.year
   m: int := d.month
   if m<3 
       then y, m := y-1, m+10
       else m := m-2
   end
   c: int := y/100
   y := y//100
   z: int := (26*m-2)/10 + d.day + y + y/4 + c/4 - 2*c + 777
   return(z//7)

end weekday

start_up = proc ()

   po: stream := stream$primary_output()
   for year: int in int$from_to(2008, 2121) do
       if weekday(date$create(25, 12, year, 0, 0, 0))=0 then
           stream$putl(po, int$unparse(year))
       end
   end

end start_up</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

COBOL

Using Date Intrinsic Functions <lang COBOL>

      program-id. dec25.
      data division.
      working-storage section.
      1 work-date.
       2 yr pic 9(4) value 2008.
       2 mo-da pic 9(4) value 1225. *> Dec 25
      1 wk-date redefines work-date pic 9(8).
      1 binary.
       2 int-date pic 9(8).
       2 dow pic 9(4).
      procedure division.
          perform varying yr from 2008 by 1
          until yr > 2121
              compute int-date = function integer-of-date (wk-date)
              compute dow = function mod ((int-date - 1) 7) + 1
              if dow = 7  *> Sunday = 7 per ISO 8601 and ISO 1989
                  display yr
              end-if
          end-perform
          stop run
          .
      end program dec25.

</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Without Date Intrinsic Functions

<lang Cobol>

      identification division.            
      program-id. dowtest.                
      data division.                      
      working-storage section.            
      01  ws-inp-date   pic x(08).        
      01  filler redefines ws-inp-date.   
        03  ws-inp-year  pic 9(04).       
      01  ws-dow        pic 9(05).              
      procedure division.                       
          move '00001225' to ws-inp-date        
          perform test before                   
          varying ws-inp-year from 2008 by +1   
          until ws-inp-year > 2121            
            call "todow" using                  
                by reference ws-inp-date        
                by reference ws-dow             
                if ws-dow = 1 then                  
                  display 'year=' ws-inp-year 
                end-if                              
          end-perform                           
          stop run.                             
                                                
      end program dowtest.                      
                                                
      identification division.                  
      program-id.  todow.                       
      environment division.                         
      input-output section.                         
      file-control.                                 
      data division.                                
      file section.                                 
      working-storage section.  
      01 tally pic 9(05).
      01  wms-work-area.                            
        03  wms-year       pic 9(04).               
        03  wms-month      pic 9(02).               
        03  wms-csys       pic 9(01) value 1.  
        03  wms-sum        pic 9(05).
      linkage section.                              
      01  lkip-date.                                
        03  lkip-date-year     pic 9(04).           
        03  lkip-date-month    pic 9(02).           
        03  lkip-date-day      pic 9(02).           
      01  lkop-dow             pic 9(05).           
        88  lkop-sunday                   value 1.  
      procedure division using                      
          by reference lkip-date                    
          by reference lkop-dow                     
          .                                                            
                                                                       
          if lkip-date-month < 3                                       
            compute wms-month = lkip-date-month + 12                   
            compute wms-year  = lkip-date-year - 1                     
          else                                                         
            compute wms-month = lkip-date-month                        
            compute wms-year  = lkip-date-year                         
          end-if                                                       
                                                                       
         compute wms-sum    =                           
                         ( lkip-date-day + 2 * wms-month + wms-year    
                         + function integer (6 * (wms-month + 1) / 10) 
                         + function integer ( wms-year / 4   )         
                         - function integer ( wms-year / 100 )         
                         + function integer ( wms-year / 400 )         
                         + wms-csys )                             
        compute lkop-dow = function mod (wms-sum, 7) + 1
                         .                                             
      end program todow. 

</lang>

Output:
year=2011
year=2016
year=2022
year=2033
year=2039
year=2044
year=2050
year=2061
year=2067
year=2072
year=2078
year=2089
year=2095
year=2101
year=2107
year=2112
year=2118

CoffeeScript

<lang coffeescript>december = 11 # gotta love Date APIs :) sunday = 0 for year in [2008..2121]

 xmas = new Date year, december, 25
 console.log year if xmas.getDay() is sunday</lang>one-liner:<lang coffeescript>console.log year for year in [2008...2121] when new Date(year, 11, 25).getDay() is 0</lang>
Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

ColdFusion

<lang ColdFusion> <cfloop from = "2008" to = "2121" index = "i">

   <cfset myDate = createDate(i, 12, 25) />
   <cfif dayOfWeek(myDate) eq 1>
       December 25th falls on a Sunday in <cfoutput>#i#</cfoutput>
</cfif>

</cfloop> </lang>

Common Lisp

<lang lisp>(loop for year from 2008 upto 2121

  when (= 6 (multiple-value-bind
                  (second minute hour date month year day-of-week dst-p tz)
                (decode-universal-time (encode-universal-time 0 0 0 25 12 year))
              (declare (ignore second minute hour date month year dst-p tz))
              day-of-week))
    collect year)</lang>

<lang lisp>(loop for year from 2008 upto 2121

  for xmas = (encode-universal-time 0 0 0 25 12 year)
  for day  = (nth-value 6 (decode-universal-time xmas))
  when (= day 6) collect year)</lang>

Component Pascal

<lang oberon2> MODULE DayOfWeek; IMPORT DevCommanders, TextMappers, Dates, StdLog;

PROCEDURE XmastOnSun(s,e: INTEGER); VAR i: INTEGER; d: Dates.Date; BEGIN i := s;d.day := 25;d.month := 12; WHILE i < e DO d.year := i; IF Dates.DayOfWeek(d) = Dates.sunday THEN StdLog.Int(i);StdLog.Ln END; INC(i) END END XmastOnSun;

PROCEDURE Do*; VAR s: TextMappers.Scanner; r: ARRAY 2 OF INTEGER; i: INTEGER; BEGIN s.ConnectTo(DevCommanders.par.text); s.SetPos(DevCommanders.par.beg); s.Scan;i := 0; WHILE ~s.rider.eot DO IF s.type = TextMappers.int THEN r[i] := s.int; INC(i) END; s.Scan END; XmastOnSun(r[0],r[1]); END Do;

END DayOfWeek. </lang> Execute: ^Q DayOfWeek.Do 2008 2121~

Output:
 2011
 2016
 2022
 2033
 2039
 2044
 2050
 2061
 2067
 2072
 2078
 2089
 2095
 2101
 2107
 2112
 2118

Cowgol

<lang cowgol>include "cowgol.coh";

sub weekday(year: uint16, month: uint8, day: uint8): (wd: uint8) is

   if month < 3 then
       month := month + 10;
       year := year - 1;
   else
       month := month - 2;
   end if;
   var c := year / 100;
   var y := year % 100;
   var z := (26 * month as uint16 - 2) / 10;
   z := z + day as uint16 + y + (y / 4) + (c / 4) - 2 * c + 777;
   wd := (z % 7) as uint8;

end sub;

var year: uint16 := 2008; while year <= 2121 loop

   if weekday(year, 12, 25) == 0 then
       print_i16(year);
       print_nl();
   end if;
   year := year + 1;

end loop;</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118


D

<lang d>void main() {

   import std.stdio, std.range, std.algorithm, std.datetime;
   writeln("Christmas comes on a Sunday in the years:\n",
           iota(2008, 2122)
           .filter!(y => Date(y, 12, 25).dayOfWeek == DayOfWeek.sun));

}</lang>

Output:
Christmas comes on a Sunday in the years:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

Delphi

Library: sysutils

always in uses clause in Delphi

<lang delphi>procedure IsXmasSunday(fromyear, toyear: integer); var i: integer; TestDate: TDateTime; outputyears: string; begin outputyears := ;

 for i:= fromyear to toyear do
 begin
   TestDate := EncodeDate(i,12,25);
   if dayofweek(TestDate) = 1 then
   begin
     outputyears := outputyears + inttostr(i) + ' ';
   end;
 end;
 //CONSOLE
 //writeln(outputyears);
 //GUI 
 form1.label1.caption := outputyears;

end;</lang>

Procedure called with year range to test and outputs a space-delimited array of years to a label. There is no error check that fromyear < toyear, but this is easily added.

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Draco

<lang draco>proc nonrec weekday(word y, m, d) byte:

   word c;
   if m<3 then
       m := m+10;
       y := y+1
   else
       m := m-2
   fi;
   c := y/100;
   y := y%100;
   ((26 * m - 2)/10 + d + y + y/4 + c/4 - 2*c + 777) % 7

corp

proc nonrec main() void:

   word year;
   for year from 2008 upto 2121 do
       if weekday(year, 12, 25)=0 then
           writeln(year)
       fi
   od

corp</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

ECL

<lang ECL>//In what years between 2008 and 2121 will the 25th of December be a Sunday?

IMPORT STD;

BaseYear := 2008; EndYear  := 2121;

ChristmasDay := RECORD

 UNSIGNED1 DayofWeek;
 UNSIGNED2 Year;

END;

ChristmasDay FindDate(INTEGER Ctr) := TRANSFORM

 SELF.DayofWeek := (STD.Date.FromGregorianYMD((BaseYear-1) + Ctr,12,25)) % 7; //0=Sunday
 SELF.Year := (BaseYear-1) + Ctr;

END;

YearDS := DATASET(EndYear-BaseYear,FindDate(COUNTER)); OUTPUT(YearDS(DayofWeek=0),{Year});

/* Outputs:

  2011
  2016
  2022
  2033
  2039
  2044
  2050
  2061
  2067
  2072
  2078
  2089
  2095
  2101
  2107
  2112
  2118
  • /

</lang> This code solves a specific task, but can easily be modified as a generic function to return the DayOfWeek for any day after 1 AD.

Elixir

Works with: Elixir version 1.4

<lang elixir>Enum.each(2008..2121, fn year ->

 wday = Date.from_erl!({year, 12, 25}) |> Date.day_of_week
 if wday==7, do: IO.puts "25 December #{year} is sunday"

end)</lang>

Output:
25 December 2011 is sunday
25 December 2016 is sunday
25 December 2022 is sunday
25 December 2033 is sunday
25 December 2039 is sunday
25 December 2044 is sunday
25 December 2050 is sunday
25 December 2061 is sunday
25 December 2067 is sunday
25 December 2072 is sunday
25 December 2078 is sunday
25 December 2089 is sunday
25 December 2095 is sunday
25 December 2101 is sunday
25 December 2107 is sunday
25 December 2112 is sunday
25 December 2118 is sunday

Emacs Lisp

<lang lisp>(require 'calendar)

(defun sunday-p (y)

 "Is Dec 25th a Sunday in this year?"
 (= (calendar-day-of-week (list 12 25 y)) 0))

(defun xmas-sunday (a b)

 "In which years in the range a, b is Dec 25th a Sunday?"
 (seq-filter #'sunday-p (number-sequence a b)))

(print (xmas-sunday 2008 2121))</lang>

Output:
(2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118)

Erlang

<lang erlang>% Implemented by bengt kleberg -module(yuletide). -export([main/0, sunday_years/2]).

main() -> [io:fwrite("25 December ~p is Sunday~n", [X]) || X <- sunday_years(2008, 2121)].

sunday_years( Start, Stop ) -> [X || X <- lists:seq(Start, Stop), is_sunday(calendar:day_of_the_week({X, 12, 25}))].

is_sunday( 7 ) -> true; is_sunday( _ ) -> false.</lang>

Output:
25 December 2011 is Sunday
25 December 2016 is Sunday
25 December 2022 is Sunday
25 December 2033 is Sunday
25 December 2039 is Sunday
25 December 2044 is Sunday
25 December 2050 is Sunday
25 December 2061 is Sunday
25 December 2067 is Sunday
25 December 2072 is Sunday
25 December 2078 is Sunday
25 December 2089 is Sunday
25 December 2095 is Sunday
25 December 2101 is Sunday
25 December 2107 is Sunday
25 December 2112 is Sunday
25 December 2118 is Sunday

ERRE

<lang ERRE> PROGRAM DAY_OF_THE_WEEK

PROCEDURE MODULO(X,Y->RES)

  IF Y=0 THEN
     RES=X
    ELSE
     RES=X-Y*INT(X/Y)
  END IF

END PROCEDURE

PROCEDURE WD(M,D,Y->RES%)

  IF M=1 OR M=2 THEN
    M+=12
    Y-=1
  END IF
  MODULO(365*Y+INT(Y/4)-INT(Y/100)+INT(Y/400)+D+INT((153*M+8)/5),7->RES)
  RES%=RES+1.0

END PROCEDURE

BEGIN PRINT(CHR$(12);) ! CLS FOR YR=2008 TO 2121 DO

   WD(12,25,YR->RES%)
   IF RES%=1 THEN  ! day 1 is Sunday......
     PRINT("Dec";25;",";YR)
   END IF

END FOR GET(K$) END PROGRAM </lang>

Output:
Dec 25, 2011
Dec 25, 2016
Dec 25, 2022
Dec 25, 2033
Dec 25, 2039
Dec 25, 2044
Dec 25, 2050
Dec 25, 2061
Dec 25, 2067
Dec 25, 2072
Dec 25, 2078
Dec 25, 2089
Dec 25, 2095
Dec 25, 2101
Dec 25, 2107
Dec 25, 2112
Dec 25, 2118

Euphoria

<lang Euphoria> --Day of the week task from Rosetta Code wiki --User:Lnettnay

--In what years between 2008 and 2121 will the 25th of December be a Sunday

include std/datetime.e

datetime dt

for year = 2008 to 2121 do

       dt = new(year, 12, 25)
       if weeks_day(dt) = 1 then -- Sunday = 1
               ? year
       end if

end for </lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

F#

<lang fsharp>open System

[ 2008 .. 2121 ] |> List.choose (fun y -> if DateTime(y,12,25).DayOfWeek = DayOfWeek.Sunday then Some(y) else None) |> printfn "%A"</lang>

Output:
[2011; 2016; 2022; 2033; 2039; 2044; 2050; 2061; 2067; 2072; 2078; 2089; 2095;
 2101; 2107; 2112; 2118]

Factor

<lang factor>USING: calendar math.ranges prettyprint sequences ; 2008 2121 [a,b] [ 12 25 <date> sunday? ] filter .</lang>

FBSL

<lang qbasic>#APPTYPE CONSOLE

'In what years between 2008 and 2121 will the 25th of December be a Sunday? dim date as integer, dayname as string for dim year = 2008 to 2121 date = year * 10000 + 1225 dayname = dateconv(date,"dddd") if dayname = "Sunday" then print "Christmas Day is on a Sunday in ", year end if next PAUSE </lang>

Forth

Forth has only TIME&DATE, which does not give day of week. Many public Forth Julian date calculators had year-2100 problems, but this algorithm works well. <lang forth> \ Zeller's Congruence

weekday ( d m y -- wd) \ 1 mon..7 sun
 over 3 < if 1- swap 12 + swap then
 100 /mod
 dup 4 / swap 2* -
 swap dup 4 / + +
 swap 1+ 13 5 */ + +
 ( in zeller 0=sat, so -2 to 0= mon, then mod, then 1+ for 1=mon)
 2- 7 mod 1+ ;  
 
yuletide
 ." December 25 is Sunday in "
 2122 2008 do
   25 12 i weekday
   7 = if i . then
 loop cr ; 

</lang>

<lang forth> cr yuletide December 25 is Sunday in 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

ok

</lang>


To show year-2100 problems with SwiftForth's provided Modified Julian Day support:

<lang forth>: yuletide

 ." December 25 is Sunday in "
 2122 2008 do
   25 12 i d/m/y
   7 mod 0= if i . then
 loop cr ;

cr yuletide December 25 is Sunday in 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2100 2106 2117</lang>

In 4tH a library is available which provides the right answer:

<lang forth>include lib/time.4th

yuletide
 ." December 25 is Sunday in "
 2122 2008 do
   25 12 i weekday
   6 = if i . then
 loop cr ;

cr yuletide</lang>

The code is derived from "Collected Algorithms from ACM", Volume 1 Algorithms 1-220.

Fortran

Works with: Fortran version 90 and later

Based on Forth example <lang fortran>PROGRAM YULETIDE

IMPLICIT NONE

INTEGER :: day, year

WRITE(*, "(A)", ADVANCE="NO") "25th of December is a Sunday in" DO year = 2008, 2121

  day = Day_of_week(25, 12, year)
  IF (day == 1) WRITE(*, "(I5)", ADVANCE="NO") year

END DO

CONTAINS

FUNCTION Day_of_week(d, m, y)

  INTEGER :: Day_of_week, j, k, mm, yy
  INTEGER, INTENT(IN) :: d, m, y
 
  mm=m
  yy=y
  IF(mm.le.2) THEN
     mm=mm+12
     yy=yy-1
  END IF
  j = yy / 100
  k = MOD(yy, 100)
  Day_of_week = MOD(d + ((mm+1)*26)/10 + k + k/4 + j/4 + 5*j, 7)

END FUNCTION Day_of_week

END PROGRAM YULETIDE</lang>

Output:
 25th of December is a Sunday in 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.

In this page you can see the program(s) related to this task and their results.

Frink

<lang frink>for y = 2008 to 2121

  if (parseDate["$y-12-25"] -> ### u ###) == "7"
     println[y]</lang>
Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

FutureBasic

<lang futurebasic>window 1

long y CFDateRef dt NSInteger day CFCalendarRef cal DateComponentsRef comps

cal = fn CalendarCurrent

comps = fn DateComponentsInit DateComponentsSetMonth( comps, 12 ) DateComponentsSetDay( comps, 25 )

for y = 2008 to 2121

 DateComponentsSetYear( comps, y )
 dt = fn CalendarDateFromComponents( cal, comps )
 day = fn CalendarComponentFromDate( cal, NSCalendarUnitWeekday, dt )
 if ( day == 1 )
   print y
 end if

next

HandleEvents</lang>


Gambas

Click this link to run this code <lang gambas>Public Sub Main() Dim siCount As Short

For siCount = 2008 To 2121

 If WeekDay(Date(siCount, 12, 25)) = 0 Then Print Format(Date(siCount, 12, 25), "dddd dd mmmm yyyy") & " falls on a Sunday"

Next

End</lang> Output:

Sunday 25 December 2011 falls on a Sunday
Sunday 25 December 2016 falls on a Sunday
Sunday 25 December 2022 falls on a Sunday
Sunday 25 December 2033 falls on a Sunday
Sunday 25 December 2039 falls on a Sunday
Sunday 25 December 2044 falls on a Sunday
Sunday 25 December 2050 falls on a Sunday
Sunday 25 December 2061 falls on a Sunday
Sunday 25 December 2067 falls on a Sunday
Sunday 25 December 2072 falls on a Sunday
Sunday 25 December 2078 falls on a Sunday
Sunday 25 December 2089 falls on a Sunday
Sunday 25 December 2095 falls on a Sunday
Sunday 25 December 2101 falls on a Sunday
Sunday 25 December 2107 falls on a Sunday
Sunday 25 December 2112 falls on a Sunday
Sunday 25 December 2118 falls on a Sunday

GAP

<lang gap>Filtered([2008 .. 2121], y -> WeekDay([25, 12, y]) = "Sun");

  1. [ 2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118 ]
  1. A possible implementation of WeekDayAlt

days := ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];;

WeekDayAlt := function(args)

  local d, m, y, k;
  d := args[1];
  m := args[2];
  y := args[3];
  if m < 3 then
     m := m + 12;
     y := y - 1;
  fi;
  k := 1 + RemInt(d + QuoInt((m + 1)*26, 10) + y + QuoInt(y, 4)
         + 6*QuoInt(y, 100) + QuoInt(y, 400) + 5, 7);
  return days[k];

end;

Filtered([2008 .. 2121], y -> WeekDayAlt([25, 12, y]) = "Sun");

  1. [ 2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118 ]</lang>

Go

<lang go>package main

import "fmt" import "time"

func main() {

   for year := 2008; year <= 2121; year++ {
       if time.Date(year, 12, 25, 0, 0, 0, 0, time.UTC).Weekday() ==
           time.Sunday {
           fmt.Printf("25 December %d is Sunday\n", year)
       }
   }

}</lang>

Output:
25 December 2011 is Sunday
25 December 2016 is Sunday
25 December 2022 is Sunday
25 December 2033 is Sunday
25 December 2039 is Sunday
25 December 2044 is Sunday
25 December 2050 is Sunday
25 December 2061 is Sunday
25 December 2067 is Sunday
25 December 2072 is Sunday
25 December 2078 is Sunday
25 December 2089 is Sunday
25 December 2095 is Sunday
25 December 2101 is Sunday
25 December 2107 is Sunday
25 December 2112 is Sunday
25 December 2118 is Sunday

Groovy

Solution: <lang groovy>def yuletide = { start, stop -> (start..stop).findAll { Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun" } }</lang>

Test program: <lang groovy>println yuletide(2008, 2121)</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

Haskell

Using the time library: <lang haskell>import Data.Time (fromGregorian) import Data.Time.Calendar.WeekDate (toWeekDate)


DAY OF THE WEEK --------------------

isXmasSunday :: Integer -> Bool isXmasSunday year = 7 == weekDay

 where
   (_, _, weekDay) = toWeekDate $ fromGregorian year 12 25



TEST -------------------------

main :: IO () main =

 mapM_
   putStrLn
   [ "Sunday 25 December " <> show year
     | year <- [2008 .. 2121],
       isXmasSunday year
   ]</lang>
Output:
Sunday 25 December 2011
Sunday 25 December 2016
Sunday 25 December 2022
Sunday 25 December 2033
Sunday 25 December 2039
Sunday 25 December 2044
Sunday 25 December 2050
Sunday 25 December 2061
Sunday 25 December 2067
Sunday 25 December 2072
Sunday 25 December 2078
Sunday 25 December 2089
Sunday 25 December 2095
Sunday 25 December 2101
Sunday 25 December 2107
Sunday 25 December 2112
Sunday 25 December 2118

The built-in System.Time module can overflow at the Unix epoch in 2038: <lang haskell>import System.Time

isXmasSunday :: Int -> Bool isXmasSunday year = ctWDay cal == Sunday

 where
   cal = toUTCTime $ toClockTime cal'
   cal' =
     CalendarTime
     { ctYear = year
     , ctMonth = December
     , ctDay = 25
     , ctHour = 0
     , ctMin = 0
     , ctSec = 0
     , ctPicosec = 0
     , ctWDay = Friday
     , ctYDay = 0
     , ctTZName = ""
     , ctTZ = 0
     , ctIsDST = False
     }

main :: IO () main =

 mapM_
   putStrLn
   [ "25 December " ++ show year ++ " is Sunday"
   | year <- [2008 .. 2121] 
   , isXmasSunday year ]</lang>
Output:

on 32-bit machine

25 December 2011 is Sunday
25 December 2016 is Sunday
25 December 2022 is Sunday
25 December 2033 is Sunday
*** Exception: user error (Time.toClockTime: invalid input)

but with 64 bit systems, running current versions of GHC:

25 December 2011 is Sunday
25 December 2016 is Sunday
25 December 2022 is Sunday
25 December 2033 is Sunday
25 December 2039 is Sunday
25 December 2044 is Sunday
25 December 2050 is Sunday
25 December 2061 is Sunday
25 December 2067 is Sunday
25 December 2072 is Sunday
25 December 2078 is Sunday
25 December 2089 is Sunday
25 December 2095 is Sunday
25 December 2101 is Sunday
25 December 2107 is Sunday
25 December 2112 is Sunday
25 December 2118 is Sunday

HicEst

<lang HicEst>DO year = 1, 1000000

  TIME(Year=year, MOnth=12, Day=25, TO, WeekDay=weekday)
  IF( weekday == 7) WRITE(StatusBar) year

ENDDO

END</lang>

No anomalies detected for the first million years :-)
Dec 25 = Sunday in 
5 ... 2011 2016 2022 2033 2039 2044 2050 2061 2067
      2072 2078 2089 2095 2101 2107 2112 2118 ... 999994

Icon and Unicon

<lang Icon>link datetime

procedure main() writes("December 25th is a Sunday in: ") every writes((dayoweek(25,12,y := 2008 to 2122)=="Sunday",y)," ") end</lang>


datetime provides dayoweek

<lang Icon>procedure dayoweek(day, month, year) #: day of the week

  static d_code, c_code, m_code, ml_code, y, C, M, Y
  initial {
     d_code := ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
     c_code := table()
     c_code[16] := c_code[20] := 0
     c_code[17] := c_code[21] := 6
     c_code[18] := c_code[22] := 4
     c_code[19] := c_code[23] := 2
     m_code := table()
     m_code[1] := m_code["January"] := 1
     m_code[2] := m_code["February"] := 4
     m_code[3] := m_code["March"] := 4
     m_code[4] := m_code["April"] := 0
     m_code[5] := m_code["May"] := 2
     m_code[6] := m_code["June"] := 5
     m_code[7] := m_code["July"] := 0
     m_code[8] := m_code["August"] := 3
     m_code[9] := m_code["September"] := 6
     m_code[10] := m_code["October"] := 1
     m_code[11] := m_code["November"] := 4
     m_code[12] := m_code["December"] := 6
     ml_code := copy(m_code)
     ml_code[1] := ml_code["January"] := 0
     ml_code[2] := ml_code["February"] := 3
     }
  if year < 1600 then stop("*** can't compute day of week that far back")
  if year > 2299 then stop("*** can't compute day of week that far ahead")
  C := c_code[(year / 100) + 1]
  y := year % 100
  Y := (y / 12) + (y % 12) + ((y % 12) / 4)
  month := integer(month)
  M := if (year % 4) = 0 then ml_code[month] else m_code[month]
  return d_code[(C + Y + M + day) % 7 + 1] 
  

end</lang>

Output:
December 25th is a Sunday in: 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

J

<lang j> load 'dates' NB. provides verb 'weekday'

  xmasSunday=: #~ 0 = [: weekday 12 25 ,~"1 0 ]   NB. returns years where 25 Dec is a Sunday
  xmasSunday 2008 + i.114                         NB. check years from 2008 to 2121

2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118</lang>

Java

<lang java>import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar;

public class Yuletide{ public static void main(String[] args) { for(int i = 2008;i<=2121;i++){ Calendar cal = new GregorianCalendar(i, Calendar.DECEMBER, 25); if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){ System.out.println(cal.getTime()); } } } }</lang>

Output:
Sun Dec 25 00:00:00 CST 2011
Sun Dec 25 00:00:00 CST 2016
Sun Dec 25 00:00:00 CST 2022
Sun Dec 25 00:00:00 CST 2033
Sun Dec 25 00:00:00 CST 2039
Sun Dec 25 00:00:00 CST 2044
Sun Dec 25 00:00:00 CST 2050
Sun Dec 25 00:00:00 CST 2061
Sun Dec 25 00:00:00 CST 2067
Sun Dec 25 00:00:00 CST 2072
Sun Dec 25 00:00:00 CST 2078
Sun Dec 25 00:00:00 CST 2089
Sun Dec 25 00:00:00 CST 2095
Sun Dec 25 00:00:00 CST 2101
Sun Dec 25 00:00:00 CST 2107
Sun Dec 25 00:00:00 CST 2112
Sun Dec 25 00:00:00 CST 2118

JavaScript

ES5

Iteration

<lang javascript>for (var year = 2008; year <= 2121; year++){

   var xmas = new Date(year, 11, 25)
   if ( xmas.getDay() === 0 )
       console.log(year)

}</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Functional composition

<lang JavaScript>(function () {

   'use strict';
   // isXmasSunday :: Integer -> Bool
   function isXmasSunday(year) {
       return (new Date(year, 11, 25))
           .getDay() === 0;
   }
   // range :: Int -> Int -> [Int]
   function range(m, n) {
       return Array.apply(null, Array(n - m + 1))
           .map(function (_, i) {
               return m + i;
           });
   }
   return range(2008, 2121)
       .filter(isXmasSunday);

})();</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 
2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

ES6

<lang JavaScript>(() => {

   "use strict";
   // main :: IO ()
   const main = () => {
       const
           xs = enumFromTo(2008)(2121)
           .filter(xmasIsSunday);
       return (
           console.log(xs),
           xs
       );
   };


   // xmasIsSunday :: Int -> Bool
   const xmasIsSunday = year =>
       (new Date(year, 11, 25))
       .getDay() === 0;


   // enumFromTo :: Int -> Int -> [Int]
   const enumFromTo = m =>
       n => Array.from({
           length: 1 + n - m
       }, (_, i) => m + i);
   // MAIN ---
   return main();

})();</lang>

Output:

<lang JavaScript>[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]</lang>

jq

<lang jq># Use Zeller's Congruence to determine the day of the week, given

  1. year, month and day as integers in the conventional way.
  2. If iso == "iso" or "ISO", then emit an integer in 1 -- 7 where
  3. 1 represents Monday, 2 Tuesday, etc;
  4. otherwise emit 0 for Saturday, 1 for Sunday, etc.

def day_of_week(year; month; day; iso):

 if month == 1 or month == 2 then
   [month + 12, year - 1]
 else
   [month, year]
 end 
 | day + (13*(.[0] + 1)/5|floor)
   +  (.[1]%100)       + ((.[1]%100)/4|floor)
   +  (.[1]/400|floor) - 2*(.[1]/100|floor) 
 | if iso == "iso" or iso == "ISO" then 1 + ((. + 5) % 7)
   else . % 7
   end;</lang>

The task: <lang jq># Give the results as an array so they can

  1. readily be presented on a single line:

[range(2008; 2122) | select( day_of_week(.;12;25;0) == 1 )]</lang>

Output:
$ jq -n -c -f zeller.jq
[2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118]

Jsish

Jsi does not yet implement the Javascript Date object. strftime' and strptime functions are used here instead.

<lang javascript>/* Day of the week, December 25th on a Sunday */ for (var year = 2008; year <= 2121; year++) {

   var xmas = strptime(year + '/12/25', '%Y/%m/%d');
   var weekDay = strftime(xmas, '%w');
   if (weekDay == 0) puts(year);

}

/*

!EXPECTSTART!

2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

!EXPECTEND!

  • /</lang>
Output:
prompt$ jsish -u dayOfTheWeek.jsi
[PASS] dayOfTheWeek.jsi

Julia

<lang julia>using Dates

lo, hi = 2008, 2121 xmas = collect(Date(lo, 12, 25):Year(1):Date(hi, 12, 25)) filter!(xmas) do dt

   dayofweek(dt) == Dates.Sunday

end

println("Years from $lo to $hi having Christmas on Sunday: ") foreach(println, year.(xmas))</lang>

Output:
Years from 2008 to 2121 having Christmas on Sunday: 
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

K

<lang K> wd:{(__jd x)!7} / Julian day count, Sun=6

   y@&6={wd 1225+x*10000}'y:2008+!114

2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118 </lang>

Kotlin

<lang scala>// version 1.0.6

import java.util.*

fun main(args: Array<String>) {

   println("Christmas day in the following years falls on a Sunday:\n")
   val calendar = GregorianCalendar(2008, Calendar.DECEMBER, 25)
   for (year in 2008..2121) {
       if (Calendar.SUNDAY == calendar[Calendar.DAY_OF_WEEK]) println(year)
       calendar.add(Calendar.YEAR, 1)
   }

}</lang>

Output:
Christmas day in the following years falls on a Sunday:

2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Lasso

<lang lasso>loop(-From=2008, -to=2121) => {^

 local(tDate = date('12/25/' + loop_count))
 #tDate->dayOfWeek == 1 ? '\r' + #tDate->format('%D') + ' is a Sunday'

^}</lang>

Output:
12/25/2011 is a Sunday
12/25/2016 is a Sunday
12/25/2022 is a Sunday
12/25/2033 is a Sunday
12/25/2039 is a Sunday
12/25/2044 is a Sunday
12/25/2050 is a Sunday
12/25/2061 is a Sunday
12/25/2067 is a Sunday
12/25/2072 is a Sunday
12/25/2078 is a Sunday
12/25/2089 is a Sunday
12/25/2095 is a Sunday
12/25/2101 is a Sunday
12/25/2107 is a Sunday
12/25/2112 is a Sunday
12/25/2118 is a Sunday

Liberty BASIC

<lang lb> count = 0

   for year = 2008 to 2121
       dateString$="12/25/";year
       dayNumber=date$(dateString$)
       if dayNumber mod 7 = 5 then
           count = count + 1
           print dateString$
       end if
   next year
   print count; " years when Christmas Day falls on a Sunday"
   end</lang>

Lingo

<lang lingo>put "December 25 is a Sunday in:" refDateObj = date(1905,1,2) repeat with year = 2008 to 2121

 dateObj = date(year, 12, 25)
 dayOfWeek = ((dateObj - refDateObj) mod 7)+1 -- 1=Monday..7=Sunday
 if dayOfWeek=7 then put year

end repeat</lang>

Output:
-- "December 25 is a Sunday in:"
-- 2011
-- 2016
-- 2022
-- 2033
-- 2039
-- 2044
-- 2050
-- 2061
-- 2067
-- 2072
-- 2078
-- 2089
-- 2095
-- 2101
-- 2107
-- 2112
-- 2118

LiveCode

<lang LiveCode>function xmasSunday startDate endDate

   convert the long date to dateitems
   put it into xmasDay
   put 12 into item 2 of xmasDay
   put 25 into item 3 of xmasDay
   repeat with i = startDate to endDate
       put i into item 1 of xmasDay
       convert xmasDay to dateItems
       if item 7 of xmasDay is 1 then put i & comma after xmasYear
   end repeat
   if the last char of xmasYear is comma then delete the last char of xmasYear
   return xmasYear

end xmasSunday</lang>Example<lang LiveCode>put xmasSunday(2008,2121)</lang>Output

2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118

<lang Logo>; Determine if a Gregorian calendar year is leap to leap? :year

 output (and 
   equal? 0 modulo :year 4
   not member? modulo :year 400 [100 200 300]
 )

end

Convert Gregorian calendar date to a simple day count from
day 1 = January 1, 1 CE

to day_number :year :month :day

 local "elapsed make "elapsed difference :year 1
 output (sum  product 365 :elapsed
             int quotient :elapsed 4
             minus int quotient :elapsed 100
             int quotient :elapsed 400
             int quotient difference product 367 :month 362 12
             ifelse lessequal? :month 2 0 ifelse leap? :year -1 -2
             :day)

end

Find the day of the week from a day number; 0 = Sunday through 6 = Saturday

to day_of_week :day_number

 output modulo :day_number 7

end

True if the given day is a Sunday

to sunday? :year :month :day

 output equal? 0 day_of_week day_number :year :month :day

end

Put it all together to answer the question posed in the problem

print filter [sunday? ? 12 25] iseq 2008 2121 bye</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Lua

Library: LuaDate

<lang Lua>require("date")

for year=2008,2121 do

  if date(year, 12, 25):getweekday() == 1 then
     print(year)
  end

end</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Without external modules

Same output as above <lang Lua>local dTab = {day = 25, month = 12} for year = 2008, 2121 do

   dTab.year = year
   if os.date("%A", os.time(dTab)) == "Sunday" then
       print(year)
   end

end</lang>

M2000 Interpreter

Str$( number, format$) use Visual Basic 6 format <lang M2000 Interpreter> Print "December 25 is a Sunday in:" For Year=2008 to 2121 {

     if  Str$(Date("25/12/"+str$(Year,"")),"w")="1" Then {
           Print Year
     }

} \\ is the same with this: Print "December 25 is a Sunday in:" For Year=2008 to 2121 {

     if  Str$(Date(str$(Year,"")+"-12-25"),"w")="1" Then {
           Print Year
     }

}


</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

M4

<lang M4>divert(-1)

define(`for',

  `ifelse($#,0,``$0,
  `ifelse(eval($2<=$3),1,
  `pushdef(`$1',$2)$4`'popdef(`$1')$0(`$1',incr($2),$3,`$4')')')')

dnl julian day number corresponding to December 25th of given year define(`julianxmas',

  `define(`yrssince0',eval($1+4712))`'define(`noOfLpYrs',
     eval((yrssince0+3)/4))`'define(`jd',
     eval(365*yrssince0+noOfLpYrs-10-($1-1501)/100+($1-1201)/400+334+25-1))`'
     ifelse(eval($1%4==0 && ($1%100!=0 || $1%400==0)),1,
        `define(`jd',incr(jd))')`'jd')

divert

for(`yr',2008,2121,

  `ifelse(eval(julianxmas(yr)%7==6),1,`yr ')')</lang>
Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112
2118

Maple

<lang Maple>xmas:= proc() local i, dt; for i from 2008 to 2121 by 1 do dt := Date(i, 12, 25); if (Calendar:-DayOfWeek(dt) = 1) then print(i); end if; end do; end proc;

xmas();</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Or simply:

<lang maple>select(y->Calendar:-DayOfWeek(Date(y,12,25))=1,[$2008..2121]);</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

Mathematica / Wolfram Language

<lang Mathematica>Reap[If[DateString[{#,12,25},"DayName"]=="Sunday",Sow[#]]&/@Range[2008,2121]]2,1</lang> gives back: <lang Mathematica>{2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118}</lang>

MATLAB / Octave

<lang Matlab> t = datenum([[2008:2121]',repmat([12,25,0,0,0], 2121-2007, 1)]);

 t  = t(strmatch('Sunday', datestr(t,'dddd')), :);
 datestr(t,'yyyy')		

</lang>


Output:
 ans =
  2011
  2016
  2022
  2033
  2039
  2044
  2050
  2061
  2067
  2072
  2078
  2089
  2095
  2101
  2107
  2112
  2118

Maxima

<lang maxima>weekday(year, month, day) := block([m: month, y: year, k],

  if m < 3 then (m: m + 12, y: y - 1),
  k: 1 + remainder(day + quotient((m + 1)*26, 10) + y + quotient(y, 4)
       + 6*quotient(y, 100) + quotient(y, 400) + 5, 7),
  ['monday, 'tuesday, 'wednesday, 'thurdsday, 'friday, 'saturday, 'sunday][k]

)$

sublist(makelist(i, i, 2008, 2121),

       lambda([y], weekday(y, 12, 25) = 'sunday));

/* [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118] */</lang>

МК-61/52

<lang>П9 7 П7 1 П8 НОП ИП8 2 2 - 1 0 / [x] П6 ИП9 + 1 8 9 9 - 3 6 5 , 2 5 * [x] ИП8 ИП6 1 2 * - 1 4 - 3 0 , 5 9 * [x] + 2 9 + ИП7 + П4 ИП4 7 / [x] 7 * - x=0 64 ИП9 С/П ИП9 1 + П9 БП 06</lang>

Input: РX: starting year.

Output: the year in which Christmas falls on a Sunday. For example, enter 2008, the first result: 2018 (January 7, 2018 is Sunday).

Modula-3

Translation of: C

Modula-3 represents time using a (safe) wrapper around the C time interface. Consequently, it suffers from the same problem as C.

<lang modula3>MODULE Yule EXPORTS Main;

IMPORT IO, Fmt, Date, Time;

VAR date: Date.T;

   time: Time.T;

BEGIN

 FOR year := 2008 TO 2121 DO
   date.day := 25;
   date.month := Date.Month.Dec;
   date.year := year;
   TRY
     time := Date.ToTime(date);
   EXCEPT
   | Date.Error => 
     IO.Put(Fmt.Int(year) & " is the last year we can specify\n");
     EXIT;
   END;
   date := Date.FromTime(time);
   IF date.weekDay = Date.WeekDay.Sun THEN
     IO.Put("25th of December " & Fmt.Int(year) & " is Sunday\n");
   END;
 END;

END Yule.</lang>

Output:
25th of December 2011 is Sunday
25th of December 2016 is Sunday
25th of December 2022 is Sunday
25th of December 2033 is Sunday
2038 is the last year we can specify

MUMPS

Library: VA Kernel version 22.0

<lang MUMPS> DOWHOLIDAY

;In what years between 2008 and 2121 will December 25 be a Sunday?
;Uses the VA's public domain routine %DTC (Part of the Kernel) named here DIDTC
NEW BDT,EDT,CHECK,CHKFOR,LIST,I,X,Y
;BDT - the beginning year to check
;EDT - the end year to check
;BDT and EDT are year offsets from the epoch date 1/1/1700
;CHECK - the month and day to look at
;CHKFOR - what day of the week to look for
;LIST - list of years in which the condition is true
;I - the year currently being checked
;X - the date in an "internal" format, for input to DOW^DIDTC
;Y - the output from DOW^DIDTC
SET BDT=308,EDT=421,CHECK="1225",CHKFOR=0,LIST=""
FOR I=BDT:1:EDT SET X=I_CHECK D DOW^DIDTC SET:(Y=0) LIST=$SELECT($LENGTH(LIST):LIST_", ",1:"")_(I+1700)
IF $LENGTH(LIST)=0 WRITE !,"There are no years that have Christmas on a Sunday in the given range."
IF $LENGTH(LIST) WRITE !,"The following years have Christmas on a Sunday: ",LIST
KILL BDT,EDT,CHECK,CHKFOR,LIST,I,X,Y
QUIT

</lang>Usage:

USER>D ^DOW
 
The following years have Christmas on a Sunday: 2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118

Nanoquery

<lang Nanoquery>import Nanoquery.Util

// loop through the years 2008 through 2121 for year in range(2008, 2121) if (new(Date,"12/25/" + str(year)).getDayOfWeek() = "Sunday") println "In " + year + ", December 25th is a Sunday." end if end for</lang>

NetRexx

<lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols nobinary

yearRanges = [int 2008, 2121] searchday = cal = Calendar

loop year = yearRanges[0] to yearRanges[1]

 cal = GregorianCalendar(year, Calendar.DECEMBER, 25)
 dayIndex = cal.get(Calendar.DAY_OF_WEEK)
 if dayIndex = Calendar.SUNDAY then searchday = searchday year
 end year

say 'Between' yearRanges[0] 'and' yearRanges[1]', Christmas day falls on a Sunday on the following years:' searchday = searchday.strip.changestr(' ', ',') say ' 'searchday

return </lang>

Output:
Between 2008 and 2121, Christmas day falls on a Sunday on the following years:
  2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118

Comparison of Some Common Day-of-Week Algorithms

The following program exercises some common "Day-0f-Week" algorithms to confirm they all arrive at the same result. <lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols nobinary

days = 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday' yearRanges = [int 2008, 2121]

searchday = searchday['index'] = days.wordpos('Sunday') searchday[0] = 0

algorithmName = ['Java Calendar', 'Zeller[1]', 'Zeller[2]', 'Sakamoto', 'Gauss', 'Keith', 'Babwani']

loop alg = 0 to algorithmName.length - 1

 sd = searchday[0] + 1
 searchday[0] = sd
 searchday['agorithm', sd] = algorithmName[alg]
 loop year = yearRanges[0] to yearRanges[1]
   select case alg
     when 0 then dayIndex = getDaynumJavaLibrary(year, 12, 25)
     when 1 then dayIndex = getDaynumZellersCongruenceMethod1(year, 12, 25)
     when 2 then dayIndex = getDaynumZellersCongruenceMethod2(year, 12, 25)
     when 3 then dayIndex = getDaynumSakamoto(year, 12, 25)
     when 4 then dayIndex = getDaynumGauss(year, 12, 25)
     when 5 then dayIndex = getDaynumKeith(year, 12, 25)
     when 6 then dayIndex = getDaynumBabwani(year, 12, 25)
     otherwise nop
     end
   if dayIndex = searchday['index'] then
     searchday[sd] = searchday[sd] year
   end year
 end alg

-- display results say 'Between' yearRanges[0] 'and' yearRanges[1]', Christmas day falls on a Sunday in the following years:' loop r_ = 1 to searchday[0]

 searchday[r_] = searchday[r_].strip.changestr(' ', ',')
 say searchday['agorithm', r_].right(20)':' searchday[r_]
 end r_

return

-- ----------------------------------------------------------------------------- method getDaynumJavaLibrary(Year = int, Month = int, Day = int, iso = Rexx 'Y') public static binary returns int

 -- The day-of-week is an integer value where 1 is Sunday, 2 is Monday, ..., and 7 is Saturday
 -- For an ISO week date Day-of-Week d (1 = Monday to 7 = Sunday), use d = ((h - 1 + 6) mod 7) + 1
 cal = Calendar
 jmNumber = [ -
     Calendar.JANUARY,   Calendar.FEBRUARY, Calendar.MARCH,    Calendar.APRIL    -
   , Calendar.MAY,       Calendar.JUNE,     Calendar.JULY,     Calendar.AUGUST   -
   , Calendar.SEPTEMBER, Calendar.OCTOBER,  Calendar.NOVEMBER, Calendar.DECEMBER -
   ]
 mon = jmNumber[Month - 1]
 cal = GregorianCalendar(Year, mon, Day)
 h   = cal.get(Calendar.DAY_OF_WEEK)
 if 'YES'.abbrev(iso.upper, 1) then w = ((h - 1 + 6) // 7) + 1
                               else w = h
 return w

-- ----------------------------------------------------------------------------- method getDaynumZellersCongruenceMethod1(Year = int, Month = int, Day = int, iso = Rexx 'Y') public static returns int

 -- DayNum results in an integer in the range 0-6 where 0 represents Monday etc.
 -- For an ISO week date add 1
 if Month = 1 | Month = 2 then do
   Month = Month + 12
   Year  = Year - 1
   end
 MonthFactor = 2 * Month + 3 * (Month + 1) % 5
 YearFactor  = Year + Year % 4 - Year % 100 + Year % 400
 DayNum      = (Day + MonthFactor + YearFactor) // 7
 if 'YES'.abbrev(iso.upper, 1) then d = DayNum + 1
                               else d = DayNum
 return d

-- ----------------------------------------------------------------------------- method getDaynumZellersCongruenceMethod2(Year = int, Month = int, Day = int, iso = Rexx 'Y') public static binary returns int

 -- h is the day of the week (0 = Saturday, 1 = Sunday, 2 = Monday, ...)
 -- For an ISO week date Day-of-Week d (1 = Monday to 7 = Sunday), use d = ((h + 5) mod 7) + 1
 if Month < 3 then do
   Month = Month + 12
   Year  = Year - 1
   end
 q = Day
 m = Month
 Y = Year
 h = (q + ((m + 1) * 26 % 10) + Y + (Y % 4) + 6 * (Y % 100) + (Y % 400)) // 7
 if 'YES'.abbrev(iso.upper, 1) then d = ((h + 5) // 7) + 1
                               else d = h
 return d

-- ----------------------------------------------------------------------------- method getDaynumSakamoto(y = int, m = int, d = int, iso = Rexx 'Y') public static binary returns int

 -- h is the day of the week (0 = Sunday, 1 = Monday, 2 = Tuesday...)
 -- For an ISO week date Day-of-Week d (1 = Monday to 7 = Sunday), use d = ((h + 6) mod 7) + 1
 t = [int 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
 y = y - (m < 3)
 h = (y + y % 4 - y % 100 + y % 400 + t[m - 1] + d) // 7
 if 'YES'.abbrev(iso.upper, 1) then d = ((h + 6) // 7) + 1
                               else d = h
 return d

-- ----------------------------------------------------------------------------- method getDaynumGauss(Year = int, Month = int, Day = int, iso = Rexx 'Y') public static binary returns int

 -- W is week day (0 = Sunday, ..., 6 = Saturday)
 -- For an ISO week date Day-of-Week d (1 = Monday to 7 = Sunday), use d = ((h + 6) mod 7) + 1
 Year = Year - (Month < 3)
 k = double Day
 C = double Year % 100
 Y = double Year // 100
 m = double ((Month + 9) // 12) + 1
 W = modulo(int (k + Math.floor(2.6 * m - 0.2) + y + Math.floor(y / 4) + Math.floor(c / 4) - 2 * c), 7)
 if 'YES'.abbrev(iso.upper, 1) then h = ((W + 6) // 7) + 1
                               else h = W
 return h

-- ----------------------------------------------------------------------------- method getDaynumKeith(y = int, m = int, d = int, iso = Rexx 'Y') public constant binary returns int

 -- W is week day (0 = Sunday, ..., 6 = Saturday)
 -- For an ISO week date Day-of-Week d (1 = Monday to 7 = Sunday), use d = ((h + 6) mod 7) + 1
 if m < 3 then do
   d = d + y
   y = y - 1
   end
 else do
   d = d + y - 2
   end
 h = (23 * m % 9 + d + 4 + y % 4 - y % 100 + y % 400) // 7
 if 'YES'.abbrev(iso.upper, 1) then W = ((h + 6) // 7) + 1
                               else W = h
 return W

-- ----------------------------------------------------------------------------- method getDaynumBabwani(Year = int, Month = int, Day = int, iso = Rexx 'Y') public constant binary returns int

 -- return dow = Day of week: 0 = Saturday, 1 = Sunday, ... 6 = Friday
 -- For an ISO week date Day-of-Week W (1 = Monday to 7 = Sunday), use W = ((dow + 5) mod 7) + 1
 y = Year
 m = Month
 d = Day
 dow    = int -- dow stands for day of week
 dowfg  = double
 fmonth = int
 leap   = int
 if ((y // 100 == 0) & (y // 400 \= 0)) then  -- leap function 1 for leap & 0 for non-leap
   leap = 0
 else if (y // 4 == 0) then
   leap = 1
 else
   leap = 0
 fmonth = 3 + (2 - leap) * ((m + 2) % (2 * m)) + (5 * m + m % 9) % 2 -- f(m) formula
 fmonth = fmonth // 7 -- f(m) is brought in range of 0 to 6
 century    = y % 100
 lastdigits = y // 100
 dowfg = 1.25 * lastdigits + fmonth + d - 2 * (century // 4) -- function of weekday for Gregorian
 dow = int dowfg // 7 -- remainder on division by 7
 if 'YES'.abbrev(iso.upper, 1) then W = ((dow + 5) // 7) + 1
                               else W = dow
 return W

-- ----------------------------------------------------------------------------- method modulo(N = int, D = int) inheritable static binary returns int

 return (D + (N // D)) // D

</lang>

Output:
Between 2008 and 2121, Christmas day falls on a Sunday in the following years:
       Java Calendar: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
           Zeller[1]: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
           Zeller[2]: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
            Sakamoto: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
               Gauss: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
               Keith: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118
             Babwani: 2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118

Nim

<lang nim>import times

for year in 2008..2121:

 if getDayOfWeek(25, mDec, year) == dSun:
   stdout.write year, ' '

echo ""</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118 

Oberon-2

Works with: oo2c version 2

<lang oberon2> MODULE DayOfWeek; IMPORT NPCT:Dates, Out; VAR

 year: INTEGER;
 date: Dates.Date;

BEGIN

 FOR year := 2008 TO 2121 DO
   date := Dates.NewDate(25,12,year);
   IF date.DayOfWeek() = Dates.sunday THEN
    Out.Int(date.year,4);Out.Ln
   END
 END

END DayOfWeek. </lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118
Works with: AOS

<lang Oberon2> MODULE DaysOfWeek; (** AUTHOR ""; PURPOSE ""; *)

IMPORT Out := KernelLog, Dates;

PROCEDURE Do*; VAR date: Dates.DateTime; i,y,w,wd: LONGINT; BEGIN FOR i := 2008 TO 2121 DO date.year := i;date.month :=12; date.day := 25; date.hour := 0;date.minute := 0; date.second := 0; Dates.WeekDate(date,y,w,wd); IF wd = 7 THEN Out.Int(i,0);Out.Ln END END END Do;

END DaysOfWeek. </lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Objective-C

Works with: GNUstep
Works with: Cocoa

<lang objc>#import <Foundation/Foundation.h>

int main() {

  @autoreleasepool {
     for(NSUInteger i=2008; i<2121; i++)
     {
        NSCalendarDate *d = [[NSCalendarDate alloc] 
                             initWithYear: i
                             month: 12
                             day: 25
                             hour: 0 minute: 0 second:0 
                             timeZone: [NSTimeZone timeZoneWithAbbreviation:@"CET"] ];
        if ( [d dayOfWeek] == 0 )
        {  
           printf("25 Dec %u is Sunday\n", i);
        }
     }
  
  }
  return 0;

}</lang>

Output:
25 Dec 2011 is Sunday
25 Dec 2016 is Sunday
25 Dec 2022 is Sunday
25 Dec 2033 is Sunday
25 Dec 2039 is Sunday
25 Dec 2044 is Sunday
25 Dec 2050 is Sunday
25 Dec 2061 is Sunday
25 Dec 2067 is Sunday
25 Dec 2072 is Sunday
25 Dec 2078 is Sunday
25 Dec 2089 is Sunday
25 Dec 2095 is Sunday
25 Dec 2101 is Sunday
25 Dec 2107 is Sunday
25 Dec 2112 is Sunday
25 Dec 2118 is Sunday

OCaml

Translation of: C

<lang ocaml>#load "unix.cma" open Unix

try

 for i = 2008 to 2121 do
   (* I'm lazy so we'll just borrow the current time
      instead of having to set all the fields explicitly *)
   let mytime = { (localtime (time ())) with
                  tm_year  = i - 1900;
                  tm_mon   = 11;
                  tm_mday  = 25 } in
   try
     let _, mytime = mktime mytime in
       if mytime.tm_wday = 0 then
         Printf.printf "25 December %d is Sunday\n" i
   with e ->
     Printf.printf "%d is the last year we can specify\n" (i-1);
     raise e
 done

with _ -> ()</lang>

Output:

of a run on a 32 bit machine

25 December 2011 is Sunday
25 December 2016 is Sunday
25 December 2022 is Sunday
25 December 2033 is Sunday
2037 is the last year we can specify

With a dedicated library

Unlike the previous example which only uses the OCaml standard library, here with the OCaml Calendar Library we can go until the year 2121:

<lang ocaml>open CalendarLib

let list_make_seq first last =

 let rec aux i acc =
   if i < first then acc
   else aux (pred i) (i::acc)
 in
 aux last []

let print_date (year, month, day) =

 Printf.printf "%d-%02d-%02d\n" year month day

let () =

 let years = list_make_seq 2008 2121 in
 let years = List.filter (fun year ->
   Date.day_of_week (Date.make year 12 25) = Date.Sun) years in
 print_endline "December 25 is a Sunday in:";
 List.iter (Printf.printf "%d\n") years</lang>
Output:
$ ocaml unix.cma str.cma -I +calendar calendarLib.cma xmas_sundays.ml
December 25 is a Sunday in:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Oforth

<lang Oforth>import: date seqFrom(2008, 2121) filter(#[ 12 25 Date newDate dayOfWeek Date.SUNDAY == ]) .</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

ooRexx

Christmas

<lang ooRexx>date = .datetime~new(2008, 12, 25) lastdate = .datetime~new(2121, 12, 25)

resultList = .array~new -- our collector of years

-- date objects are directly comparable loop while date <= lastdate

 if date~weekday == 7 then resultList~append(date~year)
 -- step to the next year
 date = date~addYears(1)

end

say "Christmas falls on Sunday in the years" resultList~toString("Line", ", ")</lang>

Output:
Christmas falls on Sunday in the years 2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118

Weekday

<lang ooRexx>/* REXX */ Parse Arg yyyymmdd If arg(1)= |,

  arg(1)='?' Then Do
 Say 'rexx wd yyyymmdd will show which weekday that is'
 Exit
 End

Parse Var yyyymmdd y +4 m +2 d wd=.Array~of('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday') dt=.DateTime~new(y,m,d) say yyyymmdd 'is a' wd[dt~weekday]</lang>

Output:
H:\>rexx wd ?
rexx wd yyyymmdd will show which weekday that is

H:\>rexx wd 20211206
20211206 is a Monday 

PARI/GP

<lang parigp> njd(D) = {

 my (m, y);
 if (D[2] > 2, y = D[1]; m = D[2]+1, y = D[1]-1; m = D[2]+13);
 (1461*y)\4 + (306001*m)\10000 + D[3] - 694024 + if (100*(100*D[1]+D[2])+D[3] > 15821004, 2 - y\100 + y\400)

}

for (y = 2008, 2121, if (njd([y,12,25]) % 7 == 1, print(y))); </lang>

Output:

2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Pascal

Library: sysutils
Works with: Free Pascal

See Delphi

Peloton

<lang sgml><@ SAI> <@ ITEFORLI3>2121|2008| <@ LETVARCAP>Christmas Day|25-Dec-<@ SAYVALFOR>...</@></@> <@ TSTDOWVARLIT>Christmas Day|1</@> <@ IFF> <@ SAYCAP>Christmas Day <@ SAYVALFOR>...</@> is a Sunday</@><@ SAYKEY>__Newline</@> </@> </@> </@></lang>

English dialect variable-length space-padded opcodes <lang html><# suppressimplicitoutput> <# iterate foriteration literalstring3>2121|2008| <# let variable capture>Christmas Day|25-Dec-<# say value foriteration>...</#></#> <# test dayofweek variable literal>Christmas Day|1</#> <# if> <# say capture>Christmas Day <# say value foriteration>...</#> is a Sunday</#><# say keyword>__Newline</#> </#> </#>

</#></lang>

Output:
Christmas Day 2011 is a Sunday
Christmas Day 2016 is a Sunday
Christmas Day 2022 is a Sunday
Christmas Day 2033 is a Sunday
Christmas Day 2039 is a Sunday
Christmas Day 2044 is a Sunday
Christmas Day 2050 is a Sunday
Christmas Day 2061 is a Sunday
Christmas Day 2067 is a Sunday
Christmas Day 2072 is a Sunday
Christmas Day 2078 is a Sunday
Christmas Day 2089 is a Sunday
Christmas Day 2095 is a Sunday
Christmas Day 2101 is a Sunday
Christmas Day 2107 is a Sunday
Christmas Day 2112 is a Sunday
Christmas Day 2118 is a Sunday

Perl

<lang perl>#! /usr/bin/perl -w

use Time::Local; use strict;

foreach my $i (2008 .. 2121) {

 my $time = timelocal(0,0,0,25,11,$i);
 my ($s,$m,$h,$md,$mon,$y,$wd,$yd,$is) = localtime($time);
 if ( $wd == 0 )
 {
   print "25 Dec $i is Sunday\n";
 }

}

exit 0;</lang>

Output:
25 Dec 2011 is Sunday
25 Dec 2016 is Sunday
25 Dec 2022 is Sunday
25 Dec 2033 is Sunday
Day too big - 25195 > 24855
Sec too small - 25195 < 78352
Sec too big - 25195 > 15247
Cannot handle date (0, 0, 0, 25, 11, 2038) at ./ydate.pl line 8

Using the DateTime module from CPAN: <lang perl>#! /usr/bin/perl -w

use DateTime; use strict;

foreach my $i (2008 .. 2121) {

 my $dt = DateTime->new( year   => $i,
                         month  => 12,
                         day    => 25
                       );
 if ( $dt->day_of_week == 7 )
 {
   print "25 Dec $i is Sunday\n";
 }

}

exit 0;</lang> or shorter: <lang perl>#! /usr/bin/perl -w

use DateTime; use strict;

for (2008 .. 2121) {

 print "25 Dec $_ is Sunday\n"
   if DateTime->new(year => $_, month => 12, day => 25)->day_of_week == 7;

}

exit 0;</lang>

Output:
25 Dec 2011 is Sunday
25 Dec 2016 is Sunday
25 Dec 2022 is Sunday
25 Dec 2033 is Sunday
25 Dec 2039 is Sunday
25 Dec 2044 is Sunday
25 Dec 2050 is Sunday
25 Dec 2061 is Sunday
25 Dec 2067 is Sunday
25 Dec 2072 is Sunday
25 Dec 2078 is Sunday
25 Dec 2089 is Sunday
25 Dec 2095 is Sunday
25 Dec 2101 is Sunday
25 Dec 2107 is Sunday
25 Dec 2112 is Sunday
25 Dec 2118 is Sunday

Alternatively in one line using grep (read from right to left): <lang perl>#! /usr/bin/perl -w

use DateTime; use strict;

print join " ", grep { DateTime->new(year => $_, month => 12, day => 25)->day_of_week == 7 } (2008 .. 2121);

0;</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Phix

Library: Phix/basics
-- demo\rosetta\Day_of_the_week.exw
sequence res = {}
for y=2008 to 2121 do
    if day_of_week(y,12,25,true)="Sunday" then
        res = append(res,y)
    end if
end for
?res
Output:
{2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118}

PHP

<lang php><?php for($i=2008; $i<2121; $i++) {

 $datetime = new DateTime("$i-12-25 00:00:00");
 if ( $datetime->format("w") == 0 )
 {
    echo "25 Dec $i is Sunday\n";
 }

} ?></lang>

Output:
25 Dec 2011 is Sunday
25 Dec 2016 is Sunday
25 Dec 2022 is Sunday
25 Dec 2033 is Sunday
25 Dec 2039 is Sunday
25 Dec 2044 is Sunday
25 Dec 2050 is Sunday
25 Dec 2061 is Sunday
25 Dec 2067 is Sunday
25 Dec 2072 is Sunday
25 Dec 2078 is Sunday
25 Dec 2089 is Sunday
25 Dec 2095 is Sunday
25 Dec 2101 is Sunday
25 Dec 2107 is Sunday
25 Dec 2112 is Sunday
25 Dec 2118 is Sunday

Picat

<lang Picat>go =>

  L = [Year : Year in 2008..2121, dow(Year, 12, 25) == 0],
  println(L), 
  println(len=L.length),
  nl.

% Day of week, Sakamoto's method dow(Y, M, D) = R =>

 T = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4],
 if M < 3 then
    Y := Y - 1
 end,
 R = (Y + Y // 4 - Y // 100 + Y // 400 + T[M] + D) mod 7.

</lang>

Output:
[2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118]
len = 17

PicoLisp

<lang PicoLisp>(for (Y 2008 (>= 2121 Y) (inc Y))

  (when (= "Sunday" (day (date Y 12 25)))
     (printsp Y) ) )</lang>
Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Pike

<lang Pike>filter(Calendar.Year(2008)->range(Calendar.Year(2121))->years()->month(12)->day(25), lambda(object day){ return day->week_day()==7; })->year()->format_nice();</lang>

Output:
 Result: ({ /* 17 elements */
                 "2011",
                 "2016",
                 "2022",
                 "2033",
                 "2039",
                 "2044",
                 "2050",
                 "2061",
                 "2067",
                 "2072",
                 "2078",
                 "2089",
                 "2095",
                 "2101",
                 "2107",
                 "2112",
                 "2118"
             })

PL/I

<lang PL/I> declare i picture '9999'; do i = 2008 to 2121;

  if weekday(days('25Dec' || i, 'DDMmmYYYY')) = 1 then
     put skip list ('Christmas day ' || i || ' is a Sunday');

end; </lang>

PL/I-80

<lang PL/I>/* Test of PL/I-80 routine to determine day of the week */

sunday_christmas:

   proc options (main);
   %replace
     sunday by 0;
   dcl
       (year, w) fixed bin(15);
   put skip list ('Christmas will fall on Sunday in these years:');
   do year = 2008 to 2121;
       w = weekday((year),12,25);
       if w = sunday then
          put skip edit (year) (f(4));
   end;
   stop;

/*

  • Return day of week (Sun=0, Mon=1, etc.) for a given
  • yr, mo, da using Zeller's congruence
  • /

weekday:

   proc (yr, mo, da) returns (fixed bin(15));
   dcl (yr, mo, da) fixed bin(15);
   dcl (c, y, m, d, z) fixed bin(15);
   y = yr;  /* make local copies */
   m = mo;
   d = da;
   if m < 3 then
       do;
           m = m + 10;
           y = y - 1;
       end;
   else m = m - 2;
   c = y / 100;
   y = mod(y, 100);  
   z = (26 * m - 2) / 10;
   z = z + d + y + (y/4) + (c/4) - 2 * c + 777;
   return (mod(z, 7));

end weekday;

end sunday_christmas; </lang>

Output:
Christmas will fall on Sunday in these years:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

PowerShell

<lang powershell>2008..2121 | Where-Object { (Get-Date $_-12-25).DayOfWeek -eq "Sunday" }</lang>

Find Christmas holiday for any day and/or year

<lang PowerShell> function Get-ChristmasHoliday {

   [CmdletBinding()]
   [OutputType([PSCustomObject])]
   Param
   (
       [Parameter(Mandatory=$false,
                  ValueFromPipeline=$true,
                  ValueFromPipelineByPropertyName=$true,
                  Position=0)]
       [ValidateRange(1,9999)]
       [int[]]
       $Year = (Get-Date).Year
   )
   Process
   {
       [datetime]$christmas = Get-Date $Year/12/25
       switch ($christmas.DayOfWeek)
       {
           "Sunday"   {[datetime[]]$dates = 1..5 | ForEach-Object {$christmas.AddDays($_)}}
           "Monday"   {[datetime[]]$dates = $christmas, $christmas.AddDays(1)}
           "Saturday" {[datetime[]]$dates = $christmas.AddDays(-2), $christmas.AddDays(-1)}
           Default    {[datetime[]]$dates = $christmas.AddDays(-1), $christmas}
       }
       $dates | Group-Object  -Property Year |
                Select-Object -Property @{Name="Year"     ; Expression={$_.Name}},
                                        @{Name="DayOfWeek"; Expression={$christmas.DayOfWeek}},
                                        @{Name="Christmas"; Expression={$christmas.ToString("MM/dd/yyyy")}},
                                        @{Name="DaysOff"  ; Expression={$_.Group | ForEach-Object {$_.ToString("MM/dd/yyyy")}}}
   }

} </lang> Satisfy the task requirement: <lang PowerShell> 2008..2121 | Get-ChristmasHoliday | where DayOfWeek -match Su </lang>

Output:
Year DayOfWeek Christmas  DaysOff                                            
---- --------- ---------  -------                                            
2011    Sunday 12/25/2011 {12/26/2011, 12/27/2011, 12/28/2011, 12/29/2011...}
2016    Sunday 12/25/2016 {12/26/2016, 12/27/2016, 12/28/2016, 12/29/2016...}
2022    Sunday 12/25/2022 {12/26/2022, 12/27/2022, 12/28/2022, 12/29/2022...}
2033    Sunday 12/25/2033 {12/26/2033, 12/27/2033, 12/28/2033, 12/29/2033...}
2039    Sunday 12/25/2039 {12/26/2039, 12/27/2039, 12/28/2039, 12/29/2039...}
2044    Sunday 12/25/2044 {12/26/2044, 12/27/2044, 12/28/2044, 12/29/2044...}
2050    Sunday 12/25/2050 {12/26/2050, 12/27/2050, 12/28/2050, 12/29/2050...}
2061    Sunday 12/25/2061 {12/26/2061, 12/27/2061, 12/28/2061, 12/29/2061...}
2067    Sunday 12/25/2067 {12/26/2067, 12/27/2067, 12/28/2067, 12/29/2067...}
2072    Sunday 12/25/2072 {12/26/2072, 12/27/2072, 12/28/2072, 12/29/2072...}
2078    Sunday 12/25/2078 {12/26/2078, 12/27/2078, 12/28/2078, 12/29/2078...}
2089    Sunday 12/25/2089 {12/26/2089, 12/27/2089, 12/28/2089, 12/29/2089...}
2095    Sunday 12/25/2095 {12/26/2095, 12/27/2095, 12/28/2095, 12/29/2095...}
2101    Sunday 12/25/2101 {12/26/2101, 12/27/2101, 12/28/2101, 12/29/2101...}
2107    Sunday 12/25/2107 {12/26/2107, 12/27/2107, 12/28/2107, 12/29/2107...}
2112    Sunday 12/25/2112 {12/26/2112, 12/27/2112, 12/28/2112, 12/29/2112...}
2118    Sunday 12/25/2118 {12/26/2118, 12/27/2118, 12/28/2118, 12/29/2118...}

Get days off for a random year: <lang PowerShell> Get-ChristmasHoliday -Year (2008..2121 | Get-Random) </lang>

Output:
Year DayOfWeek Christmas  DaysOff                 
---- --------- ---------  -------                 
2110  Thursday 12/25/2110 {12/24/2110, 12/25/2110}

Get days off for the current year using the Year property returned by Get-Date: <lang PowerShell> (Get-Date | Get-ChristmasHoliday).DaysOff </lang>

Output:
12/26/2016
12/27/2016
12/28/2016
12/29/2016
12/30/2016

Get days off for the current year as [DateTime] objects: <lang PowerShell> (Get-Date | Get-ChristmasHoliday).DaysOff | Get-Date </lang>

Output:
Monday, December 26, 2016 12:00:00 AM
Tuesday, December 27, 2016 12:00:00 AM
Wednesday, December 28, 2016 12:00:00 AM
Thursday, December 29, 2016 12:00:00 AM
Friday, December 30, 2016 12:00:00 AM

Prolog

Works with SWI-Prolog; <lang Prolog>main() :-

   christmas_days_falling_on_sunday(2011, 2121, SundayList),
   writeln(SundayList).

christmas_days_falling_on_sunday(StartYear, EndYear, SundayList) :-

   numlist(StartYear, EndYear, YearRangeList),
   include(is_christmas_day_a_sunday, YearRangeList, SundayList).
   

is_christmas_day_a_sunday(Year) :-

   Date = date(Year, 12, 25),
   day_of_the_week(Date, DayOfTheWeek),
   DayOfTheWeek == 7.

</lang>

Output:
?- main.
[2011,2016,2022,2033,2039,2044,2050,2061,2067,2072,2078,2089,2095,2101,2107,2112,2118]
true.

PureBasic

PureBasic's internal Date() is limited between 1970-01-01 00:00:00 and 2038-01-19 03:14:07 <lang PureBasic>For i=2008 To 2037

 If DayOfWeek(Date(i,12,25,0,0,0))=0
   PrintN(Str(i))
 EndIf

Next</lang>

Python

<lang python>from calendar import weekday, SUNDAY

[year for year in range(2008, 2122) if weekday(year, 12, 25) == SUNDAY]</lang>

Output:
[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

The function calendar.weekday accepts all dates between 1/1/1 and 9999/12/31, and uses the proleptic Gregorian calendar before adoption of the Gregorian calendar in 1582. There is no gap between 1582/10/4 and 1582/10/15, as can be seen with print(calendar.calendar(1582)).


Or, in terms of datetime:

Works with: Python version 3.7

<lang python>Days of the week

from datetime import date from itertools import islice


  1. xmasIsSunday :: Int -> Bool

def xmasIsSunday(y):

   True if Dec 25 in the given year is a Sunday.
   return 6 == date(y, 12, 25).weekday()


  1. main :: IO ()

def main():

   Years between 2008 and 2121 with 25 Dec on a Sunday
   xs = list(filter(
       xmasIsSunday,
       enumFromTo(2008)(2121)
   ))
   total = len(xs)
   print(
       fTable(main.__doc__ + ':\n\n' + '(Total ' + str(total) + ')\n')(
           lambda i: str(1 + i)
       )(str)(index(xs))(
           enumFromTo(0)(total - 1)
       )
   )


  1. GENERIC -------------------------------------------------
  1. enumFromTo :: (Int, Int) -> [Int]

def enumFromTo(m):

   Integer enumeration from m to n.
   return lambda n: list(range(m, 1 + n))


  1. index (!!) :: [a] -> Int -> a

def index(xs):

   Item at given (zero-based) index.
   return lambda n: None if 0 > n else (
       xs[n] if (
           hasattr(xs, "__getitem__")
       ) else next(islice(xs, n, None))
   )


  1. FORMATTING ---------------------------------------------
  2. fTable :: String -> (a -> String) ->
  3. (b -> String) -> (a -> b) -> [a] -> String

def fTable(s):

   Heading -> x display function -> fx display function ->
                    f -> xs -> tabular string.
   
   def go(xShow, fxShow, f, xs):
       ys = [xShow(x) for x in xs]
       w = max(map(len, ys))
       return s + '\n' + '\n'.join(map(
           lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
           xs, ys
       ))
   return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
       xShow, fxShow, f, xs
   )


  1. MAIN --

if __name__ == '__main__':

   main()</lang>
Output:
Years between 2008 and 2121 with 25 Dec on a Sunday:

(Total 17)

 1 -> 2011
 2 -> 2016
 3 -> 2022
 4 -> 2033
 5 -> 2039
 6 -> 2044
 7 -> 2050
 8 -> 2061
 9 -> 2067
10 -> 2072
11 -> 2078
12 -> 2089
13 -> 2095
14 -> 2101
15 -> 2107
16 -> 2112
17 -> 2118

Quackery

Using Tomohiko Sakamoto's algorithm.

<lang Quackery> [ over 3 < if [ 1 - ]

   dup 4 / over +
   over 100 / -
   swap 400 / +
   swap 1 - 
   [ table 
     0 3 2 5 0 3
     5 1 4 6 2 4 ]
   + + 7 mod ]         is dayofweek ( day month year --> weekday )

say "The 25th of December is a Sunday in: " cr 2121 1+ 2008 - times

 [ 25 12 i^ 2008 + dayofweek
   0 = if [ i^ 2008 + echo sp ] ] </lang>
Output:
The 25th of December is a Sunday in: 
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118 

R

<lang R>years <- 2008:2121 xmas <- as.POSIXlt(paste0(years, '/12/25')) years[xmas$wday==0]

  1. 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118
  1. Also:

xmas=seq(as.Date("2008/12/25"), as.Date("2121/12/25"), by="year") as.numeric(format(xmas[weekdays(xmas)== 'Sunday'], "%Y"))

  1. Still another solution, using ISOdate and weekdays

with(list(years=2008:2121), years[weekdays(ISOdate(years, 12, 25)) == "Sunday"])

  1. Or with "subset"

subset(data.frame(years=2008:2121), weekdays(ISOdate(years, 12, 25)) == "Sunday")$years

  1. Simply replace "Sunday" with whatever it's named in your country,
  2. or set locale first, with

Sys.setlocale(cat="LC_ALL", "en")

  1. Under MS Windows, write instead

Sys.setlocale("LC_ALL", "English")</lang>

Racket

<lang Racket>

  1. lang racket

(require racket/date)

(define (xmas-on-sunday? year)

 (zero? (date-week-day (seconds->date (find-seconds 0 0 12 25 12 year)))))

(for ([y (in-range 2008 2121)] #:when (xmas-on-sunday? y))

 (displayln y))

</lang>

Raku

(formerly Perl 6)

Works with: Rakudo version 2010.07

As Perl 5, except DateTime is built-in, so you don't need to download a module of that name:

<lang perl6>say join ' ', grep { Date.new($_, 12, 25).day-of-week == 7 }, 2008 .. 2121;</lang>

REBOL

<lang REBOL>REBOL [ Title: "Yuletide Holiday" URL: http://rosettacode.org/wiki/Yuletide_Holiday ]

for y 2008 2121 1 [ d: to-date reduce [y 12 25] if 7 = d/weekday [prin [y ""]] ]</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Red

<lang Red>Red [] repeat yy 114 [

 d: to-date reduce [25 12 (2007 + yy )]
 if 7 = d/weekday [ print d ] ;; 7 = sunday

]

or

print "version 2"

d: to-date [25 12 2008] while [d <= 25/12/2121 ] [

 if 7 = d/weekday [ 
   print rejoin [d/day '. d/month '. d/year ] 
 ] 
 d/year: d/year + 1

] </lang>

Output:
25-Dec-2011

25-Dec-2016 25-Dec-2022 25-Dec-2033 25-Dec-2039 25-Dec-2044 25-Dec-2050 25-Dec-2061 25-Dec-2067 25-Dec-2072 25-Dec-2078 25-Dec-2089 25-Dec-2095 25-Dec-2101 25-Dec-2107 25-Dec-2112 25-Dec-2118 version 2 25.12.2011 25.12.2016 25.12.2022 25.12.2033 25.12.2039 25.12.2044 25.12.2050 25.12.2061 25.12.2067 25.12.2072 25.12.2078 25.12.2089 25.12.2095 25.12.2101 25.12.2107 25.12.2112 25.12.2118 >>

REXX

using DATE weekday

The extended   DATE   parameters (arguments 2 and 3) are only supported by the newer REXX interpreters. <lang rexx> do year=2008 to 2121

   if date('w', year"1225", 's') == 'Sunday'  then say year
   end   /*year*/</lang>
output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

using DATE base

The extended DATE parameters (arguments 2 and 3) are only supported by the newer REXX interpreters. <lang rexx> do year=2008 to 2121

   if date('b', year"1225", 's') // 7 == 6  then say year
   end   /*year*/</lang>
output   is identical to the 1st REXX version.



using DATE iso

Works with Regina REXX only.

The extended   DATE   parameters (arguments 2 and 3) are only supported by the newer REXX interpreters.

Programming note:   The   ISO   option of the   date   BIF is a Regina extension.

Language note:   the DATE   built-in function always returns the day-of-week in English, no matter what the native language is in effect. <lang rexx>/*REXX program displays in which years 12/25 (December 25th) falls on a Sunday. */ parse arg start finish . /*get the START and FINISH years. */ if start== | start=="," then start=2008 /*Not specified? Then use the default.*/ if finish== | finish=="," then finish=2121 /* " " " " " " */

     do y=start  to finish                      /*process all the years specified.     */
     if date('Weekday', y"-12-25", 'ISO')\=='Sunday'  then iterate
  /* if date('w'      , y"-12-25", 'i'  ) ···       (same as above).  */
  /*          ↑↑↑↑↑↑   ↑↑↑↑↑↑↑↑↑↑  ↑↑↑                                */
  /*          option   yyyy-mm-dd  fmt                                */
     say 'December 25th,'    y    "falls on a Sunday."
     end   /*y*/
                                                /*stick a fork in it,  we're all done. */</lang>
output   when using the default inputs:
December 25th, 2011 falls on a Sunday.
December 25th, 2016 falls on a Sunday.
December 25th, 2022 falls on a Sunday.
December 25th, 2033 falls on a Sunday.
December 25th, 2039 falls on a Sunday.
December 25th, 2044 falls on a Sunday.
December 25th, 2050 falls on a Sunday.
December 25th, 2061 falls on a Sunday.
December 25th, 2067 falls on a Sunday.
December 25th, 2072 falls on a Sunday.
December 25th, 2078 falls on a Sunday.
December 25th, 2089 falls on a Sunday.
December 25th, 2095 falls on a Sunday.
December 25th, 2101 falls on a Sunday.
December 25th, 2107 falls on a Sunday.
December 25th, 2112 falls on a Sunday.
December 25th, 2118 falls on a Sunday.

old school DOW

This   DOW   (day-of-week)   version will work with any version of a REXX interpreter. <lang rexx>/*REXX program (old school) displays in which years 12/25 (Dec. 25th) falls on a Sunday.*/ parse arg start finish . /*get the START and FINISH years. */ if start== | start=="," then start=2008 /*Not specified? Then use the default.*/ if finish== | finish=="," then finish=2121 /* " " " " " " */

     do y=start  to finish                      /*process all the years specified.     */
     if dow(12,25,y)==1  then say 'December 25th,'       y       "falls on a Sunday."
     end   /*y*/

exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ dow: procedure; parse arg m,d,y; if m<3 then do; m= m+12; y= y-1; end

    yL= left(y, 2);      yr= right(y, 2);  w= (d + (m+1)*26%10 +yr +yr%4 +yL%4 +5*yL) //7
    if w==0  then w= 7;  return w               /*Sunday=1,  Monday=2,  ···  Saturday=7*/</lang>
output   when using the default input:
December 25th, 2011 falls on a Sunday.
December 25th, 2016 falls on a Sunday.
December 25th, 2022 falls on a Sunday.
December 25th, 2033 falls on a Sunday.
December 25th, 2039 falls on a Sunday.
December 25th, 2044 falls on a Sunday.
December 25th, 2050 falls on a Sunday.
December 25th, 2061 falls on a Sunday.
December 25th, 2067 falls on a Sunday.
December 25th, 2072 falls on a Sunday.
December 25th, 2078 falls on a Sunday.
December 25th, 2089 falls on a Sunday.
December 25th, 2095 falls on a Sunday.
December 25th, 2101 falls on a Sunday.
December 25th, 2107 falls on a Sunday.
December 25th, 2112 falls on a Sunday.
December 25th, 2118 falls on a Sunday.

Ring

<lang ring> for n = 2008 to 2121

   if n < 2100 leap = n - 1900 else leap = n - 1904 ok
   m = (((n-1900)%7) + floor(leap/4) + 27) % 7 
   if m = 4 see "25 Dec " + n + nl ok

next </lang>

Ruby

<lang ruby>require 'date'

(2008..2121).each {|year| puts "25 Dec #{year}" if Date.new(year, 12, 25).sunday? }</lang>

Output:
25 Dec 2011
25 Dec 2016
25 Dec 2022
25 Dec 2033
25 Dec 2039
25 Dec 2044
25 Dec 2050
25 Dec 2061
25 Dec 2067
25 Dec 2072
25 Dec 2078
25 Dec 2089
25 Dec 2095
25 Dec 2101
25 Dec 2107
25 Dec 2112
25 Dec 2118

Or using the Time class <lang ruby>(2008..2121).each {|year| puts "25 Dec #{year}" if Time.local(year, 12, 25).sunday?}</lang>

Output:
25 Dec 2011
25 Dec 2016
25 Dec 2022
25 Dec 2033
25 Dec 2039
25 Dec 2044
25 Dec 2050
25 Dec 2061
25 Dec 2067
25 Dec 2072
25 Dec 2078
25 Dec 2089
25 Dec 2095
25 Dec 2101
25 Dec 2107
25 Dec 2112
25 Dec 2118

(Note: The Time class could not handle dates beyond 2038 prior to Ruby 1.9.2.[1])

Run BASIC

<lang runbasic>for year = 2008 to 2121

if val(date$("12-25-";year)) mod 7 = 5 then print "For ";year;"xmas is Sunday"

next year</lang>

For 2011 xmas is Sunday
For 2016 xmas is Sunday
For 2022 xmas is Sunday
For 2033 xmas is Sunday
For 2039 xmas is Sunday
For 2044 xmas is Sunday
For 2050 xmas is Sunday
For 2061 xmas is Sunday
For 2067 xmas is Sunday
For 2072 xmas is Sunday
For 2078 xmas is Sunday
For 2089 xmas is Sunday
For 2095 xmas is Sunday
For 2101 xmas is Sunday
For 2107 xmas is Sunday
For 2112 xmas is Sunday
For 2118 xmas is Sunday

Rust

<lang rust>extern crate chrono;

use chrono::prelude::*;

fn main() {

   let years = (2008..2121).filter(|&y| Local.ymd(y, 12, 25).weekday() == Weekday::Sun).collect::<Vec<i32>>();
   println!("Years = {:?}", years);

}</lang>

Output:

Years = [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

S-BASIC

<lang BASIC> $constant SUNDAY = 0

rem - compute p mod q function mod(p, q = integer) = integer end = p - q * (p/q)

comment

   return day of week (Sun = 0, Mon = 1, etc.) for a
   given Gregorian calendar date using Zeller's congruence

end function dayofweek (mo, da, yr = integer) = integer

   var y, c, z = integer
   if mo < 3 then
       begin
           mo = mo + 10
           yr = yr - 1
       end
   else mo = mo - 2
   y = mod(yr,100)
   c = int(yr / 100)
   z = int((26 * mo - 2) / 10)
   z = z + da + y + int(y/4) + int(c/4) - 2 * c + 777
   z = mod(z,7)

end = z

rem - main program var year = integer print "Christmas will fall on a Sunday in" for year=2008 to 2121

  if dayofweek(12,25,year) = SUNDAY then
     print year

next year end </lang>

Output:
Christmas will fall on a Sunday in
 2011
 2016
 2011
 2033
 2039
 2044
 2050
 2061
 2067
 2072
 2078
 2089
 2095
 2101
 2107
 2112
 2118

SAS

<lang sas>data _null_; do y=2008 to 2121;

   a=mdy(12,25,y);
   if weekday(a)=1 then put y;

end; run;

/* 2011 2016 2022 2033 2039 2044 2050 2061 2067

  2072 2078 2089 2095 2101 2107 2112 2118 */</lang>

Scala

Library: Scala

JDK (discouraged)

<lang scala>import java.util.{ Calendar, GregorianCalendar } import Calendar.{ DAY_OF_WEEK, DECEMBER, SUNDAY }

object DayOfTheWeek extends App {

 val years = 2008 to 2121
 val yuletide =
   years.filter(year => (new GregorianCalendar(year, DECEMBER, 25)).get(DAY_OF_WEEK) == SUNDAY)
 // If you want a test: (optional)
 assert(yuletide ==
   Seq(2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061,
     2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118))
 println(yuletide.mkString(
   s"${yuletide.length} Years between ${years.head} and ${years.last}" +
     " including where Christmas is observed on Sunday:\n", ", ", "."))

}</lang>

JDK >= 8 (recommended)

Naive programming

<lang scala>import java.time.{ DayOfWeek, LocalDate }

object DayOfTheWeek1 extends App {

 val years = 2008 to 2121
 val yuletide = for {
   year <- years
   if LocalDate.of(year, 12, 25).getDayOfWeek() == DayOfWeek.SUNDAY
 } yield year
 println(yuletide.mkString(
   s"${yuletide.count(p => true)} Years between ${years.head} and ${years.last}" +
     " including where Christmas is observed on Sunday:\n", ", ", "."))

}</lang>

Idiomatic programming

<lang scala>import java.time.{ DayOfWeek, LocalDate }

object DayOfTheWeek1 extends App {

 val years = 2008 to 2121
 val yuletide =
   years.filter(year => (LocalDate.of(year, 12, 25).getDayOfWeek() == DayOfWeek.SUNDAY))
 // If you want a test: (optional)
 assert(yuletide ==
   Seq(2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061,
     2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118))
 println(yuletide.mkString(
   s"${yuletide.length} Years between ${years.head} and ${years.last}" +
     " including where Christmas is observed on Sunday:\n", ", ", "."))

}</lang>

Tail recursion

<lang scala>import java.time.{ DayOfWeek, LocalDate } import scala.annotation.tailrec

object DayOfTheWeek3 extends App {

 val years = 2008 to 2121
 val yuletide = {
   @tailrec
   def inner(anni: List[Int], accu: List[Int]): List[Int] = {
     if (anni == Nil) accu
     else inner(anni.tail, accu ++
       (if (LocalDate.of(anni.head, 12, 25).getDayOfWeek() == DayOfWeek.SUNDAY) List(anni.head)
       else Nil))
   }
   inner(years.toList, Nil)
 }
 // If you want a test: (optional)
 assert(yuletide ==
   Seq(2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061,
     2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118))
 println(yuletide.mkString(
   s"${yuletide.length} Years between ${years.head} and ${years.last}" +
     " including where Christmas is observed on Sunday:\n", ", ", "."))

}</lang>

Output of all solutions:
Years between 2008 and 2121 including when Christmas is observed on Sunday:
2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118.

Scheme

<lang scheme>(define (day-of-week year month day) (if (< month 3)

   (begin (set! month (+ month 12)) (set! year (- year 1))))

(+ 1

  (remainder (+ 5 day (quotient (* (+ 1 month) 13) 5)
                year (quotient year 4) (* (quotient year 100) 6) (quotient year 400))
             7)))

(define (task) (let loop ((y 2121) (v '())) (if (< y 2008)

   v
   (loop (- y 1)
         (if (= 7 (day-of-week y 12 25))
             (cons y v)
             v)))))

(task)

(2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118)</lang>

Seed7

The library time.s7i defines the function dayOfWeek, which returns 1 for monday, 2 for tuesday, and so on up to 7 for sunday. <lang seed7>$ include "seed7_05.s7i";

 include "time.s7i";

const proc: main is func

 local
   var integer: year is 0;
 begin
   for year range 2008 to 2122 do
     if dayOfWeek(date(year, 12, 25)) = 7 then
       writeln("Christmas comes on a sunday in " <& year);   
     end if;
   end for;
 end func;</lang>
Output:
Christmas comes on a sunday in 2011
Christmas comes on a sunday in 2016
Christmas comes on a sunday in 2022
Christmas comes on a sunday in 2033
Christmas comes on a sunday in 2039
Christmas comes on a sunday in 2044
Christmas comes on a sunday in 2050
Christmas comes on a sunday in 2061
Christmas comes on a sunday in 2067
Christmas comes on a sunday in 2072
Christmas comes on a sunday in 2078
Christmas comes on a sunday in 2089
Christmas comes on a sunday in 2095
Christmas comes on a sunday in 2101
Christmas comes on a sunday in 2107
Christmas comes on a sunday in 2112
Christmas comes on a sunday in 2118

SenseTalk

<lang sensetalk>// In what years between 2008 and 2121 will the 25th of December be a Sunday?

repeat with year = 2008 to 2121 set Christmas to "12/25/" & year if the WeekDayName of Christmas is Sunday then put "Christmas in " & year & " falls on a Sunday" end if end repeat</lang>

Output:
Christmas in 2011 falls on a Sunday
Christmas in 2016 falls on a Sunday
Christmas in 2022 falls on a Sunday
Christmas in 2033 falls on a Sunday
Christmas in 2039 falls on a Sunday
Christmas in 2044 falls on a Sunday
Christmas in 2050 falls on a Sunday
Christmas in 2061 falls on a Sunday
Christmas in 2067 falls on a Sunday
Christmas in 2072 falls on a Sunday
Christmas in 2078 falls on a Sunday
Christmas in 2089 falls on a Sunday
Christmas in 2095 falls on a Sunday
Christmas in 2101 falls on a Sunday
Christmas in 2107 falls on a Sunday
Christmas in 2112 falls on a Sunday
Christmas in 2118 falls on a Sunday

Sidef

Translation of: Perl

<lang ruby>require('Time::Local')   for year in (2008 .. 2121) {

   var time = %S<Time::Local>.timelocal(0,0,0,25,11,year)
   var wd = Time(time).local.wday
   if (wd == 0) {
       say "25 Dec #{year} is Sunday"
   }

}</lang>

Output:
25 Dec 2011 is Sunday
25 Dec 2016 is Sunday
25 Dec 2022 is Sunday
25 Dec 2033 is Sunday
25 Dec 2039 is Sunday
25 Dec 2044 is Sunday
25 Dec 2050 is Sunday
25 Dec 2061 is Sunday
25 Dec 2067 is Sunday
25 Dec 2072 is Sunday
25 Dec 2078 is Sunday
25 Dec 2089 is Sunday
25 Dec 2095 is Sunday
25 Dec 2101 is Sunday
25 Dec 2107 is Sunday
25 Dec 2112 is Sunday
25 Dec 2118 is Sunday

Simula

Translation of: Sinclair ZX81 BASIC

<lang simula>BEGIN

   INTEGER M,D,Y;
   M := 12;
   D := 25;
   FOR Y := 2008 STEP 1 UNTIL 2121 DO BEGIN
       INTEGER W,A,MM,YY;
       A := (14 - M)//12;
       MM := M + 12*A - 2;
       YY := Y - A;
       W := D + ((13*MM - 1)//5) + YY + (YY//4) - (YY//100) + (YY//400);
       W := MOD(W,7);
       IF W = 0 THEN
       BEGIN OUTINT(Y,0);
             OUTIMAGE;
       END;
   END;

END.</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Smalltalk

<lang smalltalk>2008 to: 2121 do: [ :year | |date|

    date := Date newDay: 25 monthIndex: 12 year: year.
    date dayName = #Sunday
      ifTrue: [ date displayNl ]

]</lang>

Output:
25-Dec-2011
25-Dec-2016
25-Dec-2022
25-Dec-2033
25-Dec-2039
25-Dec-2044
25-Dec-2050
25-Dec-2061
25-Dec-2067
25-Dec-2072
25-Dec-2078
25-Dec-2089
25-Dec-2095
25-Dec-2101
25-Dec-2107
25-Dec-2112
25-Dec-2118

SQL

SQL has good support for date functions; care must be taken with NLS settings (globalization support), in the code below the date format language is passed in as an argument to the relevant function. (Or, see a variation that does not depend on language settings, after the output shown below.)

<lang sql>select extract(year from dt) as year_with_xmas_on_sunday from (

        select  add_months(date '2008-12-25', 12 * (level - 1)) as dt
        from    dual
        connect by level <= 2121 - 2008 + 1
      ) 

where to_char(dt, 'Dy', 'nls_date_language=English') = 'Sun' order by 1

</lang>


Output:
YEAR_WITH_XMAS_ON_SUNDAY
------------------------
                    2011
                    2016
                    2022
                    2033
                    2039
                    2044
                    2050
                    2061
                    2067
                    2072
                    2078
                    2089
                    2095
                    2101
                    2107
                    2112
                    2118

17 rows selected.

Alternatively, the WHERE clause can be written in a way that avoids the complication of language settings. The (overloaded) TRUNC function, as applied to dates, takes a second argument indicating "to what" we must truncate. One option is 'iw' for "ISO week"; this truncates to the most recent Monday (the beginning of the ISO standard week, which is Monday through Sunday by definition). Like so (replace in the query above):

<lang sql>where dt - trunc(dt, 'iw') = 6</lang>

Standard ML

<lang sml>(* Call: yearsOfSundayXmas(2008, 2121) *) fun yearsOfSundayXmas(fromYear, toYear) =

 if fromYear>toYear then
   ()
 else
   let
     val d = Date.date {year=fromYear, month=Date.Dec, day=25, 
             hour=0, minute=0, second=0,
                     offset=SOME Time.zeroTime}
     val wd = Date.weekDay d
   in
     if wd=Date.Sun then
       (
         print(Int.toString fromYear ^ "\n");
         yearsOfSundayXmas(fromYear+1, toYear)
       )
     else
       yearsOfSundayXmas(fromYear+1, toYear)
   end;</lang>
Output:
- yearsOfSundayXmas(2008, 2121);
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Stata

The dow() function returns the day of week, where sunday is zero and saturday is 6. <lang stata>clear sca n=2121-2008+1 set obs `=n' gen year=2007+_n list if dow(mdy(12,25,year))==0, noobs sep(0)

 +------+
 | year |
 |------|
 | 2011 |
 | 2016 |
 | 2022 |
 | 2033 |
 | 2039 |
 | 2044 |
 | 2050 |
 | 2061 |
 | 2067 |
 | 2072 |
 | 2078 |
 | 2089 |
 | 2095 |
 | 2101 |
 | 2107 |
 | 2112 |
 | 2118 |
 +------+</lang>

Mata

<lang mata>year=2008::2121 select(year,dow(mdy(12,25,year)):==0)</lang>

Suneido

<lang Suneido>year = 2008 while (year <= 2121)

   {
   if Date('#' $ year $ '1225').WeekDay() is 0
       Print(year)
   ++year
   }</lang>
Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Swift

<lang Swift>import Cocoa

var year=2008 let formatter=NSDateFormatter() formatter.dateFormat = "yyyy-MM-dd"

let gregorian:NSCalendar! = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) while (year<2122){

   var date:NSDate!=formatter.dateFromString(String(year)+"-12-25")
   var components=gregorian.components(NSCalendarUnit.CalendarUnitWeekday, fromDate: date)
   var dayOfWeek:NSInteger=components.weekday
   if(dayOfWeek==1){
       println(year)
   }
   year++

}</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Tcl

Works with: Tcl version 8.5

<lang tcl>package require Tcl 8.5

for {set y 2008} {$y <= 2121} {incr y} {

   if {[clock format [clock scan "$y-12-25" -format {%Y-%m-%d}] -format %w] == 0} {
       puts "xmas $y is a sunday"
   }

}</lang>

Output:
xmas 2011 is a sunday
xmas 2016 is a sunday
xmas 2022 is a sunday
xmas 2033 is a sunday
xmas 2039 is a sunday
xmas 2044 is a sunday
xmas 2050 is a sunday
xmas 2061 is a sunday
xmas 2067 is a sunday
xmas 2072 is a sunday
xmas 2078 is a sunday
xmas 2089 is a sunday
xmas 2095 is a sunday
xmas 2101 is a sunday
xmas 2107 is a sunday
xmas 2112 is a sunday
xmas 2118 is a sunday

TI-83 BASIC

Works with TI-84+/SE only <lang ti83b>

For(A,2008,2121
If dayofWk(A,12,25)=1
Disp A
End

</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118
Done

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT PRINT "25th of December will be a Sunday in the following years: " LOOP year=2008,2121 SET dayofweek = DATE (number,25,12,year,nummer) IF (dayofweek==7) PRINT year ENDLOOP </lang>

Output:
25th of December will be a Sunday in the following years:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

TypeScript

Translation of: Minimal BASIC

<lang javascript> // Find years with Sunday Christmas var f = 2008; var t = 2121; console.log(`Sunday Christmases ${f} - ${t}`); for (y = f; y <= t; y++) {

 var x = (y * 365) + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) - 6;
 if (x % 7 == 0)
   process.stdout.write(`${y}\t`);

} process.stdout.write("\n"); </lang>

Output:
Sunday Christmases 2008 - 2121
2011	2016	2022	2033	2039	2044	2050	2061	2067	2072	2078	2089	2095	2101	2107	2112	2118	

UNIX Shell

Unix commands may use time_t to count seconds since the epoch. For systems with 32-bit time, the counter overflows during 19 January 2038. These scripts continue to 2121 and may need a system with 64-bit time, to prevent the overflow.

With GNU date

This solution uses date -d, which seems to be a GNU extension, so it only works with those systems.

Works with: bash

<lang bash>#! /bin/bash

for (( i=2008; i<=2121; ++i )) do

date -d "$i-12-25"

done |grep Sun

exit 0</lang>

The first lines of output (from a GNU/Linux system with 32bit time_t, date version 6.9) are

<lang bash>Sun Dec 25 00:00:00 CET 2011 Sun Dec 25 00:00:00 CET 2016 Sun Dec 25 00:00:00 CET 2022 Sun Dec 25 00:00:00 CET 2033 date: invalid date `2038-12-25'</lang>

I.e., starting from year 2038, the date command (which uses the glibc library, at least on GNU systems), is not able to recognise the date as a valid one!

Different machine/OS version (64 bit time_t): This is the same command run on RedHat Linux. <lang bash>bash-3.00$ date --version date (coreutils) 5.2.1 Written by David MacKenzie.

Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. bash-3.00$ uname -a Linux brslln01 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux bash-3.00$ for((i=2009; i <= 2121; i++)); do date -d "$i-12-25" |egrep Sun; done Sun Dec 25 00:00:00 GMT 2011 Sun Dec 25 00:00:00 GMT 2016 Sun Dec 25 00:00:00 GMT 2022 Sun Dec 25 00:00:00 GMT 2033 Sun Dec 25 00:00:00 GMT 2039 Sun Dec 25 00:00:00 GMT 2044 Sun Dec 25 00:00:00 GMT 2050 Sun Dec 25 00:00:00 GMT 2061 Sun Dec 25 00:00:00 GMT 2067 Sun Dec 25 00:00:00 GMT 2072 Sun Dec 25 00:00:00 GMT 2078 Sun Dec 25 00:00:00 GMT 2089 Sun Dec 25 00:00:00 GMT 2095 Sun Dec 25 00:00:00 GMT 2101 Sun Dec 25 00:00:00 GMT 2107 Sun Dec 25 00:00:00 GMT 2112 Sun Dec 25 00:00:00 GMT 2118 bash-3.00$</lang>

With GNU date and GNU seq (UnixPipes)

Like the previous solution, this solution uses date -d, which seems to be a GNU extension. Output is same as previous solution.

<lang bash>seq 2008 2121 | xargs -IYEAR -n 1 date +%c -d 'Dec 25 YEAR' | grep Sun</lang>

With Unix cal

The cal command is a tradition since Version 6 AT&T UNIX. This solution assumes that cal will always output a calendar in this format.

$ cal 12 2011 
   December 2011
Su Mo Tu We Th Fr Sa
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
                    

This format always puts Sunday in columns 1 and 2. The solution uses tail to delete the first 2 lines (month, year, names of days), cut to extract Sunday's columns, and grep to check if "25" appears in those columns.

Works with: Bourne Shell

<lang bash>y=2008 while test $y -lt 2122; do cal 12 $y | tail +3 | cut -c1-2 | grep -Fq 25 && echo 25 Dec $y y=`expr $y + 1` done</lang>

Running this script with OpenBSD, the output is identical to the C# program. OpenBSD cal accepts any year from 1 to 9999, so 2008 to 2122 is well within range.

With zsh

<lang bash>zmodload zsh/datetime for (( year = 2010; year <= 2121; year++ ));

 if $(strftime '%A' $(strftime -r '%F' $year-12-25)) == Sunday  print $year</lang>

If the system has 32-bit time, this script will malfunction for years >= 2038; it will print no year from 2038 to 2121 (unless today is Sunday, then it prints every year from 2038 to 2121). This happens because strftime -r '%F' $year-12-25 yields -1 for an out-of-range date, and strftime '%A' -1 yields name of today.

Ursala

A standard library, stt, provides basic date manipulation functions, and is imported in this example. Unix era times denominated in seconds since 1969 (excluding leap seconds) are represented as natural numbers with unlimited precision. Results are valid for the arbitrarily distant future assuming the Gregorian calendar remains in effect.

The algorithm relies on the string_to_time function converting a date expressed as a character string to seconds without needing a weekday field in the input, and the time_to_string function outputting the corresponding date with the weekday included. The output is then filtered for Sundays.

<lang Ursala>#import std

  1. import nat
  2. import stt

christmases = time_to_string* string_to_time*TS 'Dec 25 0:0:0 '-*@hS %nP* nrange/2008 2121

  1. show+

sunday_years = ~&zS sep` * =]'Sun'*~ christmases</lang>

Output:
2011                            
2016                            
2022                            
2033                            
2039                            
2044                            
2050                            
2061                            
2067                            
2072                            
2078                            
2089                            
2095                            
2101                            
2107                            
2112
2118

VBA

<lang vb>Option Explicit

Sub MainDayOfTheWeek()

   Debug.Print "Xmas will be a Sunday in : " & XmasSunday(2008, 2121)

End Sub

Private Function XmasSunday(firstYear As Integer, lastYear As Integer) As String Dim i As Integer, temp$

   For i = firstYear To lastYear
       If Weekday(CDate("25/12/" & i)) = vbSunday Then temp = temp & ", " & i
   Next
   XmasSunday = Mid(temp, 2)

End Function</lang>

Output:
Xmas will be a Sunday in :  2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118

VBScript

<lang vb>For year = 2008 To 2121

   If Weekday(DateSerial(year, 12, 25)) = 1 Then
       WScript.Echo year
   End If

Next</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Vedit macro language

<lang vedit>Buf_Switch(Buf_Free) for (#3 = 2008; #3 < 2122; #3++) {

   Reg_Set(10, "12/25/")
   Num_Str(#3, 10, LEFT+APPEND)
   if (JDate(@10) % 7 == 0) {

Num_Ins(#3, NOCR)

   }

}</lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Visual Objects

<lang visualfoxpro> local i as dword

for i := 2008 upto 2121 if DOW(ConDate(i, 12, 25)) = 1 ? AsString(i) endif next i </lang>

Output:
2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Vlang

Updated for Vlang version 0.2.2 <lang go>import time

fn main() {

   for year := 2008; year <= 2121; year++ {
       date := time.parse('${year}-12-25 00:00:00') or { continue }
       if date.long_weekday_str() == 'Sunday' {
           println('December 25 ${year} is a ${date.long_weekday_str()}')
       }
   }

}</lang>

Output:
December 25 2011 is a Sunday
December 25 2016 is a Sunday
December 25 2022 is a Sunday
December 25 2033 is a Sunday
December 25 2039 is a Sunday
December 25 2044 is a Sunday
December 25 2050 is a Sunday
December 25 2061 is a Sunday
December 25 2067 is a Sunday
December 25 2072 is a Sunday
December 25 2078 is a Sunday
December 25 2089 is a Sunday
December 25 2095 is a Sunday
December 25 2101 is a Sunday
December 25 2107 is a Sunday
December 25 2112 is a Sunday
December 25 2118 is a Sunday

VTL-2

Translation of: ALGOL W

...which is

Translation of: Fortran

VTL-2 does not have operator precedence - all expressions are evaluated left-to-right, except for expressions nested in parenthesis, hence the expression at line 1090 differs from that in the Algol W sample. <lang VTL2>1000 #=2000 1010 R=! 1020 N=M 1030 X=Y 1040 #=N>3*1070 1050 N=N+12 1060 X=X-1 1070 J=X/100 1080 K=% 1090 W=N+1*26/10+D+K+(K/4)+(J/4)+(5*J)/7*0+% 1100 #=R 2000 ?="25th of December is a Sunday in"; 2010 Y=2008 2020 M=12 2030 D=25 2040 #=1010 2050 #=W=1=0*2080 2060 $=32 2070 ?=Y 2080 Y=Y+1 2090 #=Y<2121*2040 2100 ?=""</lang>

Output:
25th of December is a Sunday in 2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118

Wortel

<lang wortel>!-&y = 0 `.getDay. @new Date[y 11 25] @range[2008 2121]</lang>

Returns:

[2011 2016 2022 2033 2039 2044 2050 2061 2067 2072 2078 2089 2095 2101 2107 2112 2118]

Wren

Library: Wren-date

<lang ecmascript>import "/date" for Date

System.print("Years between 2008 and 2121 when 25th December falls on Sunday:") for (year in 2008..2121) {

   if (Date.new(year, 12, 25).dayOfWeek == 7) System.print(year)

}</lang>

Output:
Years between 2008 and 2121 when 25th December falls on Sunday:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

XPL0

The original routine in the library only worked correctly between the years 1980 and 2099. It was upgraded with this new routine that handles all dates in the Gregorian calendar, from 1583 onward. It's based on Zeller's Congruence.

<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations

func WeekDay(Year, Month, Day); \Return day of week (0=Sat 1=Sun..6=Fri) int Year, Month, Day; [if Month<=2 then [Month:= Month+12; Year:= Year-1]; return rem((Day + (Month+1)*26/10 + Year + Year/4 + Year/100*6 + Year/400) / 7); ]; \WeekDay


int Year; [for Year:= 2008 to 2121 do

   if WeekDay(Year, 12, 25) = 1 then   \25th of December is a Sunday
       [IntOut(0, Year);  CrLf(0)];

]</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

Yabasic

Translation of: FreeBASIC

<lang Yabasic>sub wd(m, d, y)

 If m < 3 Then        // If m = 1 Or m = 2 Then
   m = m + 12
   y = y - 1
 End If
 Return mod((y + int(y / 4) - int(y / 100) + int(y / 400) + d + int((153 * m + 8) / 5)), 7)

End sub

// ------=< MAIN >=------

For yr = 2008 To 2121

 If wd(12, 25, yr) = 0 Then
   Print "Dec 25 ", yr
 EndIf

Next</lang>

zkl

ISO dates, monday is 1, sunday is 7 <lang zkl>var [const] D=Time.Date; foreach y in ([2008..2121]){

  if (D.Sunday==D.weekDay(y,12,25)) println(y)

}</lang> Or, in a more functional manner: <lang zkl>var [const] D=Time.Date; [2008..2121].filter(fcn(y){ D.Sunday==D.weekDay(y,12,25) }).println()</lang>

Output:
2011
2016
2022
2033
2039
2044
2050
2061
2067
2072
2078
2089
2095
2101
2107
2112
2118

zonnon

<lang zonnon> module Main; (*Access to Mono System package *) import System;

var now: System.DateTime; begin now := System.DateTime.Now; System.Console.Write(now.ToString("yyyy-MM-dd :")); System.Console.WriteLine(now.DayOfWeek); end Main. </lang>

Output:
2017-12-05 :Tuesday

ZX Spectrum Basic

Translation of: BASIC

<lang zxbasic>10 CLS 20 FOR y=2008 TO 2121 30 LET year=y: LET m=12: LET d=25: GO SUB 1000 40 IF wd=0 THEN PRINT d;" ";m;" ";y 50 NEXT y 60 STOP 1000 REM week day 1010 IF m=1 OR m=2 THEN LET m=m+12: LET year=year-1 1020 LET wd=FN m(year+INT (year/4)-INT (year/100)+INT (year/400)+d+INT ((153*m+8)/5),7) 1030 RETURN 1100 DEF FN m(a,b)=a-INT (a/b)*b</lang>