I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Find the last Sunday of each month

Find the last Sunday of each month
You are encouraged to solve this task according to the task description, using any language you may know.

Write a program or a script that returns the last Sundays of each month of a given year. The year may be given through any simple input method in your language (command line, std in, etc).

Example of an expected output:

```./last_sundays 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## 11l

`F last_sundays(year)   [String] sundays   L(month) 1..12      V last_day_of_month = I month < 12 {Time(year, month + 1)} E Time(year + 1)      L         last_day_of_month -= TimeDelta(days' 1)         I last_day_of_month.strftime(‘%w’) == ‘0’            sundays [+]= year‘-’(‘#02’.format(month))‘-’last_day_of_month.strftime(‘%d’)            L.break   R sundays print(last_sundays(2013).join("\n"))`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## 360 Assembly

The program uses one ASSIST macro (XPRNT) to keep the code as short as possible.

`*        Last Sunday of each month 31/01/2017LASTSUND CSECT         USING  LASTSUND,R13       base register         B      72(R15)            skip savearea         DC     17F'0'             savearea         STM    R14,R12,12(R13)    prolog         ST     R13,4(R15)         " <-         ST     R15,8(R13)         " ->         LR     R13,R15            " addressability         L      R4,YEAR            year         SRDA   R4,32              .         D      R4,=F'400'         year/400         LTR    R4,R4              if year//400=0         BZ     LEAP         L      R4,YEAR            year         SRDA   R4,32              .         D      R4,=F'4'           year/4         LTR    R4,R4              if year//4=0         BNZ    NOTLEAP         L      R4,YEAR            year         SRDA   R4,32              .         D      R4,=F'100'         year/400         LTR    R4,R4              if year//100=0         BZ     NOTLEAPLEAP     MVC    DAYS+4(4),=F'29'   days(2)=29NOTLEAP  L      R8,YEAR            year         BCTR   R8,0               y=year-1         LA     R7,42              42         AR     R7,R8              +y         LR     R3,R8              y         SRA    R3,2               y/4         AR     R7,R3              +y/4         LR     R4,R8              y         SRDA   R4,32              .         D      R4,=F'100'         y/100         LA     R4,0               .         M      R4,=F'6'           *6         AR     R7,R5              +6*(y/100)         LR     R4,R8              y         SRDA   R4,32              .         D      R4,=F'400'         y/100         AR     R7,R5              k=42+y+y/4+6*(y/100)+y/400         LA     R6,1               m=1LOOPM    C      R6,=F'12'          do m=1 to 12         BH     ELOOPM         LR     R1,R6              m         SLA    R1,2               .         L      R2,DAYS-4(R1)      days(m)         AR     R7,R2              k=k+days(m)         LR     R4,R7              k         SRDA   R4,32              .         D      R4,=F'7'           k/7         SR     R2,R4              days(m)-k//7         LR     R9,R2              d=days(m)-k//7         L      R1,YEAR            year         CVD    R1,DW              year: binary to packed          OI     DW+7,X'0F'           zap sign         UNPK   PG(4),DW             unpack (ZL4)         CVD    R6,DW              m : binary to packed          OI     DW+7,X'0F'           zap sign         UNPK   PG+5(2),DW           unpack (ZL2)         CVD    R9,DW              d: binary to packed          OI     DW+7,X'0F'           zap sign         UNPK   PG+8(2),DW           unpack (ZL2)         XPRNT  PG,L'PG            print buffer         LA     R6,1(R6)           m=m+1         B      LOOPMELOOPM   L      R13,4(0,R13)       epilog          LM     R14,R12,12(R13)    " restore         XR     R15,R15            " rc=0         BR     R14                exitYEAR     DC     F'2013'            <== input yearDAYS     DC     F'31',F'28',F'31',F'30',F'31',F'30'         DC     F'31',F'31',F'30',F'31',F'30',F'31'PG       DC     CL80'YYYY-MM-DD'   bufferXDEC     DS     CL12               tempDW       DS     D                  packed (PL8) 15num         YREGS         END    LASTSUND`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Action!

Day of the week is determined using Sakamoto method.

`;https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Sakamoto.27s_methodsBYTE FUNC DayOfWeek(INT y BYTE m,d)	;1<=m<=12, y>1752  BYTE ARRAY t=[0 3 2 5 0 3 5 1 4 6 2 4]  BYTE res   IF m<3 THEN    y==-1  FI  res=(y+y/4-y/100+y/400+t(m-1)+d) MOD 7RETURN (res) BYTE FUNC IsLeapYear(INT y)  IF y MOD 100=0 THEN    IF y MOD 400=0 THEN      RETURN (1)    ELSE      RETURN (0)    FI  FI   IF y MOD 4=0 THEN    RETURN (1)  FIRETURN (0) INT FUNC GetMaxDay(INT y BYTE m)  BYTE ARRAY MaxDay=[31 28 31 30 31 30 31 31 30 31 30 31]   IF m=2 AND IsLeapYear(y)=1 THEN    RETURN (29)  FIRETURN (MaxDay(m-1)) PROC PrintB2(BYTE x)  IF x<10 THEN    Put('0)  FI  PrintB(x)RETURN PROC Main()  INT MinYear=[1753],MaxYear=[9999],y  BYTE m,d,last,maxD   DO    PrintF("Input year in range %I...%I: ",MinYear,MaxYear)    y=InputI()  UNTIL y>=MinYear AND y<=MaxYear  OD   FOR m=1 TO 12  DO    last=0    maxD=GetMaxDay(y,m)    FOR d=1 TO maxD    DO      IF DayOfWeek(y,m,d)=0 THEN        last=d      FI    OD    PrintI(y) Put('-)    PrintB2(m) Put('-)    PrintB2(last) PutE()  ODRETURN`
Output:
```Input year in range 1753...9999: 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

The program from [[1]] solves this task, as well.

Output:
```>./last_weekday_in_month sunday 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## ALGOL 68

Translation of: ALGOL W
`BEGIN # find the last Sunday in each month of a year             #    # returns true if year is a leap year, false otherwise       #    # assumes year is in the Gregorian Calendar                  #    PROC is leap year = ( INT year )BOOL:         year MOD 400 = 0 OR ( year MOD 4 = 0 AND year MOD 100 /= 0 );    # returns the day of the week of the specified date (d/m/y)  #    #         Sunday = 1                                         #    PROC day of week = ( INT d, m, y )INT:         BEGIN            INT mm := m;            INT yy := y;            IF mm <= 2 THEN                mm := mm + 12;                yy := yy - 1            FI;            INT j = yy OVER 100;            INT k = yy MOD  100;            (d + ( ( mm + 1 ) * 26 ) OVER 10 + k + k OVER 4 + j OVER 4 + 5 * j ) MOD 7         END # day of week # ;    # returns an array of the last Sunday of each month in year  #    PROC last sundays = ( INT year )[]INT:         BEGIN            [ 1 : 12 ]INT last days := ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );            IF is leap year( year ) THEN last days[ 2 ] := 29 FI;            # for each month, determine the day number of the    #            # last Sunday                                        #            [ 1 : 12 ]INT last;            FOR m pos TO 12 DO                INT dow := day of week( last days[ m pos ], m pos, year );                IF dow = 0 # Saturday # THEN dow := 7 FI;                # calculate the offset for the previous Sunday   #                last[ m pos ] := ( last days[ m pos ] + 1 ) - dow            OD;            last         END # last sundays # ;    # test the last sundays procedure                            #    INT   year = 2021;    []INT last = last sundays( year );    FOR m pos TO 12 DO        print( ( whole( year, 0 )               , IF m pos < 10 THEN "-0" ELSE "-1" FI               , whole( m pos MOD 10, 0 )               , "-"               , whole( last[ m pos ], 0 )               , newline               )             )    ODEND`
Output:
```2021-01-31
2021-02-28
2021-03-28
2021-04-25
2021-05-30
2021-06-27
2021-07-25
2021-08-29
2021-09-26
2021-10-31
2021-11-28
2021-12-26
```

## ALGOL-M

` 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; % RETURN 1 IF Y IS A LEAP YEAR, OTHERWISE 0 %INTEGER FUNCTION ISLEAPYR(Y);INTEGER Y;BEGIN  IF MOD(Y,4) <> 0 THEN  % QUICK EXIT IN MOST COMMON CASE %    ISLEAPYR := 0  ELSE IF MOD(Y,400) = 0 THEN    ISLEAPYR := 1  ELSE IF MOD(Y,100) = 0 THEN    ISLEAPYR := 0  ELSE                   % NON-CENTURY AND DIVISIBLE BY 4 %    ISLEAPYR := 1;END; % RETURN THE NUMBER OF DAYS IN THE SPECIFIED MONTH %INTEGER FUNCTION MONTHDAYS(MO, YR);INTEGER MO, YR;BEGIN  IF MO = 2 THEN    BEGIN      IF ISLEAPYR(YR) = 1 THEN        MONTHDAYS := 29      ELSE        MONTHDAYS := 28;    END  ELSE IF (MO = 4) OR (MO = 6) OR (MO = 9) OR (MO = 11) THEN    MONTHDAYS := 30  ELSE    MONTHDAYS := 31;END; COMMENT  RETURN THE DAY OF THE MONTH CORRESPONDING TO LAST OCCURRENCE  OF WEEKDAY K (SUN=0, MON=1, ETC.) FOR A GIVEN MONTH AND YEAR;INTEGER FUNCTION LASTKDAY(K, M, Y);INTEGER K, M, Y;BEGIN  INTEGER D, W;  % DETERMINE WEEKDAY FOR THE LAST DAY OF THE MONTH %  D := MONTHDAYS(M, Y);  W := DAYOFWEEK(M, D, Y);  % BACK UP AS NEEDED TO DESIRED WEEKDAY %  IF W >= K THEN    D := D - (W - K)  ELSE    D := D - (7 - K - W);  LASTKDAY := D;END; STRING FUNCTION MONTHNAME(N);INTEGER N;BEGIN  CASE (N - 1) OF    BEGIN      MONTHNAME := "JAN";      MONTHNAME := "FEB";      MONTHNAME := "MAR";      MONTHNAME := "APR";      MONTHNAME := "MAY";      MONTHNAME := "JUN";      MONTHNAME := "JUL";      MONTHNAME := "AUG";      MONTHNAME := "SEP";      MONTHNAME := "OCT";      MONTHNAME := "NOV";      MONTHNAME := "DEC";    END;END; % EXERCISE THE ROUTINE %INTEGER M, Y, SUNDAY;SUNDAY := 0;WRITE("DISPLAY LAST SUNDAYS FOR WHAT YEAR?");READ(Y);FOR M:=1 STEP 1 UNTIL 12 DO  WRITE(MONTHNAME(M), LASTKDAY(SUNDAY,M,Y)); END `
Output:
```DISPLAY LAST SUNDAYS FOR WHAT YEAR?
-> 2021
JAN    31
FEB    28
MAR    28
APR    25
MAY    30
JUN    27
JUL    25
AUG    29
SEP    26
OCT    31
NOV    28
DEC    26
```

## ALGOL W

Uses the Day_of_week and isLeapYear procedures from the day-of-the-week and leap-year tasks - included here for convenience.

`begin % find the last Sunday in each month of a year             %    % returns true if year is a leap year, false otherwise       %    % assumes year is in the Gregorian Calendar                  %    logical procedure isLeapYear ( integer value year ) ;        year rem 400 = 0 or ( year rem 4 = 0 and year rem 100 not = 0 );    % returns the day of the week of the specified date (d/m/y)  %    %         Sunday = 1                                         %    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;    % sets the elements of last to the day of the last Sunday   %    % of each month in year                                     %    procedure lastSundays ( integer value year                          ; integer array last ( * )                          ) ;        begin            integer array lastDays ( 1 :: 12 );            integer m;            % set ld to the day number od the last day of each  %            % month in year                                     %            m := 1;            for ld := 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 do begin                lastDays( m ) := ld;                m             := m + 1            end for_ld ;            if isLeapYear( year ) then lastDays( 2 ) := 29;            % for each month, determine the day number of the   %            % last Sunday                                       %            for mPos := 1 until 12 do begin                integer dow;                dow := Day_of_week( lastDays( mPos ), mPos, year );                if dow = 0 % Saturday % then dow := 7;                % calculate the offset for the previous Sunday  %                last( mPos ) := ( lastDays( mPos ) + 1 ) - dow            end for_mPos        end lastSundays ;    begin        % test the lastSundays procedure                        %        integer array last ( 1 :: 12 );        integer year;        year := 2020;        lastSundays( year, last );        i_w := 1; s_w := 0; % output formatting                 %        for mPos := 1 until 12 do write( year, if mPos < 10 then "-0" else "-1", mPos rem 10, "-", last( mPos ) )    endend.`
Output:
```2020-01-26
2020-02-23
2020-03-29
2020-04-26
2020-05-31
2020-06-28
2020-07-26
2020-08-30
2020-09-27
2020-10-25
2020-11-29
2020-12-27
```

## AppleScript

Translation of: JavaScript
`-- LAST SUNDAYS OF YEAR ------------------------------------------------------ --  lastSundaysOfYear :: Int -> [Date]on lastSundaysOfYear(y)     -- lastWeekDaysOfYear :: Int -> Int -> [Date]    script lastWeekDaysOfYear        on |λ|(intYear, iWeekday)             -- lastWeekDay :: Int -> Int -> Date            script lastWeekDay                on |λ|(iLastDay, iMonth)                    set iYear to intYear                     calendarDate(iYear, iMonth, iLastDay - ¬                        (((weekday of calendarDate(iYear, iMonth, iLastDay)) as integer) + ¬                            (7 - (iWeekday))) mod 7)                end |λ|            end script             map(lastWeekDay, lastDaysOfMonths(intYear))        end |λ|         -- isLeapYear :: Int -> Bool        on isLeapYear(y)            (0 = y mod 4) and (0 ≠ y mod 100) or (0 = y mod 400)        end isLeapYear         -- lastDaysOfMonths :: Int -> [Int]        on lastDaysOfMonths(y)            {31, cond(isLeapYear(y), 29, 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}        end lastDaysOfMonths    end script     lastWeekDaysOfYear's |λ|(y, Sunday as integer)end lastSundaysOfYear  -- TEST ----------------------------------------------------------------------on run argv     intercalate(linefeed, ¬        map(isoRow, ¬            transpose(map(lastSundaysOfYear, ¬                apply(cond(class of argv is list and argv ≠ {}, ¬                    singleYearOrRange, fiveCurrentYears), argIntegers(argv)))))) end run -- ARGUMENT HANDLING --------------------------------------------------------- -- Up to two optional command line arguments: [yearFrom], [yearTo]-- (Default range in absence of arguments: from two years ago, to two years ahead) -- ~ \$ osascript ~/Desktop/lastSundays.scpt -- ~ \$ osascript ~/Desktop/lastSundays.scpt 2013-- ~ \$ osascript ~/Desktop/lastSundays.scpt 2013 2016 -- singleYearOrRange :: [Int] -> [Int]on singleYearOrRange(argv)    apply(cond(length of argv > 0, my range, my fiveCurrentYears), argv)end singleYearOrRange -- fiveCurrentYears :: () -> [Int]on fiveCurrentYears(_)    set intThisYear to year of (current date)    enumFromTo(intThisYear - 2, intThisYear + 2)end fiveCurrentYears -- argIntegers :: maybe [String] -> [Int]on argIntegers(argv)    if class of argv is list and argv ≠ {} then        {map(my parseInt, argv)}    else        {}    end ifend argIntegers  -- GENERIC FUNCTIONS --------------------------------------------------------- -- apply (a -> b) -> a -> bon apply(f, a)    mReturn(f)'s |λ|(a)end apply -- calendarDate :: Int -> Int -> Int -> Dateon calendarDate(intYear, intMonth, intDay)    tell (current date)        set {its year, its month, its day, its time} to ¬            {intYear, intMonth, intDay, 0}        return it    end tellend calendarDate -- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)on cond(bool, f, g)    if bool then        f    else        g    end ifend cond -- enumFromTo :: Int -> Int -> [Int]on enumFromTo(m, n)    if m > n then        set d to -1    else        set d to 1    end if    set lst to {}    repeat with i from m to n by d        set end of lst to i    end repeat    return lstend enumFromTo -- intercalate :: Text -> [Text] -> Texton intercalate(strText, lstText)    set {dlm, my text item delimiters} to ¬        {my text item delimiters, strText}    set strJoined to lstText as text    set my text item delimiters to dlm    return strJoinedend intercalate -- isoDateString :: Date -> Stringon isoDateString(dte)    (((year of dte) as string) & ¬        "-" & text items -2 thru -1 of ¬        ("0" & ((month of dte) as integer) as string)) & ¬        "-" & text items -2 thru -1 of ¬        ("0" & day of dte)end isoDateString -- isoRow :: [Date] -> Stringon isoRow(lstDate)    intercalate(tab, map(my isoDateString, lstDate))end isoRow -- map :: (a -> b) -> [a] -> [b]on map(f, xs)    tell mReturn(f)        set lng to length of xs        set lst to {}        repeat with i from 1 to lng            set end of lst to |λ|(item i of xs, i, xs)        end repeat        return lst    end tellend map -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Scripton mReturn(f)    if class of f is script then        f    else        script            property |λ| : f        end script    end ifend mReturn -- parseInt :: String -> Inton parseInt(s)    s as integerend parseInt -- transpose :: [[a]] -> [[a]]on transpose(xss)    script column        on |λ|(_, iCol)            script row                on |λ|(xs)                    item iCol of xs                end |λ|            end script             map(row, xss)        end |λ|    end script     map(column, item 1 of xss)end transpose`
Output:
```2015-01-25    2016-01-31    2017-01-29    2018-01-28    2019-01-27
2015-02-22    2016-02-28    2017-02-26    2018-02-25    2019-02-24
2015-03-29    2016-03-27    2017-03-26    2018-03-25    2019-03-31
2015-04-26    2016-04-24    2017-04-30    2018-04-29    2019-04-28
2015-05-31    2016-05-29    2017-05-28    2018-05-27    2019-05-26
2015-06-28    2016-06-26    2017-06-25    2018-06-24    2019-06-30
2015-07-26    2016-07-31    2017-07-30    2018-07-29    2019-07-28
2015-08-30    2016-08-28    2017-08-27    2018-08-26    2019-08-25
2015-09-27    2016-09-25    2017-09-24    2018-09-30    2019-09-29
2015-10-25    2016-10-30    2017-10-29    2018-10-28    2019-10-27
2015-11-29    2016-11-27    2017-11-26    2018-11-25    2019-11-24
2015-12-27    2016-12-25    2017-12-31    2018-12-30    2019-12-29```

More straightforward solution:

AppleScript's weekday constants can be coerced either to English text or to the integers 1 (for Sunday) to 7 (Saturday).

`on lastSundayOfEachMonthInYear(y)	-- Initialise an AppleScript date to the first day of some month in the specified year.	tell (current date) to set {firstDayOfNextMonth, its day, its year} to {it, 1, y} 	-- Get a string representation of y, zero-padded if necessary, and initialise the output string.	set y to text 2 thru 5 of ((10000 + y) as text)	set outputText to "./last_sundays " & y	repeat with nextMonth from 2 to 13 -- Yes!		-- For each month in the year, get the first day of the following month.		set firstDayOfNextMonth's month to nextMonth		-- Calculate the date of the Sunday which occurs in the seven days prior to that		-- by subtracting a day plus the difference between the previous day's weekday and the target weekday.		set lastSundayOfThisMonth to firstDayOfNextMonth - (1 + ((firstDayOfNextMonth's weekday) + 5) mod 7) * days		-- Append the required details to the output text.		set {month:m, day:d} to lastSundayOfThisMonth		tell (10000 + m * 100 + d) as text to ¬			set outputText to outputText & (linefeed & y & "-" & text 2 thru 3 & "-" & text 4 thru 5)	end repeat 	return outputTextend lastSundayOfEachMonthInYear lastSundayOfEachMonthInYear(2020)`
Output:
```"./last_sundays 2020
2020-01-26
2020-02-23
2020-03-29
2020-04-26
2020-05-31
2020-06-28
2020-07-26
2020-08-30
2020-09-27
2020-10-25
2020-11-29
2020-12-27"```

The above is hard-coded for Sundays. As with the "Last Friday of each month" task [Last Friday of each month], the handler can be made more flexible with a weekday constant parameter, so that it can be used for any last weekday of the months:

`on lastWeekdayWOfEachMonthInYear(w, y) -- Parameters: (AppleScript weekday constant, AD year number)	-- Initialise an AppleScript date to the first day of some month in the specified year.	tell (current date) to set {firstDayOfNextMonth, its day, its year} to {it, 1, y} 	-- Get a string representation of y, zero-padded if necessary, and initialise the output string.	set y to text 2 thru 5 of ((10000 + y) as text)	set outputText to "./last_" & w & "s " & y	repeat with nextMonth from 2 to 13 -- Yes!		-- For each month in the year, get the first day of the following month.		set firstDayOfNextMonth's month to nextMonth		-- Calculate the date of the target weekday which occurs in the seven days prior to that.		-- The calculation can be described in various ways, the simplest being the subtraction of a day plus the difference between the previous day's weekday and the target weekday:		--	firstDayOfNextMonth - (1 + (((firstDayOfNextMonth's weekday) - 1) - w + 7) mod 7) * days		-- But they all boil down to:		set lastWOfThisMonth to firstDayOfNextMonth - (1 + ((firstDayOfNextMonth's weekday) - w + 6) mod 7) * days		-- Get the day and month of the calculated date and append the required details to the output text.		set {month:m, day:d} to lastWOfThisMonth		tell (10000 + m * 100 + d) as text to ¬			set outputText to outputText & (linefeed & y & "-" & text 2 thru 3 & "-" & text 4 thru 5)	end repeat 	return outputTextend lastWeekdayWOfEachMonthInYear lastWeekdayWOfEachMonthInYear(Sunday, 2020)`
Output:
```"./last_Sundays 2020
2020-01-26
2020-02-23
2020-03-29
2020-04-26
2020-05-31
2020-06-28
2020-07-26
2020-08-30
2020-09-27
2020-10-25
2020-11-29
2020-12-27"```

## Arturo

`lastSundayForMonth: function [m,y][    ensure -> in? m 1..12     daysOfMonth: @[0 31 (leap? y)? -> 28 -> 27 31 30 31 30 31 31 30 31 30 31]    loop range get daysOfMonth m 1 [d][        dt: to :date.format:"yyyy-M-dd" ~"|y|-|m|-|d|"        if dt\Day = "Sunday" -> return dt    ]] getLastSundays: function [year][    loop 1..12 'month [        print to :string.format:"yyyy-MM-dd" lastSundayForMonth month year    ]] getLastSundays 2013`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## AutoHotkey

`InputBox, Year, , Enter a year., , 300, 135Date := Year . "0101" while SubStr(Date, 1, 4) = Year {    FormatTime, WD, % Date, WDay    if (WD = 1)        MM := LTrim(SubStr(Date, 5, 2), "0"), Day%MM% := SubStr(Date, 7, 2)    Date += 1, Days} Gui, Font, S10, Courier NewGui, Add, Text, , % "Last Sundays of " Year ":`n---------------------" Loop, 12 {    FormatTime, Month, % Year (A_Index > 9 ? "" : "0") A_Index, MMMM    Gui, Add, Text, y+1, % Month (StrLen(Month) > 7 ? "" : "`t") "`t" Day%A_Index%} Gui, Showreturn`
Output:
```Last Sundays of 2013:
---------------------
January		27
February	24
March		31
April		28
May		26
June		30
July		28
August		25
September	29
October		27
November	24
December	29```

## AWK

` # syntax: GAWK -f FIND_THE_LAST_SUNDAY_OF_EACH_MONTH.AWK [year]BEGIN {    split("31,28,31,30,31,30,31,31,30,31,30,31",daynum_array,",") # days per month in non leap year    year = (ARGV[1] == "") ? strftime("%Y") : ARGV[1]    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {      daynum_array[2] = 29    }    for (m=1; m<=12; m++) {      for (d=daynum_array[m]; d>=1; d--) {        if (strftime("%a",mktime(sprintf("%d %d %d 0 0 0",year,m,d))) == "Sun") {          printf("%04d-%02d-%02d\n",year,m,d)          break        }      }    }    exit(0)} `

Output:

```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Batch File

Uses day of week, last day of month and leapyear routines

` @echo offsetlocal enabledelayedexpansionset /p yr= Enter year: echo.call:monthdays %yr% list set mm=1for %%i in (!list!) do (  call:calcdow !yr! !mm! %%i dow  set/a lsu=%%i-dow  set mf=0!mm!  echo !yr!-!mf:~-2!-!lsu!   set /a mm+=1)pauseexit /b :monthdays yr &listsetlocalcall:isleap %1 lyfor /L %%i in (1,1,12) do (  set /a "nn = 30 + ^!(((%%i & 9) + 6) %% 7) + ^!(%%i ^^ 2) * (ly - 2)  set list=!list! !nn!)endlocal & set %2=%list%exit /b :calcdow yr mt dy &dow  :: 0=sundaysetlocalset/a a=(14-%2)/12,yr=%1-a,m=%2+12*a-2,"dow=(%3+yr+yr/4-yr/100+yr/400+31*m/12)%%7"endlocal & set %~4=%dow%exit /b :isleap yr &leap  :: remove ^ if not delayed expansionset /a "%2=^!(%1%%4)+(^!^!(%1%%100)-^!^!(%1%%400))"exit /b `
Output:
```Enter year: 2016

2016-01-31
2016-02-28
2016-03-27
2016-04-24
2016-05-29
2016-06-26
2016-07-31
2016-08-28
2016-09-25
2016-10-30
2016-11-27
2016-12-25
```

## BBC BASIC

` INSTALL @lib\$+"DATELIB" INPUT "What year to calculate (YYYY)? " Year% PRINT '"Last Sundays in ";Year%;" are on:"FOR Month%=1 TO 12  PRINT Year% "-" RIGHT\$("0"+STR\$Month%,2) "-";FN_dim(Month%,Year%)-FN_dow(FN_mjd(FN_dim(Month%,Year%),Month%,Year%))NEXTEND `
Output:
```What year to calculate (YYYY)? 2013

Last Sundays in 2013 are on:
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Befunge

This is essentially identical to Last Friday of each month except for the initial day offset.

`":raeY",,,,,&>55+,:::45*:*%\"d"%!*\4%+!3vv2++6**"I"5\+/*:*54\-/"d"\/4::-1::p53+g5<>:00p5g4-+7%\:0\v>,"-",5g+:55+/68*+,55+%v^<<_\$\$vv*86%+55:<^+*86%+55,+*86/+55:-1:<6>\$\$^@\$<>+\55+/:#^_\$>:#,_\$"-",\:04-\-00g^8^<# #"#"##"#"##!`       +76:+1g00,+55,+*<`
Output:
```Year:2013

2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## C

Identical to Last Friday of each month except for removal of the offset day in the output.

` #include <stdio.h>#include <stdlib.h> int main(int argc, char *argv[]){        int days[] = {31,29,31,30,31,30,31,31,30,31,30,31};        int m, y, w;         if (argc < 2 || (y = atoi(argv[1])) <= 1752) return 1;        days[1] -= (y % 4) || (!(y % 100) && (y % 400));        w = y * 365 + 97 * (y - 1) / 400 + 4;         for(m = 0; m < 12; m++) {                w = (w + days[m]) % 7;                printf("%d-%02d-%d\n", y, m + 1,days[m] - w);        }         return 0;} `

## C#

`using System; namespace LastSundayOfEachMonth{    class Program    {        static void Main()        {            Console.Write("Year to calculate: ");             string strYear = Console.ReadLine();            int year = Convert.ToInt32(strYear);             DateTime date;            for (int i = 1; i <= 12; i++)            {                date = new DateTime(year, i, DateTime.DaysInMonth(year, i), System.Globalization.CultureInfo.CurrentCulture.Calendar);                /* Modification by Albert Zakhia on 2021-16-02                   The below code is very slow due to the loop, we will go twice as fast                while (date.DayOfWeek != DayOfWeek.Sunday)                {                    date = date.AddDays(-1);                }                */                // The updated code                int daysOffset = date.DayOfWeek - dayOfWeek; // take the offset to subtract directly instead of looping                if (daysOffset < 0) daysOffset += 7; // if the code is negative, we need to normalize them                date = date.AddDays(-daysOffset ); // now just add the days offset                Console.WriteLine(date.ToString("yyyy-MM-dd"));            }        }    }} `
Output:
```Year to calculate: 2013
2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29
```

## C++

` #include <windows.h>#include <iostream>#include <string> //--------------------------------------------------------------------------------------------------using namespace std; //--------------------------------------------------------------------------------------------------class lastSunday{public:    lastSunday()    {	m[0]  = "JANUARY:   "; m[1]  = "FEBRUARY:  "; m[2]  = "MARCH:     "; m[3]  = "APRIL:     "; 	m[4]  = "MAY:       "; m[5]  = "JUNE:      "; m[6]  = "JULY:      "; m[7]  = "AUGUST:    "; 	m[8]  = "SEPTEMBER: "; m[9]  = "OCTOBER:   "; m[10] = "NOVEMBER:  "; m[11] = "DECEMBER:  ";     }     void findLastSunday( int y )    {	year = y;	isleapyear(); 	int days[] = { 31, isleap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },		d;	for( int i = 0; i < 12; i++ )	{	    d = days[i];	    while( true )	    {		if( !getWeekDay( i, d ) ) break;		d--;	    }	    lastDay[i] = d;	} 	display();    } private:    void isleapyear()    {	isleap = false;	if( !( year % 4 ) )	{	    if( year % 100 ) isleap = true;	    else if( !( year % 400 ) ) isleap = true;	}    }     void display()    {	system( "cls" );	cout << "  YEAR " << year << endl << "=============" << endl;	for( int x = 0; x < 12; x++ )	    cout << m[x] << lastDay[x] << endl; 	cout << endl << endl;    }     int getWeekDay( int m, int d )    {	int y = year; 	int f = y + d + 3 * m - 1;	m++;	if( m < 3 ) y--;	else f -= int( .4 * m + 2.3 ); 	f += int( y / 4 ) - int( ( y / 100 + 1 ) * 0.75 );	f %= 7; 	return f;    }     int lastDay[12], year;    string m[12];    bool isleap;};//--------------------------------------------------------------------------------------------------int main( int argc, char* argv[] ){    int y;    lastSunday ls;     while( true )    {	system( "cls" );	cout << "Enter the year( yyyy ) --- ( 0 to quit ): "; 	cin >> y;	if( !y ) return 0; 	ls.findLastSunday( y ); 	system( "pause" );    }    return 0;}//-------------------------------------------------------------------------------------------------- `
Output:
```  YEAR 2013
=============
JANUARY:   27
FEBRUARY:  24
MARCH:     31
APRIL:     28
MAY:       26
JUNE:      30
JULY:      28
AUGUST:    25
SEPTEMBER: 29
OCTOBER:   27
NOVEMBER:  24
DECEMBER:  29
```

Other solution, based on the Boost DateTime library:

`#include <iostream>#include <boost/date_time/gregorian/gregorian.hpp>#include <cstdlib> int main( int argc , char* argv[ ] ) {   using namespace boost::gregorian ;    int year =  std::atoi( argv[ 1 ] ) ;   for ( int i = 1 ; i < 13 ; i++ ) {      try { 	 date d( year , i , 1  ) ;	 d = d.end_of_month( ) ;	 day_iterator d_itr ( d ) ;	 while ( d_itr->day_of_week( ) != Sunday ) {	    --d_itr ;	 }	 std::cout << to_simple_string ( *d_itr ) << std::endl ;      } catch ( bad_year by ) {	  std::cout << "Terminated because of " << by.what( ) << "\n" ;      }   }   return 0 ;}`
Output:
```2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29
```

## Clojure

`(ns last-sundays.core  (:require [clj-time.core :as time]            [clj-time.periodic :refer [periodic-seq]]            [clj-time.format :as fmt])  (:import (org.joda.time DateTime DateTimeConstants))  (:gen-class)) (defn sunday? [t]  (= (.getDayOfWeek t) (DateTimeConstants/SUNDAY))) (defn sundays [year]  (take-while #(= (time/year %) year)              (filter sunday? (periodic-seq (time/date-time year 1 1) (time/days 1))))) (defn last-sundays-of-months [year]  (->> (sundays year)       (group-by time/month)       (vals)       (map (comp first #(sort-by time/day > %)))       (map #(fmt/unparse (fmt/formatters :year-month-day) %))       (interpose "\n")       (apply str))) (defn -main [& args]  (println (last-sundays-of-months (Integer. (first args))))) `
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## COBOL

`        program-id. last-sun.       data division.       working-storage section.       1 wk-date.        2 yr pic 9999.        2 mo pic 99 value 1.        2 da pic 99 value 1.       1 rd-date redefines wk-date pic 9(8).       1 binary.        2 int-date pic 9(8).        2 dow pic 9(4).        2 sunday pic 9(4) value 7.       procedure division.           display "Enter a calendar year (1601 thru 9999): "               with no advancing           accept yr           if yr >= 1601 and <= 9999               continue           else               display "Invalid year"               stop run           end-if           perform 12 times               move 1 to da               add 1 to mo               if mo > 12              *> to avoid y10k in 9999                   move 12 to mo                   move 31 to da               end-if               compute int-date = function                   integer-of-date (rd-date)               if mo =12 and da = 31   *> to avoid y10k in 9999                   continue               else                   subtract 1 from int-date               end-if               compute rd-date = function                   date-of-integer (int-date)               compute dow = function mod                   ((int-date - 1) 7) + 1               compute dow = function mod ((dow - sunday) 7)               subtract dow from da               display yr "-" mo "-" da               add 1 to mo           end-perform           stop run           .       end program last-sun. `
Output:
```2016-01-31
2016-02-28
2016-03-27
2016-04-24
2016-05-29
2016-06-26
2016-07-31
2016-08-28
2016-09-25
2016-10-30
2016-11-27
2016-12-25
```

## Common Lisp

First, calculate the day of week of the 1st day of next month. Then figure out how many days you have to go back until the last Sunday of the month.

`(defun last-sundays (year)  (loop for month from 1 to 12        for last-month-p = (= month 12)        for next-month = (if last-month-p 1 (1+ month))        for year-of-next-month = (if last-month-p (1+ year) year)        for 1st-day-next-month = (encode-universal-time 0 0 0 1 next-month year-of-next-month 0)        for 1st-day-dow = (nth-value 6 (decode-universal-time 1st-day-next-month 0))        ;; 0: monday, 1: tuesday, ... 6: sunday        for diff-to-last-sunday = (1+ 1st-day-dow)        for last-sunday = (- 1st-day-next-month (* diff-to-last-sunday 24 60 60))        do (multiple-value-bind (second minute hour date month year)               (decode-universal-time last-sunday 0)             (declare (ignore second minute hour))             (format t "~D-~2,'0D-~2,'0D~%" year month date)))) (last-sundays 2013)`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## D

`void lastSundays(in uint year) {    import std.stdio, std.datetime;     foreach (immutable month; 1 .. 13) {        auto date = Date(year, month, 1);        date.day(date.daysInMonth);        date.roll!"days"(-(date.dayOfWeek + 7) % 7);        date.writeln;    }} void main() {    lastSundays(2013);}`
Output:
```2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29```

## Delphi

Translation of: C#
` program Find_the_last_Sunday_of_each_month; {\$APPTYPE CONSOLE} uses  System.SysUtils,  System.DateUtils; // ADayOfWeek -> sunday is the first day and is 1function LastDayOfWeekOfEachMonth(AYear, ADayOfWeek: Word): TArray<TDateTime>;var  month: word;  daysOffset: Integer;  date: TDatetime;begin  if (ADayOfWeek > 7) or (ADayOfWeek < 1) then    raise Exception.CreateFmt('Error on FindAllDaysOfWeek: "%d" must be in [1..7] (sun..sat)',      [ADayOfWeek]);   SetLength(Result, 12);   for month := 1 to 12 do  begin    date := EncodeDate(AYear, month, DaysInAMonth(AYear, month));     daysOffset := DayOfWeek(date) - ADayOfWeek;    if daysOffset < 0 then      inc(daysOffset, 7);     Result[month - 1] := date - daysOffset;  end;end; var  strYear: string;  Year: Integer;  date: TDateTime; begin  write('Year to calculate: ');  Readln(strYear);  if not TryStrToInt(strYear, Year) or (Year < 1900) then    raise Exception.CreateFmt('Error: "%s" is not a valid year', [strYear]);   for date in LastDayOfWeekOfEachMonth(Year, 1) do    writeln(FormatDateTime('yyyy-mmm-dd', date));   readln;end.`

## Elixir

`defmodule RC do  def lastSunday(year) do    Enum.map(1..12, fn month ->      lastday = :calendar.last_day_of_the_month(year, month)      daynum = :calendar.day_of_the_week(year, month, lastday)      sunday = lastday - rem(daynum, 7)      {year, month, sunday}    end)  end  end y = String.to_integer(hd(System.argv))Enum.each(RC.lastSunday(y), fn {year, month, day} ->  :io.format "~4b-~2..0w-~2..0w~n", [year, month, day]end)`
Output:
```C:\Elixir>elixir lastSunday.exs 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Emacs Lisp

`(require 'calendar) (defun last-sunday (year)  "Print the last Sunday in each month of year"  (mapcar (lambda (month)    (let*      ((days (number-sequence 1 (calendar-last-day-of-month month year)))       (mdy (mapcar (lambda (x) (list month x year)) days))       (weekdays (mapcar #'calendar-day-of-week mdy))       (lastsunday (1+ (cl-position 0 weekdays :from-end t))))      (insert (format "%i-%02i-%02i \n" year month lastsunday))))    (number-sequence 1 12))) (last-sunday 2013)`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29 ```

## Erlang

` -module(last_sundays). -export([in_year/1]). % calculate all the last sundays in a particular yearin_year(Year) ->    [lastday(Year, Month, 7) || Month <- lists:seq(1, 12)]. % calculate the date of the last occurrence of a particular weekdaylastday(Year, Month, WeekDay) ->    Ldm = calendar:last_day_of_the_month(Year, Month),    Diff = calendar:day_of_the_week(Year, Month, Ldm) rem WeekDay,    {Year, Month, Ldm - Diff}.  `
Output:
```30> [io:fwrite("~B-~2.10.0B-~B~n", [Y,M,D]) || {Y,M,D} <- last_sundays:in_year(2013)].
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Excel

### LAMBDA

Binding the name lastSundayOfEachMonth to the following lambda expression in the Name Manager of the Excel WorkBook:

`lastSundayOfEachMonth=LAMBDA(y,    LAMBDA(monthEnd,        1 + monthEnd - WEEKDAY(monthEnd)    )(        EDATE(            DATEVALUE(y & "-01-31"),            SEQUENCE(12, 1, 0, 1)        )    ))`
Output:

The formula in cell B2 defines an array which populates the range B2:B13.

(Any Excel date format can be applied to those cells)

 =lastSundayOfEachMonth(A2) fx A B 1 Year Last Sundays 2 2013 2013-01-27 3 2013-02-24 4 2013-03-31 5 2013-04-27 6 2013-05-25 7 2013-06-29 8 2013-07-27 9 2013-08-24 10 2013-09-28 11 2013-10-26 12 2013-11-24 13 2013-12-29

## F#

We use a transformation from and to the Julian Day Number, see also PARI/GP or Fortran.

The formulars used here come from [2] (section "Calculation").

`let jdn (year, month, day) =    let a = (14 - month) / 12    let y = year + 4800 - a    let m = month + 12 * a - 3    day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 - 32045 let date_from_jdn jdn =    let j = jdn + 32044    let g = j / 146097    let dg = j % 146097    let c = (dg / 36524 + 1) * 3 / 4    let dc = dg - c * 36524    let b = dc / 1461    let db = dc % 1461    let a = (db / 365 + 1) * 3 / 4    let da = db - a * 365    let y = g * 400 + c * 100 + b * 4 + a    let m = (da * 5 + 308) / 153 - 2    let d = da - (m + 4) * 153 / 5 + 122    (y - 4800 + (m + 2) / 12, (m + 2) % 12 + 1, d + 1) [<EntryPoint>]let main argv =    let year = System.Int32.Parse(argv.[0])    [for m in 1..12 do yield jdn (year,m+1,0)]    |> List.map (fun x -> date_from_jdn (x - (x+1)%7))    |> List.iter (printfn "%A")    0`
Output:
```RosettaCode 2016
(2016, 1, 31)
(2016, 2, 28)
(2016, 3, 27)
(2016, 4, 24)
(2016, 5, 29)
(2016, 6, 26)
(2016, 7, 31)
(2016, 8, 28)
(2016, 9, 25)
(2016, 10, 30)
(2016, 11, 27)
(2016, 12, 25)```

## Factor

This program expects a year passed in via command line argument. In case you are wondering — yes — Factor has a last-sunday-of-month word in its calendar vocabulary. This is par for the course when it comes to Factor.

`USING: calendar calendar.format command-line io kernel math math.parsersequences ;IN: rosetta-code.last-sunday : parse-year     (    -- ts  ) (command-line) second string>number <year> ;: print-last-sun ( ts --     ) last-sunday-of-month (timestamp>ymd) nl ;: inc-month      ( ts -- ts' ) 1 months time+ ;: process-month  ( ts -- ts' ) dup print-last-sun inc-month ;: main           (    --     ) parse-year 12 [ process-month ] times drop ; MAIN: main`
Output:
```>factor last-sunday.factor 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## FBSL

`#APPTYPE CONSOLE DIM date AS INTEGER, dayname AS STRINGFOR DIM i = 1 TO 12    FOR DIM j = 31 DOWNTO 1        date = 20130000 + (i * 100) + j        IF CHECKDATE(i, j, 2013) THEN            dayname = DATECONV(date, "dddd")            IF dayname = "Sunday" THEN                PRINT 2013, " ", i, " ", j                EXIT FOR            END IF        END IF    NEXTNEXT PAUSE `
Output:
```2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29

Press any key to continue...
```

## Fortran

Having already functions that calculate a daynumber from a date and the reverse, the notorious routines of H. F. Fliegel and T. C. van Flandern, the problem becomes simple. Their routine calculates the Julian day number but my version adjusts so that day zero is the thirty-first of December 1899, which is a Sunday. Thus, the day of the week is given by MOD(Daynumber,7) with zero for Sunday up to six for Saturday, as per Genesis.

Their routine is not only fast, but flexible, in particular allowing Month + 1 so that DAYNUM(Y,M + 1,0) gives the last day of month M for M = 1 to 12, with no agony over which month has what last day and leap years or not. If W is the day of week desired, all that remains is to use MOD(D - W,7) to determine the offset back to the desired day of the week and make that shift. There is a problem with the MOD function when negative numbers are involved: it may or may not (depending on computer, compiler, language) return a negative result; by adding 7 and taking a MOD again, this variation is suppressed.

The source uses the MODULE protocol for convenience in its usage in larger projects (which contain a calculation for Easter, daylight savings changeover dates, solar azimuth and altitude, etc. which have been removed here), but requires only F77 features, except for the annoyance of the MUNYAD function returning a TYPE(DATEBAG) result to get the three parts. This is an example where a palindromic programming protocol would be so much better. One would write
`      D = DAYNUM(Y,M,D)    !Daynumber from date.      DAYNUM(Y,M,D) = D    !Date parts from a day number.`

But alas, only pl/i offers palindromic functions, and only for SUBSTR.

`       MODULE DATEGNASHC          Calculate conforming to complex calendarical contortions.C   Astronomer Simon Newcomb determined that the tropical year of 1900c contained 31556925.9747 seconds, or 365.24219879 days.c Subsequent definitions involve "no measurable differences",c whereas in 45BC (when the Julian calendar was adopted), the year wasc 365.24232 days long, going by modern calculations.c   The "tropical" year is the time between the same equinoxes, and thusc contains the effect of the precession of the Earth's axis, which wouldc otherwise cause the seasons to likewise precess around the "fixed star"c year, that being the time for midnight to point in the same directionc amongst the "fixed" stars. Specifically, the vernal equinoxc (the northern hemisphere's spring equinox: cultural colonialism)c is meant to hover around the 21'st of March, although it may fallc within the 19'th or 20'th, which last has been the most popular inc the 20'th century, until the leap year of 2000 resynchronisedc the civil calendar.C   By contrast, the computations of astrologers are still based on thec constellations as oriented in Babylonian times... c   So, to add .24219879 to 365 days...c   Adjustment per year   Nett     Discrepancy remaining.c   +1/4     +.25        +.25      -.00780121  5h 48m 45.98sc   -1/100   -.01         .24      +.00219879    -11m 14.02sc   +1/400   +.0025       .2425    -.00030121        -26.02sc   -1/4000  -.00025      .24225   -.00005121         -4.42scc   The remnant of -.00005121 (meaning that the calendar year is too long)c amounts to needing to drop one day on 19,527 years, and while this could bec accommodated nicely enough by -1/20000 to give a calendar year ofc 365.24420 days with a remaining discrepancy of -.00000121 or -.01sec/year,c there is a problem. The Earth's spin is slowing by a similar amount.c   Similar to leap years and leap days are the leap seconds that since thec development of clocks based on atomic oscillations, have been added orc sometimes removed to keep clock time aligned with astronomical observations.c This additional confusion is not further considered.        TYPE DateBag		!Pack three parts into one.        INTEGER DAY,MONTH,YEAR	!The usual suspects.       END TYPE DateBag		!Simple enough.        CHARACTER*9 MONTHNAME(12),DAYNAME(0:6)	!Re-interpretations.       PARAMETER (MONTHNAME = (/"January","February","March","April",     1  "May","June","July","August","September","October","November",     2  "December"/))       PARAMETER (DAYNAME = (/"Sunday","Monday","Tuesday","Wednesday",     1  "Thursday","Friday","Saturday"/))	!Index this array with DayNum mod 7.       CHARACTER*3 MTHNAME(12)		!The standard abbreviations.       PARAMETER (MTHNAME = (/"JAN","FEB","MAR","APR","MAY","JUN",     1  "JUL","AUG","SEP","OCT","NOV","DEC"/))        INTEGER*4 JDAYSHIFT		!INTEGER*2 just isn't enough.       PARAMETER (JDAYSHIFT = 2415020)	!Thus shall 31/12/1899 give 0, a Sunday, via DAYNUM.       DOUBLE PRECISION DAYSINYEAR	!A real ache.       PARAMETER (DAYSINYEAR =  365.24219879D0)	!The "D0" demands DOUBLE PRECISION precision.       INTEGER*4 SECONDSINDAY			!This has its uses.       PARAMETER (SECONDSINDAY = 24*60*60)	!86400. Disregarding "leap" seconds.       INTEGER NOTADAYNUMBER			!Might as well settle on one value.       PARAMETER (NOTADAYNUMBER = -2147483648)	!And everyone use it.        PARAMETER NZBASEPLACE = "Mt. Cook Trig, Wellington."	!Name the place.       DOUBLE PRECISION NZBASELAT,NZBASELONG	!Alas, DATA statements do not allow arithmetic expressions.       PARAMETER (NZBASELAT = -((59.3 D0/60 + 17)/60 +  41))	!Degrees South, thus negative.       PARAMETER (NZBASELONG = ((34.65D0/60 + 46)/60 + 174))	!Degrees East are oriented as positive: left to right with N up.C                                   Seconds  Minutes Degrees.C   This is the location of the Mt. Cook trigonometrical base point for New Zealand.C    (It's in the foyer of what used to be the Dominion Museum, Wellington)C   Determined by Henry Jackson, chief surveyor, in 1870.        TYPE Terroir	!Collate the attributes of location, as so far needed.        CHARACTER*28 PLACENAME	!Name the location.        DOUBLE PRECISION LATITUDE,LONGITUDE	!Locate the location.        DOUBLE PRECISION ZONETIME	!The time zone of its civil clock, not necessarily a whole hour.       END TYPE Terroir		!The nature of the climate, soil, etc. is not yet involved.       TYPE(Terroir) BASE	!Righto, let's have one of them.       DATA BASE/Terroir("Mt. Cook Trig, Wellington.",	!The compiler bungles if NZBASEPLACE is used here.     1  NZBASELAT,NZBASELONG,+12.0)/	!Where it's at. +12 hours ahead = +180 degrees Eastward of Greenwhich.Careful! New Zealand is not centred on longitude 180, but its civil clock's time zone is.       DOUBLE PRECISION SINBASELAT,COSBASELAT	!Calculated in SOLARDIRECTION and ZAPME.       CONTAINS			!Let the madness begin.        INTEGER*4 FUNCTION DAYNUM(YY,M,D)	!Computes (JDayN - JDayShift), not JDayN.C   Conversion from a Gregorian calendar date to a Julian day number, JDayN.C   Valid for any Gregorian calendar date producing a Julian day numberC greater than zero, though remember that the Gregorian calendarC was not used before y1582m10d15 and often, not after that either.C thus in England (et al) when Wednesday 2'nd September 1752 (Julian style)C was followed by Thursday the 14'th, occasioning the Eleven Day riotsC because creditors demanded a full month's payment instead of 19/30'ths.C   The zero of the Julian day number corresponds to the first of JanuaryC 4713BC on the *Julian* calendar's naming scheme, as extended backwardsC with current usage into epochs when it did not exist: the proleptic Julian calendar.c This function employs the naming scheme of the *Gregorian* calendar,c and if extended backwards into epochs when it did not exist (thus thec proleptic Gregorian calendar) it would compute a zero for y-4713m11d24 *if*c it is supposed there was a year zero between 1BC and 1AD (as is convenientc for modern mathematics and astronomers and their simple calculations), *but*c 1BC immediately precedes 1AD without any year zero in between (and is a leap year)c thus the adjustment below so that the date is y-4714m11d24 or 4714BCm11d24,c not that this name was in use at the time...c   Although the Julian calendar (introduced by himself in what we would call 45BC,c which was what the Romans occasionally called 709AUC) was provoked by thec "years of confusion" resulting from arbitrary application of the rulesc for the existing Roman calendar, other confusions remain unresolved,c so precise dating remains uncertain despite apparently precise specificationsc (and much later, Dennis the Short chose wrongly for the birth of Christ)c and the Roman practice of inclusive reckoning meant that every four yearsc was interpreted as every third (by our exclusive reckoning) so that thec leap years were not as we now interpret them. This was resolved by Augustusc but exactly when (and what date name is assigned) and whose writings usedc which system at the time of writing is a matter of more confusion,c and this has continued for centuries.C   Accordingly, although an algorithm may give a regular sequence of date names,c that does not mean that those date names were used at the time even if thec calendar existed then, because the interpretation of the algorithm varied.c This in turn means that a date given as being on the Julian calendarc prior to about 10AD is not as definite as it may appear and its alignmentc with the astronomical day number is uncertain even though the calculationc is quite definite.cC   Computationally, year 1 is preceded by year 0, in a smooth progression.C But there was never a year zero despite what astronomers like to say,C so the formula's year 0 corresponds to 1BC, year -1 to 2BC, and so on back.C Thus y-4713 in this counting would be 4714BC on the Gregorian calendar,C were it to have existed then which it didn't.C   To conform to the civil usage, the incoming YY, presumed a proper BC (negative)C and AD (positive) year is converted into the computational counting sequence, Y,C and used in the formula. If a YY = 0 is (improperly) offered, it will manifestC as 1AD. Thus YY = -4714 will lead to calculations with Y = -4713.C Thus, 1BC is a leap year on the proleptic Gregorian calendar.C   For their convenience, astronomers decreed that a day starts at noon, so thatC in Europe, observations through the night all have the same day number.C The current Western civil calendar however has the day starting just after midnightC and that day's number lasts until the following midnight.CC   There is no constraint on the values of D, which is just added as it stands.C This means that if D = 0, the daynumber will be that of the last day of theC previous month. Likewise, M = 0 or M = 13 will wrap around so that Y,M + 1,0C will give the last day of month M (whatever its length) as one day beforeC the first day of the next month.CC   Example: Y = 1970, M = 1, D = 1;  JDAYN = 2440588, a Thursday but MOD(2440588,7) = 3.C   and with the adjustment JDAYSHIFT, DAYNUM = 25568; mod 7 = 4 and DAYNAME(4) = "Thursday".C   The Julian Day number 2440588.0 is for NOON that Thursday, 2440588.5 is twelve hours later.C   And Julian Day number 2440587.625 is for three a.m. Thursday.CC   DAYNUM and MUNYAD are the infamous routines of H. F. Fliegel and T.C. van Flandern,C   presented in Communications of the ACM, Vol. 11, No. 10 (October, 1968).Carefully typed in again by R.N.McLean (whom God preserve) December XXMMIIX.C   Though I remain puzzled as to why they used I,J,K for Y,M,D,C given that the variables were named in the INTEGER statement anyway.        INTEGER*4 JDAYN		!Without rebasing, this won't fit in INTEGER*2.        INTEGER YY,Y,M,MM,D	!NB! Full year number, so 1970, not 70.Caution: integer division in Fortran does not produce fractional results.C The fractional part is discarded so that 4/3 gives 1 and -4/3 gives -1.C Thus 4/3 might be Trunc(4/3) or 4 div 3 in other languages. Beware of negative numbers!         Y = YY		!I can fiddle this copy without damaging the original's value.         IF (Y.LT.1) Y = Y + 1	!Thus YY = -2=2BC, -1=1BC, +1=1AD, ... becomes Y = -1, 0, 1, ...         MM = (M - 14)/12	!Calculate once. Note that this is integer division, truncating.         JDAYN = D - 32075	!This is the proper astronomer's Julian Day Number.     a    + 1461*(Y + 4800  + MM)/4     b    +  367*(M - 2     - MM*12)/12     c    -    3*((Y + 4900 + MM)/100)/4         DAYNUM = JDAYN - JDAYSHIFT	!Thus, *NOT* the actual *Julian* Day Number.       END FUNCTION DAYNUM		!But one such that Mod(n,7) gives day names. Could compute the day of the year somewhat as follows...c  DN:=D + (61*Month + (Month div 8)) div 2 - 30c        + if Month > 2 then FebLength - 30 else 0;        TYPE(DATEBAG) FUNCTION MUNYAD(DAYNUM)	!Oh for palindromic programming!Conversion from a Julian day number to a Gregorian calendar date. See JDAYN/DAYNUM.        INTEGER*4 DAYNUM,JDAYN	!Without rebasing, this won't fit in INTEGER*2.        INTEGER Y,M,D,L,N		!Y will be a full year number: 1950 not 50.         JDAYN = DAYNUM + JDAYSHIFT	!Revert to a proper Julian day number.         L = JDAYN + 68569	!Further machinations of H. F. Fliegel and T.C. van Flandern.         N = 4*L/146097         L = L - (146097*N + 3)/4         Y = 4000*(L + 1)/1461001         L = L - 1461*Y/4 + 31         M = 80*L/2447         D = L - 2447*M/80         L = M/11         M = M + 2 - 12*L         Y = 100*(N - 49) + Y + L         IF (Y.LT.1) Y = Y - 1	!The other side of conformity to BC/AD, as in DAYNUM.         MUNYAD%YEAR  = Y	!Now place for the world to see.         MUNYAD%MONTH = M         MUNYAD%DAY   = D       END FUNCTION MUNYAD	!A year has 365.2421988 days...        CHARACTER*10 FUNCTION SLASHDATE(DAYNUM)	!This is relatively innocent.Caution! The Gregorian calendar did not exist prior to 15/10/1582!Confine expected operation to four-digit years, since fixed-field sizes are in mind.Can use this function in WRITE statements with FORMAT, since this function does not use them.Compilers of lesser merit can concoct code that bungles such double usage otherwise.        INTEGER*4 DAYNUM	!-32768 to 32767 is just not adequate.        TYPE(DATEBAG) D		!Though these numbers are more restrained.        INTEGER N,L		!Workers.         IF (DAYNUM.EQ.NOTADAYNUMBER) THEN	!Perhaps some work can be dodged.           SLASHDATE = " Undated!!"	!No proper day number has been placed.          RETURN		!So give up, rather than show odd results.         END IF			!So much for confusion.         D = MUNYAD(DAYNUM)	!Get the pieces.         IF (D%DAY.GT.9) THEN	!Here we go.           SLASHDATE(1:1) = CHAR(D%DAY/10 + ICHAR("0"))	!Faster than a table look-up?          ELSE			!Even if not,           SLASHDATE(1:1) = " "	!This should be quick.         END IF			!So much for the tens digit.         SLASHDATE(2:2) = CHAR(MOD(D%DAY,10) + ICHAR("0"))	!The units digit.         SLASHDATE(3:3) = "/"	!Enough of the day number. The separator.         IF (D%MONTH.GT.9) THEN	!Now for the month.           SLASHDATE(4:4) = CHAR(D%MONTH/10 + ICHAR("0"))	!The tens digit.          ELSE			!Not so often used. A table beckons...           SLASHDATE(4:4) = " "	!Some might desire leading zeroes here.         END IF			!Enough of October, November and December.         SLASHDATE(5:5) = CHAR(MOD(D%MONTH,10) + ICHAR("0"))	!The units digit.         SLASHDATE(6:6) = "/"	!Enough of the month number. The separator.         L = 10			!The year value deserves a loop, it having four digits.         N = ABS(D%YEAR)	!Should never be zero. 1BC is year -1 and 1AD is year = +1.    1    SLASHDATE(L:L) = CHAR(MOD(N,10) + ICHAR("0"))	!But if it is, this will place a zero.         N = N/10		!Drop a power of ten.         L = L - 1		!Step back for the next digit.         IF (L.GT.6) GO TO 1	!Thus always four digits, even if they lead with zero.         IF (N.GT.0) SLASHDATE(7:7) = "?"	!Y > 9999? Might as well do something.         IF (D%YEAR.LT.0) SLASHDATE(7:7) = "-"	!Years BC? Rather than give no indication.c         WRITE (SLASHDATE,1) D%DAY,D%MONTH,D%YEAR	!Some compilers will bungle this.c    1    FORMAT (I2,"/",I2,"/",I4)			!If so, a local variable must be used.        RETURN			!Enough.		!As when SLASHDATE is invoked in a WRITE statement.       END FUNCTION SLASHDATE	!Simple enough.      END MODULE DATEGNASH       PROGRAM LASTSUNDAY      USE DATEGNASH      INTEGER D,W,M,Y      WRITE (6,1)    1 FORMAT ("Employs the Gregorian calendar pattern.",/,     1 "You specify a day of the week, then nominate a year.",/,     2 "For each month of that year, this calculates the date ",     3 "of the last such day.",//     4 "So, what day (0 = Sunday, 6 = Saturday):",\$)      READ (5,*) W      IF (W.LT.0 .OR. W.GT.6) STOP "Not a good week day number!"    10 WRITE (6,11)   11 FORMAT ("What year (non-positive to quit):",\$)      READ (5,*) Y      IF (Y.LE.0) STOP      DO M = 1,12        D = DAYNUM(Y,M + 1,0)	!Zeroth day = last day of previous month.        D = D - MOD(MOD(D - W,7) + 7,7)	!Protect against MOD(D,7) giving negative values for D < 0.        WRITE (6,*) SLASHDATE(D)," : ",DAYNAME(MOD(D,7))      END DO      GO TO 10      END `

And after all that, results:

```Employs the Gregorian calendar pattern.
You specify a day of the week, then nominate a year.
For each month of that year, this calculates the date of the last such day.

So, what day (0 = Sunday, 6 = Saturday):0
What year (non-positive to quit):2013
27/ 1/2013 : Sunday
24/ 2/2013 : Sunday
31/ 3/2013 : Sunday
28/ 4/2013 : Sunday
26/ 5/2013 : Sunday
30/ 6/2013 : Sunday
28/ 7/2013 : Sunday
25/ 8/2013 : Sunday
29/ 9/2013 : Sunday
27/10/2013 : Sunday
24/11/2013 : Sunday
29/12/2013 : Sunday
What year (non-positive to quit):0
```

## Free Pascal

` program sundays; Uses sysutils; type  MonthLength = Array[1..13] of Integer; procedure sund(y : Integer);var  dt : TDateTime;  m,mm : Integer;  len : MonthLength;begin   len[1] := 31; len[2] := 28; len[3] := 31; len[4] := 30;   len[5] := 31; len[6] := 30; len[7] := 31; len[8] := 31;   len[9] := 30; len[10] := 31; len[11] := 30; len[12] := 31; len[13] := 29;   for m := 1 to 12 do   begin      mm := m;      if (m = 2) and IsLeapYear( y ) then         mm := 13;      dt := EncodeDate( y, mm, len[mm] );      dt := EncodeDate( y, mm, len[mm] - DayOfWeek(dt) + 1 );      WriteLn(FormatDateTime('YYYY-MM-DD', dt ));   end;end; var  i : integer;  yy: integer;begin   for i := 1 to paramCount() do begin      Val( paramStr(1), yy );      sund( yy );   end;end. `
Output:
```./sundays 2025
2025-01-26
2025-02-23
2025-03-30
2025-04-27
2025-05-25
2025-06-29
2025-07-27
2025-08-31
2025-09-28
2025-10-26
2025-11-30
2025-12-28
```

## FreeBASIC

`' version 23-06-2015' compile with: fbc -s console #Ifndef TRUE        ' define true and false for older freebasic versions    #Define FALSE 0    #Define TRUE Not FALSE#EndIf Function leapyear(Year_ As Integer) As Integer    ' from the leapyear entry    If (Year_ Mod 4) <> 0 Then Return FALSE    If (Year_ Mod 100) = 0 AndAlso (Year_ Mod 400) <> 0 Then Return FALSE    Return TRUE End Function Function wd(m As Integer, d As Integer, y As Integer) As Integer    ' Zellerish    ' 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday    ' 4 = Thursday, 5 = Friday, 6 = Saturday     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 7End Function ' ------=< MAIN >=------ Type month_days    m_name As String    days As UByteEnd Type Dim As month_days arr(1 To 12)Data "January",   31, "February", 28, "March",    31, "April",    30Data "May",       31, "June",     30, "July",     31, "August",   31Data "September", 30, "October",  31, "November", 30, "December", 31 Dim As Integer yr, d, i, xDim As String keypress For i = 1 To 12    With arr(i)        Read .m_name        Read .days    End WithNext Do     Do        Print "For what year do you want to find the last Sunday of the month"        Input "any number below 1800 stops program, year in YYYY format";yr        ' empty input also stops        If yr < 1800 Then            End        Else            Exit Do        End If    Loop     Print : Print    Print "Last Sunday of the month for"; yr     For i = 1 To 12        d = arr(i).days        If i = 2 AndAlso leapyear(yr) = TRUE Then d = d + 1        x = wd(i, d, yr)        d = d - x   ' don't test it just do it        Print d; " "; arr(i).m_name    Next     ' empty key buffer    While Inkey <> "" : keypress = Inkey : Wend    Print : Print    Print "Find last Sunday for a other year [Y|y], anything else stops"    keypress =""    While keypress = "" : keypress = Inkey : Wend    If LCase(keypress) <> "y" Then Exit Do    Print : Print LoopEnd`
Output:
```For what year do you want to find the last Sunday of the month
any number below 1800 stops program, year in YYYY format? 2017

Last Sunday of the month for 2017
29 January
26 February
26 March
30 April
28 May
25 June
30 July
27 August
24 September
29 October
26 November
31 December```

## Frink

`d = parseDate[[email protected]]for m = 1 to 12{   d = beginningOfNextMonth[d]   n = d - parseInt[d -> ### u ###] days   println[n->###yyyy-MM-dd###]}`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

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

## Gambas

`Public Sub Form_Open()Dim sYear As String                                                             'To store the year chosenDim siDay, siMonth, siWeekday As Short                                          'Day, Month and Weekday sYear = InputBox("Input year", "Last Sunday of each month")                     'Get the user to enter a yearPrint "Last Sundays in " & sYear                                                'Print a heading For siMonth = 1 To 12                                                           'Loop for each month  For siDay = 31 DownTo 23                                                      'Count backwards from 31 to 23 (Sunday 23rd February 1930)     siWeekday = 7                                                               'Set the Weekday to Saturday in case of error in the next line    Try siWeekday = WeekDay(Date(Val(sYear), siMonth, siDay))                   'TRY and get the Weekday. If there is an error it will be ignored e.g. 31 February    If siWeekday = 0 Then                                                       'If Weekday is Sunday then..      Print Format(Date(Val(sYear), siMonth, siDay), "dddd dd mmmm yyyy")       'Print the date      Break                                                                     'Jump out of this loop    End If  NextNext End`

Output:

```Last Sundays in 2013
Sunday 27 January 2013
Sunday 24 February 2013
Sunday 31 March 2013
Sunday 28 April 2013
Sunday 26 May 2013
Sunday 30 June 2013
Sunday 28 July 2013
Sunday 25 August 2013
Sunday 29 September 2013
Sunday 27 October 2013
Sunday 24 November 2013
Sunday 29 December 2013
```

## Go

This is different from the Go code for Last Friday of each month. It uses the fact that time functions in Go correct for dates: if you enter 32nd of october, Go corrects to 1st of November. So that if 29th of February is corrected to 1st of March, chosen year is not a leap year.

`package main import (	"fmt"	"time") func main() { 	var year int	var t time.Time	var lastDay = [12]int { 31,29,31,30,31,30,31,31,30,31,30,31 } 	for {		fmt.Print("Please select a year: ")		_, err := fmt.Scanf("%d", &year)		if err != nil {			fmt.Println(err)			continue		} else {			break		}	} 	fmt.Println("Last Sundays of each month of", year)	fmt.Println("==================================") 	for i := 1;i < 13; i++ {		j := lastDay[i-1]		if i == 2 {			if time.Date(int(year), time.Month(i), j, 0, 0, 0, 0, time.UTC).Month() == time.Date(int(year), time.Month(i), j-1, 0, 0, 0, 0, time.UTC).Month() {				j = 29			} else {				j = 28			}		}		for {			t = time.Date(int(year), time.Month(i), j, 0, 0, 0, 0, time.UTC)			if t.Weekday() == 0 {				fmt.Printf("%s: %d\n", time.Month(i), j)				break			}			j = j - 1		}	}} `
```Please select a year: 2013
Last Sundays of each month of 2013
==================================
January: 27
February: 24
March: 31
April: 28
May: 26
June: 30
July: 28
August: 25
September: 29
October: 27
November: 24
December: 29
```

## Groovy

Solution:

`enum Day {    Sun, Mon, Tue, Wed, Thu, Fri, Sat    static Day valueOf(Date d) { Day.valueOf(d.format('EEE')) }} def date = Date.&parse.curry('yyyy-MM-dd')def month = { it.format('MM') }def days = { year -> (date("\${year}-01-01")..<date("\${year+1}-01-01")) }def weekDays = { dayOfWeek, year -> days(year).findAll { Day.valueOf(it) == dayOfWeek } } def lastWeekDays = { dayOfWeek, year ->    weekDays(dayOfWeek, year).reverse().inject([:]) { months, sunday ->        def monthStr = month(sunday)        !months[monthStr]  ?  months + [(monthStr):sunday]  :  months    }.values().sort()}`

Test:

`def ymd = { it.format('yyyy-MM-dd') }def lastSundays = lastWeekDays.curry(Day.Sun)lastSundays(args[0] as int).each { println (ymd(it)) }`

Execution (Cygwin on Windows 7):

`[2201] groovy lastSundays.groovy 2013`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

`import Data.List (find, intercalate, transpose)import Data.Maybe (fromJust)import Data.Time.Calendar  ( Day,    addDays,    fromGregorian,    gregorianMonthLength,    showGregorian,  )import Data.Time.Calendar.WeekDate (toWeekDate) ---------------- LAST SUNDAY OF EACH MONTH --------------- lastSundayOfEachMonth = lastWeekDayDates 7 --------------------------- TEST -------------------------main :: IO ()main =  mapM_    putStrLn    ( intercalate "  "        <\$> transpose          (lastSundayOfEachMonth <\$> [2013 .. 2017])    ) ------------------- NEAREST DAY OF WEEK ------------------ lastWeekDayDates :: Int -> Integer -> [String]lastWeekDayDates dayOfWeek year =  (showGregorian . mostRecentWeekday dayOfWeek)    . (fromGregorian year <*> gregorianMonthLength year)    <\$> [1 .. 12] mostRecentWeekday :: Int -> Day -> DaymostRecentWeekday dayOfWeek date =  fromJust    (find p ((`addDays` date) <\$> [-6 .. 0]))  where    p x =      let (_, _, day) = toWeekDate x       in dayOfWeek == day`
Output:
```2018-01-28  2019-01-27  2020-01-26  2021-01-31  2022-01-30  2023-01-29
2018-02-25  2019-02-24  2020-02-23  2021-02-28  2022-02-27  2023-02-26
2018-03-25  2019-03-31  2020-03-29  2021-03-28  2022-03-27  2023-03-26
2018-04-29  2019-04-28  2020-04-26  2021-04-25  2022-04-24  2023-04-30
2018-05-27  2019-05-26  2020-05-31  2021-05-30  2022-05-29  2023-05-28
2018-06-24  2019-06-30  2020-06-28  2021-06-27  2022-06-26  2023-06-25
2018-07-29  2019-07-28  2020-07-26  2021-07-25  2022-07-31  2023-07-30
2018-08-26  2019-08-25  2020-08-30  2021-08-29  2022-08-28  2023-08-27
2018-09-30  2019-09-29  2020-09-27  2021-09-26  2022-09-25  2023-09-24
2018-10-28  2019-10-27  2020-10-25  2021-10-31  2022-10-30  2023-10-29
2018-11-25  2019-11-24  2020-11-29  2021-11-28  2022-11-27  2023-11-26
2018-12-30  2019-12-29  2020-12-27  2021-12-26  2022-12-25  2023-12-31```

## Icon and Unicon

This is a trivial adaptation of the solution to the "Last Friday of each month" task and works in both languages:

`procedure main(A)every write(lastsundays(!A))end procedure lastsundays(year)every m := 1 to 12 do {   d := case m of {      2        : if IsLeapYear(year) then 29 else 28      4|6|9|11 : 30      default  : 31      }                          # last day of month    z := 0     j := julian(m,d,year) + 1     # first day of next month   until (j-:=1)%7 = 6 do z -:=1 # backup to last sunday (6)   suspend sprintf("%d-%d-%d",year,m,d+z)   }end link datetime, printf`

Sample run:

```->lsem 2013 2014
2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29
2014-1-26
2014-2-23
2014-3-30
2014-4-27
2014-5-25
2014-6-29
2014-7-27
2014-8-31
2014-9-28
2014-10-26
2014-11-30
2014-12-28
->
```

## J

Same solution as for Last_Friday_of_each_month#J

`require'dates'last_sundays=: 12 {. [: ({:/.~ }:"1)@(#~ 0 = weekday)@todate (i.366) + [email protected],&1 1`

Example use:

`   last_sundays 20132013  1 272013  2 242013  3 312013  4 282013  5 262013  6 302013  7 282013  8 252013  9 292013 10 272013 11 242013 12 29`

## Java

`import java.util.Scanner; public class LastSunday {	static final String[] months={"January","February","March","April","May","June","July","August","September","October","November","December"}; 	public static int[] findLastSunday(int year)	{		boolean isLeap = isLeapYear(year); 		int[] days={31,isLeap?29:28,31,30,31,30,31,31,30,31,30,31};		int[] lastDay=new int[12]; 		for(int m=0;i<12;i++)		{			int d;			for(d=days[m]; getWeekDay(year,m,d)!=0; d--)				;			lastDay[m]=d;		} 		return lastDay;	} 	private static boolean isLeapYear(int year)	{		if(year%4==0)		{			if(year%100!=0)				return true;			else if (year%400==0)				return true;		}		return false;	} 	private static int getWeekDay(int y, int m, int d)	{		int f=y+d+3*m-1;		m++; 		if(m<3)			y--;		else			f-=(int)(0.4*m+2.3); 		f+=(int)(y/4)-(int)((y/100+1)*0.75);		f%=7; 		return f;	} 	private static void display(int year, int[] lastDay)	{		System.out.println("\nYEAR: "+year);		for(int m=0;i<12;i++)			System.out.println(months[m]+": "+lastDay[m]);	} 	public static void main(String[] args) throws Exception	{		System.out.print("Enter year: ");		Scanner s=new Scanner(System.in); 		int y=Integer.parseInt(s.next()); 		int[] lastDay = findLastSunday(y);		display(y, lastDay); 		s.close();	}}`
Output:
```Enter year: 2013

YEAR: 2013
January: 27
February: 24
March: 31
April: 28
May: 26
June: 30
July: 28
August: 25
September: 29
October: 27
November: 24
December: 29
```

### Java 8

`import java.time.*;import java.util.stream.*;import static java.time.temporal.TemporalAdjusters.*; public class FindTheLastSundayOfEachMonth {    public static Stream<LocalDate> lastSundaysOf(int year) {        return IntStream.rangeClosed(1, 12).mapToObj(month ->            LocalDate.of(year, month, 1).with(lastDayOfMonth())            .with(previousOrSame(DayOfWeek.SUNDAY))        );    }     public static java.util.List<LocalDate> listLastSundaysOf(int year) {        return lastSundaysOf(year).collect(Collectors.toList());    }     public static void main(String[] args) throws Exception {        int year = args.length > 0 ? Integer.parseInt(args[0]) : LocalDate.now().getYear();         for (LocalDate d : listLastSundaysOf(year)) {            System.out.println(d);        };         String result = lastSundaysOf(2013).map(LocalDate::toString).collect(Collectors.joining("\n"));        String test = "2013-01-27\n2013-02-24\n2013-03-31\n2013-04-28\n2013-05-26\n2013-06-30\n2013-07-28\n2013-08-25\n2013-09-29\n2013-10-27\n2013-11-24\n2013-12-29";        if (!test.equals(result)) throw new AssertionError("test failure");    } }`

## JavaScript

### ES5

#### Iteration

`function lastSundayOfEachMonths(year) {	var lastDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];	var sundays = [];	var date, month;	if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {		lastDay[2] = 29;	}	for (date = new Date(), month = 0; month < 12; month += 1) {		date.setFullYear(year, month, lastDay[month]);		date.setDate(date.getDate() - date.getDay());		sundays.push(date.toISOString().substring(0, 10));	}	return sundays;} console.log(lastSundayOfEachMonths(2013).join('\n'));`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

#### Functional composition

`(function () {    'use strict';     // lastSundaysOfYear :: Int -> [Date]    function lastSundaysOfYear(y) {        return lastWeekDaysOfYear(y, days.sunday);    }     // lastWeekDaysOfYear :: Int -> Int -> [Date]    function lastWeekDaysOfYear(y, iWeekDay) {        return [                31,                0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,                31, 30, 31, 30, 31, 31, 30, 31, 30, 31            ]            .map(function (d, m) {                var dte = new Date(Date.UTC(y, m, d));                 return new Date(Date.UTC(                    y, m, d - (                        (dte.getDay() + (7 - iWeekDay)) % 7                    )                ));            });    }     // isoDateString :: Date -> String    function isoDateString(dte) {        return dte.toISOString()            .substr(0, 10);    }     // range :: Int -> Int -> [Int]    function range(m, n) {        return Array.apply(null, Array(n - m + 1))            .map(function (x, i) {                return m + i;            });    }     // transpose :: [[a]] -> [[a]]    function transpose(lst) {        return lst[0].map(function (_, iCol) {            return lst.map(function (row) {                return row[iCol];            });        });    }     var days = {        sunday: 0,        monday: 1,        tuesday: 2,        wednesday: 3,        thursday: 4,        friday: 5,        saturday: 6    }     // TEST     return transpose(            range(2012, 2016)            .map(lastSundaysOfYear)        )        .map(function (row) {            return row                .map(isoDateString)                .join('\t');        })        .join('\n'); })();`
Output:
```2013-01-27	2014-01-26	2015-01-25	2016-01-31	2017-01-29
2013-02-24	2014-02-23	2015-02-22	2016-02-28	2017-02-26
2013-03-31	2014-03-30	2015-03-29	2016-03-27	2017-03-26
2013-04-28	2014-04-27	2015-04-26	2016-04-24	2017-04-30
2013-05-26	2014-05-25	2015-05-31	2016-05-29	2017-05-28
2013-06-30	2014-06-29	2015-06-28	2016-06-26	2017-06-25
2013-07-28	2014-07-27	2015-07-26	2016-07-31	2017-07-30
2013-08-25	2014-08-31	2015-08-30	2016-08-28	2017-08-27
2013-09-29	2014-09-28	2015-09-27	2016-09-25	2017-09-24
2013-10-27	2014-10-26	2015-10-25	2016-10-30	2017-10-29
2013-11-24	2014-11-30	2015-11-29	2016-11-27	2017-11-26
2013-12-29	2014-12-28	2015-12-27	2016-12-25	2017-12-31```

### ES6

`(() => {    'use strict'     // MAIN -----------------------------------------------    // main :: IO ()    const main = () =>        console.log(unlines(            map(                compose(                    intercalate('\t'),                    map(isoDateString)                )            )(                transpose(                    map(lastWeekDaysOfYear(days.sunday))(                        enumFromTo(2019)(2022)                    )                )            )        ));     // WEEKDAYS -------------------------------------------     // lastWeekDaysOfYear :: Int -> Int -> [Date]    const lastWeekDaysOfYear = iWeekDay =>        y => map((d, m) =>            new Date(Date.UTC(                y, m, d - ((new Date(Date.UTC(y, m, d))                    .getDay() + (7 - iWeekDay)) % 7))))([            31,            0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,            31, 30, 31, 30, 31, 31, 30, 31, 30, 31        ]);     const days = {        sunday: 0,        monday: 1,        tuesday: 2,        wednesday: 3,        thursday: 4,        friday: 5,        saturday: 6    };     // GENERIC FUNCTIONS-----------------------------------     // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c    const compose = (...fs) =>        x => fs.reduceRight((a, f) => f(a), x);     // enumFromTo :: Int -> Int -> [Int]    const enumFromTo = m => n =>        Array.from({            length: 1 + n - m        }, (_, i) => m + i);     // intercalate :: String -> [String] -> String    const intercalate = s => xs =>        xs.join(s);     // isoDateString :: Date -> String    const isoDateString = dte =>        dte.toISOString()        .substr(0, 10);     // map :: (a -> b) -> [a] -> [b]    const map = f => xs =>        (Array.isArray(xs) ? (            xs        ) : xs.split('')).map(f);     // If some of the rows are shorter than the following rows,     // their elements are skipped:    // > transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]     // transpose :: [[a]] -> [[a]]    const transpose = xss => {        const go = xss =>            0 < xss.length ? (() => {                const                    h = xss[0],                    t = xss.slice(1);                return 0 < h.length ? (                    [                        [h[0]].concat(t.reduce(                            (a, xs) => a.concat(                                0 < xs.length ? (                                    [xs[0]]                                ) : []                            ),                            []                        ))                    ].concat(go([h.slice(1)].concat(                        t.map(xs => xs.slice(1))                    )))                ) : go(t);            })() : [];        return go(xss);    };     // unlines :: [String] -> String    const unlines = xs => xs.join('\n');     // MAIN ---    return main();})();`
Output:
```2019-01-27    2020-01-26    2021-01-31    2022-01-30
2019-02-24    2020-02-23    2021-02-28    2022-02-27
2019-03-31    2020-03-29    2021-03-28    2022-03-27
2019-04-28    2020-04-26    2021-04-25    2022-04-24
2019-05-26    2020-05-31    2021-05-30    2022-05-29
2019-06-30    2020-06-28    2021-06-27    2022-06-26
2019-07-28    2020-07-26    2021-07-25    2022-07-31
2019-08-25    2020-08-30    2021-08-29    2022-08-28
2019-09-29    2020-09-27    2021-09-26    2022-09-25
2019-10-27    2020-10-25    2021-10-31    2022-10-30
2019-11-24    2020-11-29    2021-11-28    2022-11-27
2019-12-29    2020-12-27    2021-12-26    2022-12-25```

## jq

Works with: jq version 1.4

Foundations

`# In case your jq does not have "until" defined:def until(cond; next):  def _until:    if cond then . else (next|_until) end;  _until; # Zeller's Congruence from [[Day_of_the_week#jq]] # Use Zeller's Congruence to determine the day of the week, given# year, month and day as integers in the conventional way.# If iso == "iso" or "ISO", then emit an integer in 1 -- 7 where # 1 represents Monday, 2 Tuesday, etc;# otherwise emit 0 for Saturday, 1 for Sunday, etc.#def day_of_week(year; month; day; iso):  if month == 1 or month == 2 then    [year - 1, month + 12, day]  else    [year, month, day]  end  | .[2] + (13*(.[1] + 1)/5|floor)     +  (.[0]%100)       + ((.[0]%100)/4|floor)    +  (.[0]/400|floor) - 2*(.[0]/100|floor)  | if iso == "iso" or iso == "ISO" then 1 + ((. + 5) % 7)    else . % 7    end ;`

findLastSundays

`# year and month are numbered conventionally def findLastSunday(year; month):  def isLeapYear:    year%4 == 0 and ( year%100!=0 or year%400==0 ) ;  def days:    if month == 2 then (if isLeapYear then 29 else 28 end)    else [31, 28, 31,30,31,30,31,31,30,31,30,31][month-1]    end;  year as \$year  | month as \$month  | days  | until( day_of_week(\$year; \$month; .; null) == 1 ; .-1); # input: yeardef findLastSundays:  def months:    ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];  . as \$year  | "YEAR: \(.)",    (range(0;12) | "\(months[.]) \(findLastSunday(\$year; .+1))") ;  \$year|tonumber|findLastSundays `

Example:

`\$ jq --arg year 2013 -n -r -f findLastSundays.jqYEAR: 2013January 27February 24March 31April 28May 26June 30July 28August 25September 29October 27November 24December 29`

## Julia

` isdefined(:Date) || using Dates const wday = Dates.Sunconst lo = 1const hi = 12 print("\nThis script will print the last ", Dates.dayname(wday))println("s of each month of the year given.")println("(Leave input empty to quit.)") while true    print("\nYear> ")    y = chomp(readline())    0 < length(y) || break    y = try        parseint(y)    catch        println("Sorry, but that does not compute as a year.")        continue    end    println()    for m in Date(y, lo):Month(1):Date(y, hi)        println("    ", tolast(m, wday))    endend `

This code uses the `Dates` module, which is being incorporated into Julian's standard library with the current development version (0.4). I've used `isdefined` to make this code good for the current stable version (0.3) as well as for future releases. If `Dates` is not installed on your instance of Julian try `Pkg.add("Dates")` from the REPL.

Output:
```This script will print the last Sundays of each month of the year given.
(Leave input empty to quit.)

Year> 2013

2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29

Year> this year
Sorry, but that does not compute as a year.

Year>
```

## K

` / List the dates of last Sundays of each month of/ a given year/ lastsundt.k isleap: {(+/~x!' 4 100 400)!2}wd: {(_jd x)!7}dom: (31;28;31;30;31;30;31;31;30;31;30;31)init: {:[isleap x;dom[1]::29;dom[1]::28]}wdme: {[m;y]; init y; dt:(10000*y)+(100*m)+dom[m-1];jd::(_jd dt);mewd::(wd dt)}lsd: {[m;y]; wdme[m;y];:[mewd>5;jd::jd+(6-mewd);jd::jd-(1+mewd)];dt:_dj(jd);yy:\$(yr:dt%10000);dd:\$(d:dt!100);mm:\$(mo:((dt-yr*10000)%100));arr::arr,\$(yy,"-",(2\$mm),"-",(2\$dd))}lsd1: {[y];arr::(); m:1; do[12;lsd[m;y];m+:1]}main: {[y]; lsd1[y];`0: ,"Dates of last Sundays of ",(\$y); 12 10#arr}  `

The output of a session with the above script is given below:

Output:
```K Console - Enter \ for help

\l lastsundt
main 2013
Dates of last Sundays of 2013
("2013- 1-27"
"2013- 2-24"
"2013- 3-31"
"2013- 4-28"
"2013- 5-26"
"2013- 6-30"
"2013- 7-28"
"2013- 8-25"
"2013- 9-29"
"2013-10-27"
"2013-11-24"
"2013-12-29")

```

## Kotlin

`// version 1.0.6 import java.util.* fun main(args: Array<String>) {    print("Enter a year : ")    val year = readLine()!!.toInt()     println("The last Sundays of each month in \$year are as follows:")    val calendar = GregorianCalendar(year, 0, 31)    for (month in 1..12) {        val daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)        val lastSunday = daysInMonth - (calendar[Calendar.DAY_OF_WEEK] - Calendar.SUNDAY)        println("\$year-" + "%02d-".format(month) + "%02d".format(lastSunday))        if (month < 12) {            calendar.add(Calendar.DAY_OF_MONTH, 1)            calendar.add(Calendar.MONTH, 1)            calendar.add(Calendar.DAY_OF_MONTH, -1)        }    }}`

Sample input/output:

Output:
```Enter a year : 2013
The last Sundays of each month in 2013 are as follows:
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Lasso

`local(	year	= integer(web_request -> param('year') || 2013),	date	= date(#year + '-1-1'),	lastsu	= array,	lastday) with month in generateseries(1,12) do {	#date -> day = 1	#date -> month = #month	#lastday = #date -> month(-days)	#date -> day = #lastday	loop(7)	=> {		if(#date -> dayofweek == 1) => {			#lastsu -> insert(#date -> format(`dd MMMM`))			loop_abort		}		#date -> day--	}}#lastsu -> join('<br />')`
```27 January
24 February
31 March
28 April
26 May
30 June
28 July
25 August
29 September
27 October
24 November
29 December```

## Liberty BASIC

This program goes a step further and provides a function definition, NthDayOfMonth(), that returns the date of any occurrence of a day in any given month and year. For example: The third Monday in February, the last Monday in May, the fourth Thursday in November, etc.

` yyyy=2013: if yyyy<1901 or yyyy>2099 then endnda\$="Lsu"print "The last Sundays of "; yyyyfor mm=1 to 12    x=NthDayOfMonth(yyyy, mm, nda\$)    select case mm        case  1: print "   January ";   x        case  2: print "   February ";  x        case  3: print "   March ";     x        case  4: print "   April ";     x        case  5: print "   May ";       x        case  6: print "   June ";      x        case  7: print "   July ";      x        case  8: print "   August ";    x        case  9: print "   September "; x        case 10: print "   October ";   x        case 11: print "   November ";  x        case 12: print "   December ";  x    end selectnext mmend function NthDayOfMonth(yyyy, mm, nda\$)' nda\$ is a two-part code. The first character, n, denotes' first, second, third, fourth, and last by 1, 2, 3, 4, or L.' The last two characters, da, denote the day of the week by' mo, tu, we, th, fr, sa, or su. For example: ' the nda\$ for the second Monday of a month is "2mo";' the nda\$ for the last Thursday of a month is "Lth".    if yyyy<1900 or yyyy>2099 or mm<1 or mm>12 then        NthDayOfMonth=0: exit function    end if    nda\$=lower\$(trim\$(nda\$))    if len(nda\$)<>3 then NthDayOfMonth=0: exit function    n\$=left\$(nda\$,1): nC\$="1234l"    da\$=right\$(nda\$,2): daC\$="tuwethfrsasumotuwethfrsasumo"    if not(instr(nC\$,n\$)) or not(instr(daC\$,da\$)) then        NthDayOfMonth=0: exit function    end if    NthDayOfMonth=1    mm\$=str\$(mm): if mm<10 then mm\$="0"+mm\$     db\$=DayOfDate\$(str\$(yyyy)+mm\$+"01")    if da\$<>db\$ then        x=instr(daC\$,db\$): y=instr(daC\$,da\$,x): NthDayOfMonth=1+(y-x)/2    end if    dim MD(12)    MD(1)=31: MD(2)=28: MD(3)=31: MD(4)=30: MD(5)=31: MD(6)=30     MD(7)=31: MD(8)=31: MD(9)=30: MD(10)=31: MD(11)=30: MD(12)=31     if yyyy mod 4 = 0 then MD(2)=29    if n\$<>"1" then        if n\$<>"l" then            NthDayOfMonth=NthDayOfMonth+((val(n\$)-1)*7)        else            if NthDayOfMonth+27<MD(mm) then                NthDayOfMonth=NthDayOfMonth+28            else                NthDayOfMonth=NthDayOfMonth+21            end if        end if    end ifend function function DayOfDate\$(ObjectDate\$) 'yyyymmdd format    if ObjectDate\$="" then 'today        DaysSince1900 = date\$("days")    else        DaysSince1900 = date\$(mid\$(ObjectDate\$,5,2)+"/"+right\$(ObjectDate\$,2)_                +"/"+left\$(ObjectDate\$,4))    end if    DayOfWeek = DaysSince1900 mod 7    select case DayOfWeek        case 0: DayOfDate\$="tu"        case 1: DayOfDate\$="we"        case 2: DayOfDate\$="th"        case 3: DayOfDate\$="fr"        case 4: DayOfDate\$="sa"        case 5: DayOfDate\$="su"        case 6: DayOfDate\$="mo"    end selectend function `
Output:
```The last Sundays of 2013
January 27
February 24
March 31
April 28
May 26
June 30
July 28
August 25
September 29
October 27
November 24
December 29
```

## LiveCode

Abstracted version of "last friday of each month". LiveCode dateItem item 7 is day of week. It is numbered 1 (Sunday) to 7 (Saturday).

`function lastDay yyyy, dayofweek    -- year,month num,day of month,hour in 24-hour time,minute,second,numeric day of week.    convert the long date to dateitems    put 1 into item 2 of it    put 1 into item 3 of it    put yyyy into item 1 of it    put it into startDate    convert startDate to dateItems    repeat with m = 1 to 12        put m into item 2 of startDate        repeat with d = 20 to 31            put d into item 3 of startDate            convert startDate to dateItems            -- 1 is Sunday through to 7 Saturday            if item 7 of startDate is dayofweek and item 1 of startDate is yyyy and item 2 of startDate is m then                put item 3 of startDate into mydays[item 2 of startDate]            end if        end repeat    end repeat    combine mydays using cr and space    sort mydays ascending numeric    return mydaysend lastDay`
Example
`put lastDay(2013, 1)`
Output
```1 27
2 24
3 31
4 28
5 26
6 30
7 28
8 25
9 29
10 27
11 24

12 29```

## Lua

`function isLeapYear (y)    return (y % 4 == 0 and y % 100 ~=0) or y % 400 == 0end function dayOfWeek (y, m, d)    local t = os.time({year = y, month = m, day = d})    return os.date("%A", t)end function lastWeekdays (wday, year)    local monthLength, day = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}    if isLeapYear(year) then monthLength[2] = 29 end    for month = 1, 12 do        day = monthLength[month]        while dayOfWeek(year, month, day) ~= wday do day = day - 1 end        print(year .. "-" .. month .. "-" .. day)    endend lastWeekdays("Sunday", tonumber(arg[1]))`

Command line session:

```>lua lastSundays.lua 2013
2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29

>```

## Maple

`sundays := proc(year)	local i, dt, change, last_days;	last_days := [31,28,31,30,31,30,31,31,30,31,30,31];	if (Calendar:-IsLeapYear(year)) then		last_days[2] := 28;	end if;	for i to 12 do		dt := Date(year, i, last_days[i]);		change := 0;		if not(Calendar:-DayOfWeek(dt) = 1) then 			change := -Calendar:-DayOfWeek(dt) + 1;		end if;		dt := Calendar:-AdjustDateField(dt, "date", change);		printf("%d-%d-%d\n", year, Month(dt), DayOfMonth(dt));	end do;end proc; sundays(2013);`
Output:
```2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29
```

## Mathematica / Wolfram Language

`LastSundays[year_] :=  Table[[email protected]   DayRange[{year, i},     DatePlus[{year, i}, {{1, "Month"}, {-1, "Day"}}], Sunday], {i,    12}]LastSundays[2013]`
Output:
```{{2013, 1, 27}, {2013, 2, 24}, {2013, 3, 31}, {2013, 4, 28}, {2013, 5,
26}, {2013, 6, 30}, {2013, 7, 28}, {2013, 8, 25}, {2013, 9,
29}, {2013, 10, 27}, {2013, 11, 24}, {2013, 12, 29}}```

## Nim

`import os, strutils, times const  DaysInMonth: array[Month, int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]  DayDiffs:  array[WeekDay, int] = [1, 2, 3, 4, 5, 6, 0] let year = paramStr(1).parseInt for month in mJan..mDec:  var lastDay = DaysInMonth[month]  if month == mFeb and year.isLeapYear: lastDay = 29  var date = initDateTime(lastDay, month, year, 0, 0, 0)  date = date - days(DayDiffs[date.weekday])  echo date.format("yyyy-MM-dd")`

Sample usage:

```./lastsunday 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## OCaml

` let is_leap_year y =  (* See OCaml solution on Rosetta Code for      determing if it's a leap year *)   if (y mod 100) = 0    then (y mod 400) = 0    else (y mod 4) = 0;; let get_days y =  if is_leap_year y    then      [31;29;31;30;31;30;31;31;30;31;30;31]    else      [31;28;31;30;31;30;31;31;30;31;30;31];; let print_date = Printf.printf "%d/%d/%d\n";; let get_day_of_week y m d =  let y = if m > 2 then y else y - 1 in  let c = y / 100 in  let y = y mod 100 in  let m_shifted = float_of_int ( ((m + 9) mod 12) + 1) in  let m_factor = int_of_float (2.6 *. m_shifted -. 0.2) in  let leap_factor = 5 * (y mod 4) + 3 * (y mod 7) + 5 * (c mod 4) in  (d + m_factor + leap_factor) mod 7;;  let get_shift y m last_day =  get_day_of_week y m last_day;; let print_last_sunday y m =  let days = get_days y in  let last_day = List.nth days (m - 1) in  let last_sunday = last_day - (get_shift y m last_day) in  print_date y m last_sunday;; let print_last_sundays y =  let months = [1;2;3;4;5;6;7;8;9;10;11;12] in  List.iter (print_last_sunday y) months;; match (Array.length Sys.argv ) with   2 -> print_last_sundays( int_of_string (Sys.argv.(1))); |_ -> invalid_arg "Please enter a year"; `

Sample usage:

``` ocaml sundays.ml  2013
2013/01/27
2013/02/24
2013/03/31
2013/04/28
2013/05/26
2013/06/30
2013/07/28
2013/08/25
2013/09/29
2013/10/27
2013/11/24
2013/12/29```

## Oforth

`import: date : lastSunday(y)| m |   Date.JANUARY Date.DECEMBER for: m [      Date newDate(y, m, Date.DaysInMonth(y, m))      while(dup dayOfWeek Date.SUNDAY <>) [ addDays(-1) ] println      ] ;`
Output:
```2013-01-27 00:00:00,000
2013-02-24 00:00:00,000
2013-03-31 00:00:00,000
2013-04-28 00:00:00,000
2013-05-26 00:00:00,000
2013-06-30 00:00:00,000
2013-07-28 00:00:00,000
2013-08-25 00:00:00,000
2013-09-29 00:00:00,000
2013-10-27 00:00:00,000
2013-11-24 00:00:00,000
2013-12-29 00:00:00,000
```

## PARI/GP

`\\ Normalized Julian Day Number from datenjd(D) ={  my (m = D[2], y = D[1]);  if (D[2] > 2, m++, y--; m += 13);  (1461 * y) \ 4 + (306001 * m) \ 10000 + D[3] - 694024 + 2 - y \ 100 + y \ 400} \\ Date from Normalized Julian Day Numbernjdate(J) ={  my (a = J + 2415019, b = (4 * a - 7468865) \ 146097, c, d, m, y);   a += 1 + b - b \ 4 + 1524;  b = (20 * a - 2442) \ 7305;  c = (1461 * b) \ 4;  d = ((a - c) * 10000) \ 306001;  m = d - 1 - 12 * (d > 13);  y = b - 4715 - (m > 2);  d = a - c - (306001 * d) \ 10000;   [y, m, d]} for (m=1, 12, a=njd([2013,m+1,0]); print(njdate(a-(a+6)%7)))`
Output:
```[2013, 1, 27]
[2013, 2, 24]
[2013, 3, 31]
[2013, 4, 28]
[2013, 5, 26]
[2013, 6, 30]
[2013, 7, 28]
[2013, 8, 25]
[2013, 9, 29]
[2013, 10, 27]
[2013, 11, 24]
[2013, 12, 29]
```

## Perl

`#!/usr/bin/perluse strict ;use warnings ;use DateTime ; for my \$i( 1..12 ) {   my \$date = DateTime->last_day_of_month( year => \$ARGV[ 0 ] , 	 month => \$i ) ;   while ( \$date->dow != 7 ) {      \$date = \$date->subtract( days => 1 ) ;   }   my \$ymd = \$date->ymd ;   print "\$ymd\n" ;}`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Phix

Requires 0.8.1 (day_of_week() is now ISO 8601 compliant)

```include timedate.e

constant SUNDAY=7

procedure showlast(integer dow, integer doy, timedate td)
integer {year,month,day} = td
while day_of_week(year,month,day)!=dow do day-=1 end while
printf(1,"%4d-%02d-%02d\n",{year,month,day})
end procedure

procedure last_day_of_month(integer year, integer dow)
integer doy
timedate first = {year,1,1,0,0,0,0,0}
-- start by finding the 1st of the next month, less 1
for i=1 to 11 do
doy = day_of_year(year,i+1,1)-1
showlast(dow,doy,first)
end for
-- do December separately, as 1st would be next year
doy = day_of_year(year,12,31)
showlast(dow,doy,first)
end procedure
last_day_of_month(2013,SUNDAY)
```
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## PHP

`<?php// Created with PHP 7.0 function printLastSundayOfAllMonth(\$year){    \$months = array(        'January', 'February', 'March', 'April', 'June', 'July',        'August', 'September', 'October', 'November', 'December');     foreach (\$months as \$month) {        echo \$month . ': ' . date('Y-m-d', strtotime('last sunday of ' . \$month . ' ' . \$year)) . "\n";    }} printLastSundayOfAllMonth(\$argv[1]); `
Output:
```January: 2013-01-27
February: 2013-02-24
March: 2013-03-31
April: 2013-04-28
June: 2013-06-30
July: 2013-07-28
August: 2013-08-25
September: 2013-09-29
October: 2013-10-27
November: 2013-11-24
December: 2013-12-29
```

## PicoLisp

`(de lastSundays (Y)   (for M 12      (prinl         (dat\$            (find '((D) (= "Sunday" (day D)))               (mapcar '((D) (date Y M D)) `(range 31 22)) )            "-" ) ) ) )`

Test:

`: (lastSundays 2013)2013-01-272013-02-242013-03-312013-04-282013-05-262013-06-302013-07-282013-08-252013-09-292013-10-272013-11-242013-12-29`

## PowerShell

` function last-dayofweek {    param(     [Int][ValidatePattern("[1-9][0-9][0-9][0-9]")]\$year,     [String][validateset('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')]\$dayofweek    )    \$date = (Get-Date -Year \$year -Month 1 -Day 1)    while(\$date.DayOfWeek -ne \$dayofweek) {\$date = \$date.AddDays(1)}    while(\$date.year -eq \$year) {        if(\$date.Month -ne \$date.AddDays(7).Month) {\$date.ToString("yyyy-dd-MM")}        \$date = \$date.AddDays(7)    }}last-dayofweek 2013 "Sunday" `

Output:

```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

### Alternate Version

This script finds the first and/or last or all dates of any of the days of week; accepts `[Int32]` and `[DateTime]` values for Month and Year parameters; outputs `[DateTime]` objects by default but has an option to output time strings in various formats. This script also allows for pipeline input based mainly upon the Month parameter. This script has a syntax as complex as any PowerShell Cmdlet because it attempts to do everything.

` function Get-Date0fDayOfWeek{    [CmdletBinding(DefaultParameterSetName="None")]    [OutputType([datetime])]    Param    (        [Parameter(Mandatory=\$false,                   ValueFromPipeline=\$true,                   ValueFromPipelineByPropertyName=\$true,                   Position=0)]        [ValidateRange(1,12)]        [int]        \$Month = (Get-Date).Month,         [Parameter(Mandatory=\$false,                   ValueFromPipelineByPropertyName=\$true,                   Position=1)]        [ValidateRange(1,9999)]        [int]        \$Year = (Get-Date).Year,         [Parameter(Mandatory=\$true, ParameterSetName="Sunday")]        [switch]        \$Sunday,         [Parameter(Mandatory=\$true, ParameterSetName="Monday")]        [switch]        \$Monday,         [Parameter(Mandatory=\$true, ParameterSetName="Tuesday")]        [switch]        \$Tuesday,         [Parameter(Mandatory=\$true, ParameterSetName="Wednesday")]        [switch]        \$Wednesday,         [Parameter(Mandatory=\$true, ParameterSetName="Thursday")]        [switch]        \$Thursday,         [Parameter(Mandatory=\$true, ParameterSetName="Friday")]        [switch]        \$Friday,         [Parameter(Mandatory=\$true, ParameterSetName="Saturday")]        [switch]        \$Saturday,         [switch]        \$First,         [switch]        \$Last,         [switch]        \$AsString,         [Parameter(Mandatory=\$false)]        [ValidateNotNullOrEmpty()]        [string]        \$Format = "dd-MMM-yyyy"    )     Process    {        [datetime[]]\$dates = 1..[DateTime]::DaysInMonth(\$Year,\$Month) | ForEach-Object {            Get-Date -Year \$Year -Month \$Month -Day \$_ -Hour 0 -Minute 0 -Second 0 |            Where-Object -Property DayOfWeek -Match \$PSCmdlet.ParameterSetName        }         if (\$First -or \$Last)        {            if (\$AsString)            {                if (\$First) {\$dates[0].ToString(\$Format)}                if (\$Last)  {\$dates[-1].ToString(\$Format)}            }            else            {                if (\$First) {\$dates[0]}                if (\$Last)  {\$dates[-1]}            }        }        else        {            if (\$AsString)            {                \$dates | ForEach-Object {\$_.ToString(\$Format)}            }            else            {                \$dates            }        }    }} `

The default is to return `[DateTime]` objects:

` 1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday `
Output:
```Sunday, January 27, 2013 12:00:00 AM
Sunday, February 24, 2013 12:00:00 AM
Sunday, March 31, 2013 12:00:00 AM
Sunday, April 28, 2013 12:00:00 AM
Sunday, May 26, 2013 12:00:00 AM
Sunday, June 30, 2013 12:00:00 AM
Sunday, July 28, 2013 12:00:00 AM
Sunday, August 25, 2013 12:00:00 AM
Sunday, September 29, 2013 12:00:00 AM
Sunday, October 27, 2013 12:00:00 AM
Sunday, November 24, 2013 12:00:00 AM
Sunday, December 29, 2013 12:00:00 AM
```

Return the `[DateTime]` objects as strings (using the default string format):

` 1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday -AsString `
Output:
```27-Jan-2013
24-Feb-2013
31-Mar-2013
28-Apr-2013
26-May-2013
30-Jun-2013
28-Jul-2013
25-Aug-2013
29-Sep-2013
27-Oct-2013
24-Nov-2013
29-Dec-2013
```

Return the `[DateTime]` objects as strings (specifying the string format):

` 1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday -AsString -Format yyyy-MM-dd `
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## PureBasic

`Procedure LastSundayOfEachMonth(yyyy.i,List lfem.i())  Define dv.i=ParseDate("%yyyy",Str(yyyy)), mv.i=1  NewList d.i()  For d=1 To 365     dv=AddDate(dv,#PB_Date_Day,1)    If DayOfWeek(dv)=0      AddElement(d()) : d()=dv    EndIf      Next   dv=0  For mv=1 To 12    ForEach d()      If dv<d() And Month(d())=mv        dv=d()      EndIf    Next    AddElement(lfem()) : lfem()=dv  NextEndProcedure NewList lf.i()Define y.iOpenConsole("Last Sunday of each month")Print("Input Year [ 1971 < y < 2038 ]: ")y=Val(Input())If y>1971 And y<2038  PrintN("Last Sunday of each month...")  LastSundayOfEachMonth(y,lf())  ForEach lf()    PrintN(FormatDate("%dd.%mm.%yyyy",lf()))  NextEndIfPrint("...End")Input()`
Output:
```Input Year [ 1971 < y < 2038 ]: 2013
Last Sunday of each month...
27.01.2013
24.02.2013
31.03.2013
28.04.2013
26.05.2013
30.06.2013
28.07.2013
25.08.2013
29.09.2013
27.10.2013
24.11.2013
29.12.2013
...End```

## Python

` import sysimport calendar year = 2013if len(sys.argv) > 1:    try:        year = int(sys.argv[-1])    except ValueError:        pass for month in range(1, 13):    last_sunday = max(week[-1] for week in calendar.monthcalendar(year, month))    print('{}-{}-{:2}'.format(year, calendar.month_abbr[month], last_sunday)) `

Output:

` 2013-Jan-272013-Feb-242013-Mar-312013-Apr-282013-May-262013-Jun-302013-Jul-282013-Aug-252013-Sep-292013-Oct-272013-Nov-242013-Dec-29 `

## QuickBASIC 4.5

QuickBASIC 4.5 doesn't have a way to manage dates easily. Following you'll see my solution for this task in QuickBASIC/QBASIC

` ' PROGRAM Last Sundays in Quick BASIC 4.5 (LASTSQB1)' This program will calculate the last Sundays of each month in a given year.' It works assigning the year in the command prompt' Usage: LASTSQB1 Year' In the IDE, be sure to assign the COMMAND\$ value in the Run menu. ' VarDIM iWY AS INTEGERDIM A AS STRINGDIM iWM AS INTEGERDIM iWD AS INTEGERDIM strF AS STRING ' SUBs and FUNCTIONsDECLARE FUNCTION LastSundayOfMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER)DECLARE FUNCTION FirstDayOfWeekOnMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER) ' Gets the year from the command lineiWY = VAL(COMMAND\$) ' Verifies if given year is in the range.' If so, runs the program. If not, shows an error message.IF iWY >= 1753 AND iWY <= 2078 THEN  PRINT "Last Sundays of each month on year:"; iWY  strF = "####_-0#_-##"  FOR iWM = 1 TO 12    IF iWM > 9 THEN strF = "####_-##_-##"    iWD = LastSundayOfMonth(iWM, iWY)    PRINT USING strF; iWY; iWM; iWD  NEXT iWMELSE  PRINT "Incorrect year."  PRINT "Usage: LASTSQB1 Year"  PRINT  PRINT "Where Year is a value between 1753 and 2078."END IFPRINTPRINT "End of program"END FUNCTION FirstDayOfWeekOnMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER)  ' Adapted from Ray Thomas' SUB GetDay  '  taken from his program Calandar.BAS   '  available in his site http://brisray.com   ' Var  DIM iDay AS INTEGER  DIM iMonth AS INTEGER  DIM iYear AS INTEGER  DIM iCentury AS INTEGER  DIM iDoW AS INTEGER  DIM strNewYear AS STRING   ' Get the first day of the month  iDay = 1  iMonth = WhichMonth  iYear = WhichYear   ' For any date in Jan or Feb add 12 to the month and  '  subtract 1 from the year  IF iMonth < 3 THEN    iMonth = iMonth + 12    iYear = iYear - 1  END IF   ' Add 1 to the month and multiply by 2.61  ' Drop the fraction (not round) afterwards  iMonth = iMonth + 1  iMonth = FIX(iMonth * 2.61)   ' Add Day, Month and the last two digits of the year  strNewYear = LTRIM\$(STR\$(iYear))  iYear = VAL(RIGHT\$(strNewYear, 2))  iDoW = iDay + iMonth + iYear  iCentury = VAL(LEFT\$(strNewYear, 2))   ' Add a quarter of the last two digits of the year  '  (truncated not rounded)  iYear = FIX(iYear / 4)  iDoW = iDoW + iYear   ' Add the following factors for the year  IF iCentury = 18 THEN iCentury = 2  IF iCentury = 19 THEN iCentury = 0  IF iCentury = 20 THEN iCentury = 6  IF iCentury = 21 THEN iCentury = 4  iDoW = iDoW + iCentury   ' The day of the week is the modulus of iDoY divided by 7  iDoW = (iDoW MOD 7) + 1   ' The returned value will be between 1 and 7. 1 is Sunday.  FirstDayOfWeekOnMonth = iDoWEND FUNCTION FUNCTION LastSundayOfMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER)  ' Var  DIM iLDoM AS INTEGER  DIM iFDoWoM AS INTEGER   SELECT CASE WhichMonth    CASE 1, 3, 5, 7, 8, 10, 12      iLDoM = 31    CASE 2      iLDoM = 28 + ABS((WhichYear MOD 4 = 0 AND WhichYear MOD 100 OR WhichYear MOD 400 = 0) <> 0)    CASE ELSE      iLDoM = 30  END SELECT   ' Get first Sunday  ' All I have to do is to sum the days if the first of the given month  '  is not Sunday.  iFDoWoM = 1 + ((ABS(FirstDayOfWeekOnMonth(WhichMonth, WhichYear) - 7) + 1) MOD 7)   ' Get the last Sunday  ' I add as many days in multiples of 7 to get the last Sunday  '  in the given amount of days in month  iFDoWoM = iFDoWoM + (7 * ((iLDoM - iFDoWoM) \ 7))   ' Returns the last sunday of the given month and year  LastSundayOfMonth = iFDoWoM END FUNCTION `
Output:
```C:\>LASTSQB1 2013
Last Sundays of each month on year: 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

### VB-DOS 1.0

As VB-DOS uses serial numbers for dates and includes some useful functions to work with dates, it is easier to do this code in VB-DOS.

` OPTION EXPLICIT ' PROGRAM Last Sundays in VB-DOS 1.0 (LASTVD1)' This program will calculate the last Sundays of each month in a given year.' It works assigning the year in the command prompt.' Usage: LASTSVD1 Year' In the IDE, be sure to assign the COMMAND\$ value in the Run menu. ' VarDIM iWY AS INTEGERDIM A AS STRINGDIM iWM AS INTEGERDIM iWD AS INTEGER ' SUBs and FUNCTIONsDECLARE FUNCTION LastSundayOfMonth (WhichMonth AS INTEGER, WhichYear AS INTEGER) AS INTEGER ' InitializeiWY = VAL(COMMAND\$) IF iWY >= 1753 AND iWY <= 2078 THEN  PRINT "Last Sundays of each month on year:"; iWY  FOR iWM = 1 TO 12    iWD = LastSundayOfMonth(iWM, iWY)    PRINT FORMAT\$(DATESERIAL(iWY, iWM, iWD), "yyyy-mm-dd")  NEXT iWMELSE  PRINT "Incorrect year. Please, specify a value between 1753 and 2078."END IF PRINTPRINT "End of program"END FUNCTION LastSundayOfMonth (WhichMonth AS INTEGER, WhichYear AS INTEGER) AS INTEGER  ' Var  DIM iLSoM AS INTEGER   SELECT CASE WhichMonth    CASE 1, 3, 5, 7, 8, 10, 12      iLSoM = 31    CASE 2      iLSoM = 28 + ABS((WhichYear MOD 4 = 0 AND WhichYear MOD 100 OR WhichYear MOD 400 = 0) <> 0)    CASE ELSE      iLSoM = 30  END SELECT   ' Get last Sunday  iLSoM = iLSoM - (WEEKDAY(DATESERIAL(WhichYear, WhichMonth, iLSoM)) - 1)   LastSundayOfMonth = iLSoMEND FUNCTION `
Output:
```C:\>LASTSVD1 2013
Last Sundays of each month on year: 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## 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 )   [ dup 400 mod 0 = iff      [ drop true ]  done    dup 100 mod 0 = iff      [ drop false ] done    4 mod 0 = ]                     is leap       (           year --> b       )   [ swap 1 -    [ table      31 [ dup leap 28 + ]      31 30 31 30 31 31 30      31 30 31 ]    do nip ]                        is monthdays  (     month year --> n       )   [ number\$    2 times      [ char - join        over 10 < if           [ char 0 join ]        swap number\$ join ]       echo\$ ]                       is echoymd    ( day month year -->         )   [ dip      [ 2dup monthdays        dup temp put        unrot dayofweek ]    - dup 0 < if [ 7 + ]    temp take swap - ]              is lastwkday  ( month year wkd --> n       )   [ temp put     12 times      [ i^ 1+ over        2dup temp share lastwkday         unrot echoymd cr ]     drop temp release ]            is lastwkdays  (       year wkd -->        )   [ 0 lastwkdays ]                 is lastsundays (           year -->        )   2013 lastsundays`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## R

` last_sundays <- function(year) {	for (month in 1:12) {		if (month == 12) {			date <- as.Date(paste0(year,"-",12,"-",31))		} else {			date <- as.Date(paste0(year,"-",month+1,"-",1))-1		}		while (weekdays(date) != "Sunday") {			date <- date - 1		}		print(date)	}}last_sundays(2004) `
Output:
```[1] "2004-01-25"
[1] "2004-02-29"
[1] "2004-03-28"
[1] "2004-04-25"
[1] "2004-05-30"
[1] "2004-06-27"
[1] "2004-07-25"
[1] "2004-08-29"
[1] "2004-09-26"
[1] "2004-10-31"
[1] "2004-11-28"
[1] "2004-12-26"
```

## Racket

` #lang racket(require srfi/19 math) (define (days-in-month m y)  (define lengths #(0 31 #f 31 30 31 30 31 31 30 31 30 31))  (define d (vector-ref lengths m))  (or d (days-in-feb y))) (define (leap-year? y)  (and (divides? 4 y)       (or (not (divides? 100 y))           (divides? 400 y)))) (define (days-in-feb y)  (if (leap-year? y) 29 28)) (define (last-day-in-month m y)  (make-date 0 0 0 0 (days-in-month m y) m y 0)) (define (week-day date)  (define days #(sun mon tue wed thu fri sat))  (vector-ref days (date-week-day date))) (define (last-sundays y)  (for/list ([m (in-range 1 13)])    (prev-sunday (last-day-in-month m y)))) (define 24hours (make-time time-duration 0 (* 24 60 60))) (define (prev-day d)  (time-utc->date   (subtract-duration     (date->time-utc d) 24hours))) (define (prev-sunday d)  (if (eq? (week-day d) 'sun)      d      (prev-sunday (prev-day d)))) (for ([d (last-sundays 2013)])  (displayln (~a (date->string d "~a ~d ~b ~Y")))) `
Output:
```Sun 27 Jan 2013
Sun 24 Feb 2013
Sun 31 Mar 2013
Sun 28 Apr 2013
Sun 26 May 2013
Sun 30 Jun 2013
Sun 28 Jul 2013
Sun 25 Aug 2013
Sun 29 Sep 2013
Sun 27 Oct 2013
Sun 24 Nov 2013
Sun 29 Dec 2013
```

## Raku

(formerly Perl 6)

Works with: rakudo version 2018.03
`sub MAIN (\$year = Date.today.year) {    for 1..12 -> \$month {        my \$month-end = Date.new(\$year, \$month, Date.new(\$year,\$month,1).days-in-month);        say \$month-end - \$month-end.day-of-week % 7;    }}`
Output  —  for input `2018`:
```2018-01-28
2018-02-25
2018-03-25
2018-04-29
2018-05-27
2018-06-24
2018-07-29
2018-08-26
2018-09-30
2018-10-28
2018-11-25
2018-12-30```

## REBOL

`#!/usr/bin/env rebol last-sundays-of-year: function [    "Return series of last sunday (date!) for each month of the year"    year [integer!] "which year?"  ][    d: to-date reduce [1 1 year]            ; start with first day of year    collect [        repeat month 12 [            d/month: month + 1              ; move to start of next month            keep d - d/weekday              ; calculate last sunday & keep        ]    ]] foreach sunday last-sundays-of-year to-integer system/script/args [print sunday] `
Output:
```./last-sundays.reb 2013
27-Jan-2013
24-Feb-2013
31-Mar-2013
28-Apr-2013
26-May-2013
30-Jun-2013
28-Jul-2013
25-Aug-2013
29-Sep-2013
27-Oct-2013
24-Nov-2013
29-Dec-2013
```

## REXX

This REXX example is an exact replication of the Rosetta Code

• find last Fridays of each month for any year

except for the innards of the first DO loop.

The   lastDOW   subroutine can be used for any day-of-the-week for any month for any year.

`/*REXX program displays dates of last Sundays of each month for any year*/parse arg yyyy                   do j=1 for  12                   _ = lastDOW('Sunday', j, yyyy)                   say right(_,4)'-'right(j,2,0)"-"left(word(_,2),2)                   end  /*j*/exit                                   /*stick a fork in it, we're done.*//*┌────────────────────────────────────────────────────────────────────┐  │ lastDOW:  procedure to return the date of the  last day-of-week of │  │           any particular month  of any particular year.            │  │                                                                    │  │ The  day-of-week  must be specified (it can be in any case,        │  │ (lower-/mixed-/upper-case)  as an English name of the spelled day  │  │ of the week,   with a minimum length that causes no ambiguity.     │  │ I.E.:   W  for Wednesday,   Sa  for Saturday,   Su  for Sunday ... │  │                                                                    │  │ The month can be specified as an integer   1 ──► 12                │  │    1=January     2=February     3=March     ...     12=December    │  │ or the English  name  of the month,  with a minimum length that    │  │ causes no ambiguity.    I.E.:  Jun  for June,   D  for December.   │  │ If omitted  [or an asterisk(*)],  the current month is used.       │  │                                                                    │  │ The year is specified as an integer or just the last two digits    │  │ (two digit years are assumed to be in the current century,  and    │  │ there is no windowing for a two-digit year).                       │  │ If omitted  [or an asterisk(*)],  the current year is used.        │  │ Years < 100   must be specified with  (at least 2)  leading zeroes.│  │                                                                    │  │ Method used: find the "day number" of the 1st of the next month,   │  │ then subtract one  (this gives the "day number" of the last day of │  │ the month,  bypassing the leapday mess).   The last day-of-week is │  │ then obtained straightforwardly,   or  via subtraction.            │  └────────────────────────────────────────────────────────────────────┘*/lastdow: procedure; arg dow .,mm .,yy .              /*DOW = day of week*/parse arg a.1,a.2,a.3                                /*orig args, errmsg*/if mm=='' | mm=='*' then mm=left(date('U'),2)        /*use default month*/if yy=='' | yy=='*' then yy=left(date('S'),4)        /*use default year */if length(yy)==2 then yy=left(date('S'),2)yy         /*append century.  */                   /*Note mandatory leading blank in strings below.*/\$=" Monday TUesday Wednesday THursday Friday SAturday SUnday"!=" JAnuary February MARch APril MAY JUNe JULy AUgust September",  " October November December"upper \$ !                                            /*uppercase strings*/if dow==''                 then call .er "wasn't specified",1if arg()>3                 then call .er 'arguments specified',4   do j=1 for 3                                       /*any plural args ?*/  if words(arg(j))>1       then call .er 'is illegal:',j  end dw=pos(' 'dow,\$)                                     /*find  day-of-week*/if dw==0                   then call .er 'is invalid:',1if dw\==lastpos(' 'dow,\$)  then call .er 'is ambigious:',1 if datatype(mm,'month') then                         /*if MM is alpha...*/  do  m=pos(' 'mm,!)                                     /*maybe its good...*/  if m==0                  then call .er 'is invalid:',1  if m\==lastpos(' 'mm,!)  then call .er 'is ambigious:',2  mm=wordpos(word(substr(!,m),1),!)-1                /*now, use true Mon*/  end if \datatype(mm,'W')       then call .er "isn't an integer:",2if \datatype(yy,'W')       then call .er "isn't an integer:",3if mm<1 | mm>12            then call .er "isn't in range 1──►12:",2if yy=0                    then call .er "can't be 0 (zero):",3if yy<0                    then call .er "can't be negative:",3if yy>9999                 then call .er "can't be > 9999:",3 tdow=wordpos(word(substr(\$,dw),1),\$)-1               /*target DOW, 0──►6*/                                                     /*day# of last dom.*/_=date('B',right(yy+(mm=12),4)right(mm//12+1,2,0)"01",'S')-1?=_//7                                               /*calc. DOW,  0──►6*/if ?\==tdow then _=_-?-7+tdow+7*(?>tdow)             /*not DOW?  Adjust.*/return date('weekday',_,"B") date(,_,'B')            /*return the answer*/ .er: arg ,_;say; say '***error!*** (in LASTDOW)';say /*tell error,  and */  say word('day-of-week month year excess',arg(2)) arg(1) a._  say; exit 13                                       /*... then exit.   */`
output   when using the default input   (the current year,   2013):
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Ring

` see "What year to calculate (yyyy) : " give yearsee "Last Sundays in " + year + " are on :" + nlmonth = list(12)mo = [4,0,0,3,5,1,3,6,2,4,0,2]mon = [31,28,31,30,31,30,31,31,30,31,30,31]if year < 2100 leap = year - 1900 else leap = year - 1904 okm = ((year-1900)%7) + floor(leap/4) % 7for n = 1 to 12    month[n] = (mo[n] + m) % 7nextfor n = 1 to 12    for i = (mon[n] - 6) to mon[n]        x = (month[n] + i) % 7         if  n < 10 strn = "0" + string(n) else strn = string(n) ok        if x = 4 see year + "-" + strn + "-" + string(i) + nl ok    nextnext `

Output:

```What year to calculate (yyyy) : 2013
Last Sundays in 2013 are on :
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Ruby

`require 'date' def last_sundays_of_year(year = Date.today.year)  (1..12).map do |month|    d = Date.new(year, month, -1) # -1 means "last".    d - d.wday  endend puts last_sundays_of_year(2013)`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

Results before the year 1581 may differ from other languages - the Date library takes the Julian reform into account.

## Run BASIC

`input "What year to calculate (yyyy) : ";yearprint "Last Sundays in ";year;" are:" dim month(12)mo\$ = "4 0 0 3 5 1 3 6 2 4 0 2"mon\$ = "31 28 31 30 31 30 31 31 30 31 30 31" if year < 2100 then leap = year - 1900 else leap = year - 1904m = ((year-1900) mod 7) + int(leap/4) mod 7for n = 1 to 12    month(n) = (val(word\$(mo\$,n)) + m) mod 7    month(n) = (val(word\$(mo\$,n)) + m) mod 7nextfor n = 1 to 12    for i = (val(word\$(mon\$,n)) - 6) to val(word\$(mon\$,n))        x = (month(n) + i) mod 7         if x = 4 then print year ; "-";right\$("0"+str\$(n),2);"-" ; i    nextnext`
```What year to calculate (yyyy) : ?2013
Last Sundays in 2013 are:
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```

## Rust

`use std::env::args;use time::{Date, Duration}; fn main() {    let year = args().nth(1).unwrap().parse::<i32>().unwrap();    (1..=12)        .map(|month| Date::try_from_ymd(year + month / 12, ((month % 12) + 1) as u8, 1))        .filter_map(|date| date.ok())        .for_each(|date| {            let days_back =                Duration::days(((date.weekday().number_from_sunday() as i64 + 5) % 7) + 1);            println!("{}", date - days_back);        });}`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## S-BASIC

` rem - return p mod qfunction mod(p, q = integer) = integerend = p - q * (p/q) comment    return day of week (Sun = 0, Mon = 1, etc.) for a    given Gregorian calendar date using Zeller's congruenceendfunction 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 - return true if y is a leap yearfunction isleap(y = integer) = integerend = mod(y,4)=0 and mod(y,100)<>0 or mod(y,400)=0 rem - return number of days in specified monthfunction monthdays(m, y = integer) = integer    var n = integer    if m = 2 then        if isleap(y) then            n = 29        else            n = 28    else if (m = 4) or (m = 6) or (m = 9) or (m = 11) then        n = 30    else        n = 31end = n comment   return the day of the month corresponding to the last   occurrence of weekday k (Sun=0, Mon=1, etc.) in the given   month and yearendfunction lastkday(k, m, y = integer) = integer   var d, w = integer   rem - determine weekday for last day of the month   d = monthdays(m, y)   w = dayofweek(m, d, y)   rem - back up as needed to desired weekday   if w >= k then      d = d - (w - k)   else      d = d - (7 - (k - w))end = d rem - return abbreviated month namefunction shortmonth (m = integer) = stringend = mid("JanFebMarAprMayJunJulAugSepOctNovDec", m*3-2, 3) rem - main program starts here \$constant SUNDAY = 0var m, y = integerinput "Display last Sundays in what year"; yfor m = 1 to 12   print shortmonth(m);" ";lastkday(SUNDAY, m, y)next mend`
Output:
```Display last Sundays in what year? 2021
Jan 21
Feb 28
Mar 28
Apr 25
May 30
Jun 27
Jul 25
Aug 29
Sep 26
Oct 31
Nov 28
Dec 26```

## Scala

`object FindTheLastSundayOfEachMonth extends App {  import java.util.Calendar._  val cal = getInstance   def lastSundaysOf(year: Int) =    (JANUARY to DECEMBER).map{month =>      cal.set(year, month + 1, 1) // first day of next month      (1 to 7).find{_ => cal.add(DAY_OF_MONTH, -1); cal.get(DAY_OF_WEEK) == SUNDAY}      cal.getTime    }   val year = args.headOption.map(_.toInt).getOrElse(cal.get(YEAR))  val fmt = new java.text.SimpleDateFormat("yyyy-MM-dd")  println(lastSundaysOf(year).map(fmt.format) mkString "\n")}`

### Java 8

`object FindTheLastSundayOfEachMonth extends App {  def lastSundaysOf(year: Int) = (1 to 12).map{month =>    import java.time._; import java.time.temporal.TemporalAdjusters._    LocalDate.of(year, month, 1).`with`(lastDayOfMonth).`with`(previousOrSame(DayOfWeek.SUNDAY))}   val year = args.headOption.map(_.toInt).getOrElse(java.time.LocalDate.now.getYear)  println(lastSundaysOf(year) mkString "\n")}`

## Seed7

Uses the libraries time.s7i and duration.s7i. Applicable to any day of the week, cf. [[3]].

`\$ include "seed7_05.s7i";  include "time.s7i";  include "duration.s7i"; const proc: main is func  local    var integer: weekday is 1; # 1 for monday, 2 for tuesday, and so on up to 7 for sunday.    var integer: year is 0;    var integer: month is 1;    var time: aDate is time.value;    var time: selected is time.value;  begin    if length(argv(PROGRAM)) <> 2 then      writeln("usage: lastWeekdayInMonth weekday year");      writeln("  weekday: 1 for monday, 2 for tuesday, and so on up to 7 for sunday.");    else      weekday := integer parse (argv(PROGRAM)[1]);      year := integer parse (argv(PROGRAM)[2]);      for month range 1 to 12 do        aDate := date(year, month, 1);        while aDate.month = month do          if dayOfWeek(aDate) = weekday then            selected := aDate;          end if;          aDate +:= 1 . DAYS;        end while;        writeln(strDate(selected));      end for;    end if;  end func;`
Output:
when called with s7 rosetta/lastWeekdayInMonth 7 2013:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Sidef

`var dt = require('DateTime');var (year=2016) = ARGV.map{.to_i}... for i in (1 .. 12) {    var date = dt.last_day_of_month(        year  => year,        month => i    );     while (date.dow != 7) {        date = date.subtract(days => 1);    }     say date.ymd;}`
Output:
```\$ sidef last_sunday.sf 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## Smalltalk

` Pharo Smalltalk [ :yr | | firstDay firstSunday |  firstDay := Date year: yr month: 1 day: 1.  firstSunday := firstDay addDays: (1 - firstDay dayOfWeek).    (0 to: 53)       collect: [ :each | firstSunday addDays: (each * 7) ]      thenSelect: [ :each |         (((Date daysInMonth: each monthIndex forYear: yr) - each dayOfMonth) <= 6) and: [ each year = yr ] ] ] `
Output:
```Send value: 2013 to the above block to return an array:
(27 January 2013 24 February 2013 31 March 2013 28 April 2013 26 May 2013 30 June 2013 28 July 2013 25 August 2013 29 September 2013 27 October 2013 24 November 2013 29 December 2013)
```

## Stata

`program last_sundays	args year	clear	qui set obs 12	gen day=dofm(mofd(mdy(_n,1,`year'))+1)-1	qui replace day=day-mod(dow(day),7)	format %td day	list, noobs noheader sep(6)end last_sundays 2013   +-----------+  | 27jan2013 |  | 24feb2013 |  | 31mar2013 |  | 28apr2013 |  | 26may2013 |  | 30jun2013 |  |-----------|  | 28jul2013 |  | 25aug2013 |  | 29sep2013 |  | 27oct2013 |  | 24nov2013 |  | 29dec2013 |  +-----------+`

## Swift

`import Foundation func lastSundays(of year: Int) -> [Date] { 	let calendar = Calendar.current	var dates = [Date]() 	for month in 1...12 { 		var dateComponents = DateComponents(calendar: calendar,		                                    year: year,		                                    month: month + 1,		                                    day: 0,		                                    hour: 12) 		let date = calendar.date(from: dateComponents)!		let weekday = calendar.component(.weekday, from: date) 		if weekday != 1 {			dateComponents.day! -= weekday - 1		} 		dates.append(calendar.date(from: dateComponents)!)	}	return dates} var dateFormatter = DateFormatter()dateFormatter.dateStyle = .short print(lastSundays(of: 2013).map(dateFormatter.string).joined(separator: "\n"))`
Output:
```1/27/13
2/24/13
3/31/13
4/28/13
5/26/13
6/30/13
7/28/13
8/25/13
9/29/13
10/27/13
11/24/13
12/29/13
```

## Tcl

`proc lastSundays {{year ""}} {    if {\$year eq ""} {	set year [clock format [clock seconds] -gmt 1 -format "%Y"]    }    foreach month {2 3 4 5 6 7 8 9 10 11 12 13} {	set d [clock add [clock scan "\$month/1/\$year" -gmt 1] -1 day]	while {[clock format \$d -gmt 1 -format "%u"] != 7} {	    set d [clock add \$d -1 day]	}	lappend result [clock format \$d -gmt 1 -format "%Y-%m-%d"]    }    return \$result}puts [join [lastSundays {*}\$argv] "\n"]`
Output:

When called as: “`tclsh lastSundays.tcl 2013`” (or with the year argument omitted during 2013)

```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-20
2013-11-24
2013-12-29
```

## UNIX Shell

Works with: Bourne Again SHell

This uses the programs awk and cal, which are usually installed on any POSIXlike system.

`last_sundays() {  local y=\$1  for (( m=1; m<=12; ++m )); do    cal \$m \$y | awk -vy=\$y -vm=\$m '/^.[0-9]/ {d=\$1} END {print y"-"m"-"d}'  done}`
Output:
```\$ last_sundays 2013
2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29```

## VBScript

Works with: Windows Script Host version *
` strYear = WScript.StdIn.ReadLine For i = 1 To 12	d = DateSerial(strYear, i + 1, 1) - 1	WScript.Echo d - Weekday(d) + 1Next `

## Wren

Library: Wren-date
`import "os" for Processimport "/date" for Date var args = Process.argumentsif (args.count != 1) {    Fiber.abort("Please pass just the year to be processed.")} var year = Num.fromString(args[0])System.print("The dates of the last Sundays in the month for %(year) are:")Date.default = Date.isoDatefor (m in 1..12) {    var d = Date.monthLength(year, m)    var dt = Date.new(year, m, d)    var wd = dt.dayOfWeek    if (wd == 7) {        System.print(dt)    } else {        System.print(dt.addDays(-wd))    }}`
Output:
```\$ wren last_sunday.wren 2013
The dates of the last Sundays in the month for 2013 are:
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29

\$ wren last_sunday.wren 2020
The dates of the last Sundays in the month for 2020 are:
2020-01-26
2020-02-23
2020-03-29
2020-04-26
2020-05-31
2020-06-28
2020-07-26
2020-08-30
2020-09-27
2020-10-25
2020-11-29
2020-12-27
```

## XPL0

`func WeekDay(Year, Month, Day);   \Return day of week (0=Sun, 1=Mon ... 6=Sat)int  Year, Month, Day;            \works for years from 1583 onward[if Month<=2 then [Month:= Month+12;  Year:= Year-1];return rem((Day-1 + (Month+1)*26/10 + Year + Year/4 + Year/100*6 + Year/400)/7);]; int Year, Month, LastDay, WD;[Year:= IntIn(8);               \from command linefor Month:= 1 to 12 do    [LastDay:= WeekDay(Year, Month+1, 1) - WeekDay(Year, Month, 28);    if LastDay < 0 then LastDay:= LastDay + 7;    LastDay:= LastDay + 27;     \ = number of days in Month    WD:= WeekDay(Year, Month, LastDay);    LastDay:= LastDay - WD;    IntOut(0, Year);  ChOut(0, ^-);    if Month < 10 then ChOut(0, ^0);  IntOut(0, Month);  ChOut(0, ^-);    IntOut(0, LastDay);  CrLf(0);    ];]`
Output:
```2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29
```

## zkl

The program from [[4]] solves this task, as well.

Output:
```var [const] D=Time.Date;
lastDay(2013,D.Sunday)
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29```