Day of the week

Revision as of 21:13, 17 June 2013 by rosettacode>Arbautjc (→‎{{header|GAP}}: xmas function is better replaced with "Filtered" + WeekDay implementation)

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
Day of the week
You are encouraged to solve this task according to the task description, using any language you may know.

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.

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

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 Ada.Calendar.Year_Number loop -- 1901..2399
     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> Sample output:

1904-12-25 00:00:00
1910-12-25 00:00:00
1921-12-25 00:00:00
1927-12-25 00:00:00
1932-12-25 00:00:00
1938-12-25 00:00:00
1949-12-25 00:00:00
1955-12-25 00:00:00
1960-12-25 00:00:00
1966-12-25 00:00:00
1977-12-25 00:00:00
1983-12-25 00:00:00
1988-12-25 00:00:00
1994-12-25 00:00:00
2005-12-25 00:00:00
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
2129-12-25 00:00:00
2135-12-25 00:00:00
2140-12-25 00:00:00
2146-12-25 00:00:00
2157-12-25 00:00:00
2163-12-25 00:00:00
2168-12-25 00:00:00
2174-12-25 00:00:00
2185-12-25 00:00:00
2191-12-25 00:00:00
2196-12-25 00:00:00
2203-12-25 00:00:00
2208-12-25 00:00:00
2214-12-25 00:00:00
2225-12-25 00:00:00
2231-12-25 00:00:00
2236-12-25 00:00:00
2242-12-25 00:00:00
2253-12-25 00:00:00
2259-12-25 00:00:00
2264-12-25 00:00:00
2270-12-25 00:00:00
2281-12-25 00:00:00
2287-12-25 00:00:00
2292-12-25 00:00:00
2298-12-25 00:00:00
2304-12-25 00:00:00
2310-12-25 00:00:00
2321-12-25 00:00:00
2327-12-25 00:00:00
2332-12-25 00:00:00
2338-12-25 00:00:00
2349-12-25 00:00:00
2355-12-25 00:00:00
2360-12-25 00:00:00
2366-12-25 00:00:00
2377-12-25 00:00:00
2383-12-25 00:00:00
2388-12-25 00:00:00
2394-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

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>

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>

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>

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 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> This produces the following 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

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 = (from day in
                            (from year in Enumerable.Range(2008, 2121 - 2007)
                             select new DateTime(year, 12, 25))
                        where day.DayOfWeek == DayOfWeek.Sunday
                        select day.ToString("dd MMM yyyy")).ToArray();
       foreach (string day in days) Console.WriteLine(day);
   }

}</lang>

This looks better:

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

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

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)

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

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

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))
              day-of-week))
    collect year)</lang>

D

<lang d>import std.stdio, std.datetime, std.conv, std.algorithm, std.range;

void main() {

   writeln("Christmas comes on a Sunday in the years:");
   foreach (year; 2008 .. 2122) {
       immutable d = text(year) ~ "-Dec-25";
       if (Date.fromSimpleString(d).dayOfWeek() == DayOfWeek.sun)
           writeln(year);
   }

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

<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;
 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

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

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

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

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

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 import Data.Time.Calendar.WeekDate

isXmasSunday year = wday == 7

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

main = mapM_ putStrLn ["25 December " ++ show year ++ " is Sunday"

                      | year <- [2008..2121], isXmasSunday 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

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

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

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>

Sample 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

<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

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>

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>

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

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

Mathematica

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

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

МК-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).

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

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

Objective-C

Works with: GNUstep

It should works also with Cocoa and OpenStep in general, but I can't test these.

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

int main() {

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSUInteger i;
  
  for(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);
     }
     [d release];
  }
  
  [pool release];
  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>

The output of a run on a 32 bit machine is

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

ooRexx

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

Pascal

See Delphi

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

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>

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

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>

PowerShell

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

Protium

<lang html><@ 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

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>import datetime

def yuletide():

  sunday = 6
  days = (day.strftime('%d %b %Y') for day in (datetime.date(year, 12, 25) for year in range(2008,2122)) if day.weekday() == sunday)
  print '\n'.join(days)

yuletide()</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

R

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

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

<lang R> Also:

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

<lang r>#Still another solution, using ISOdate and weekdays (2008:2121)[weekdays(ISOdate(2008:2121, 12, 25)) == "Sunday"]

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

Sys.setlocale(cat="LC_ALL", "en")</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>

REBOL

<lang REBOL>REBOL [ Title: "Yuletide Holiday" Author: oofoe Date: 2009-12-07 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

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

output is the same as above

using DATE iso

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

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 which years December 25th falls on a Sunday. */ parse arg start finish . /*get the start and finish years.*/ if start== then start=2008 /*None specified? Assume default*/ if finish== then finish=2121 /*None specified? Assume default*/

     do y=start to finish             /*process 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 done.*/</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.

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 which years 12/25 falls on a Sunday*//

parse arg start finish . /*get the start and finish years.*/ if start== then start=2008 /*None specified? Assume default*/ if finish== then finish=2121 /*None specified? Assume default*/

     do y=start to finish             /*process 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 done.*/ /*─────────────────────────────────────DOW (day of week) subroutine─────*/ dow: procedure; 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 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.

Ruby

<lang ruby>require 'date'

(2008..2121).each do |year|

 puts "25 Dec #{year}" if Date.new(year, 12, 25).wday == 0 # Ruby 1.9: if Date.new(year, 12, 25).sunday?

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

The Time class overflows at the Unix epoch in 2038: <lang ruby>SUNDAY = 0

(2008..2121).each do |year|

 begin
   day = Time.local(year, 12, 25)
   puts "25 Dec #{year}" if day.wday == SUNDAY # Ruby 1.9: if day.sunday?
 rescue ArgumentError
   puts '%d is the last year we can specify' % (year-1)
   break
 end

end</lang> Output on 32-bit machine:

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

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

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

<lang scala> import java.util.{Calendar, GregorianCalendar} import Calendar._

object DayOfTheWeek {

 def main(args:Array[String]) {
   for (year <- 2008 to 2121;
        date <- Some(new GregorianCalendar(year, DECEMBER, 25));
        if date.get(DAY_OF_WEEK) == SUNDAY) {
     println(year)
   }
 }

} </lang>

Output:

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

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

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

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> outputs

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
dayofWk(A,12,25
If Ans=1
Disp A
End

</lang> outputs

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

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

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

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

proc 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