Find the last Sunday of each month: Difference between revisions

Add Easylang
(Add Easylang)
 
(139 intermediate revisions by 59 users not shown)
Line 1:
{{task}} [[Category:Date and time]]
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).
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:
Line 20 ⟶ 17:
2013-11-24
2013-12-29</pre>
<br>
 
;Related tasks
;Cf.:
* [[Day of the week]]
* [[Five weekends]]
* [[Last Friday of each month]]
<br><br>
 
=={{header|11l}}==
 
<syntaxhighlight lang="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"))</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|360 Assembly}}==
The program uses one ASSIST macro (XPRNT) to keep the code as short as possible.
<syntaxhighlight lang="360asm">* Last Sunday of each month 31/01/2017
LASTSUND 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 NOTLEAP
LEAP MVC DAYS+4(4),=F'29' days(2)=29
NOTLEAP 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=1
LOOPM 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 LOOPM
ELOOPM L R13,4(0,R13) epilog
LM R14,R12,12(R13) " restore
XR R15,R15 " rc=0
BR R14 exit
YEAR DC F'2013' <== input year
DAYS 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' buffer
XDEC DS CL12 temp
DW DS D packed (PL8) 15num
YREGS
END LASTSUND</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|Action!}}==
Day of the week is determined using [https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Sakamoto.27s_methods Sakamoto method].
<syntaxhighlight lang="action!">;https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Sakamoto.27s_methods
BYTE 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 7
RETURN (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)
FI
RETURN (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)
FI
RETURN (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()
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Find_the_last_Sunday_of_each_month.png Screenshot from Atari 8-bit computer]
<pre>
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
</pre>
 
=={{header|Ada}}==
Line 33 ⟶ 244:
<pre>>./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</pre>
 
=={{header|ALGOL 68}}==
{{Trans|ALGOL W}}
<syntaxhighlight lang="algol68">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
)
)
OD
END</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|ALGOL-M}}==
<syntaxhighlight lang="algol">
BEGIN
 
% CALCULATE P MOD Q %
INTEGER FUNCTION MOD(P, Q);
INTEGER P, Q;
BEGIN
MOD := P - Q * (P / Q);
END;
 
COMMENT
RETURN DAY OF WEEK (SUN=0, MON=1, ETC.) FOR A GIVEN
GREGORIAN CALENDAR DATE USING ZELLER'S CONGRUENCE;
INTEGER FUNCTION DAYOFWEEK(MO, DA, YR);
INTEGER MO, DA, YR;
BEGIN
INTEGER Y, C, Z;
IF MO < 3 THEN
BEGIN
MO := MO + 10;
YR := YR - 1;
END
ELSE MO := MO - 2;
Y := MOD(YR, 100);
C := YR / 100;
Z := (26 * MO - 2) / 10;
Z := Z + DA + Y + (Y / 4) + (C / 4) - 2 * C + 777;
DAYOFWEEK := MOD(Z, 7);
END;
 
% 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
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|ALGOL W}}==
Uses the Day_of_week and isLeapYear procedures from the day-of-the-week and leap-year tasks - included here for convenience.
<syntaxhighlight lang="algolw">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 ) )
end
end.</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|AppleScript}}==
 
{{Trans|JavaScript}}
 
<syntaxhighlight lang="applescript">-- 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 if
end argIntegers
 
 
-- GENERIC FUNCTIONS ---------------------------------------------------------
 
-- apply (a -> b) -> a -> b
on apply(f, a)
mReturn(f)'s |λ|(a)
end apply
 
-- calendarDate :: Int -> Int -> Int -> Date
on calendarDate(intYear, intMonth, intDay)
tell (current date)
set {its year, its month, its day, its time} to ¬
{intYear, intMonth, intDay, 0}
return it
end tell
end calendarDate
 
-- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)
on cond(bool, f, g)
if bool then
f
else
g
end if
end 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 lst
end enumFromTo
 
-- intercalate :: Text -> [Text] -> Text
on 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 strJoined
end intercalate
 
-- isoDateString :: Date -> String
on 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] -> String
on 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 tell
end map
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
-- parseInt :: String -> Int
on parseInt(s)
s as integer
end 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</syntaxhighlight>
{{Out}}
<pre>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</pre>
 
----
 
More straightforward solution:
 
AppleScript's weekday constants can be coerced either to English text or to the integers 1 (for Sunday) to 7 (Saturday).
 
<syntaxhighlight lang="applescript">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 outputText
end lastSundayOfEachMonthInYear
 
lastSundayOfEachMonthInYear(2020)</syntaxhighlight>
 
{{Out}}
<pre>"./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"</pre>
 
The above is hard-coded for Sundays. As with the "Last Friday of each month" task [[https://www.rosettacode.org/wiki/Last_Friday_of_each_month#AppleScript 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:
 
<syntaxhighlight lang="applescript">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 outputText
end lastWeekdayWOfEachMonthInYear
 
lastWeekdayWOfEachMonthInYear(Sunday, 2020)</syntaxhighlight>
{{Out}}
<pre>"./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"</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">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</syntaxhighlight>
 
{{out}}
 
<pre>2013-01-27
2013-02-24
2013-03-31
Line 46 ⟶ 852:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">InputBox, Year, , Enter a year., , 300, 135
Date := Year . "0101"
 
Line 65 ⟶ 871:
 
Gui, Show
return</langsyntaxhighlight>
{{out}}
<pre>Last Sundays of 2013:
Line 83 ⟶ 889:
 
=={{header|AWK}}==
<syntaxhighlight lang="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)
}
</syntaxhighlight>
<p>Output:</p>
<pre>
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
</pre>
 
=={{header|Batch File}}==
Works with GNU awk version 3.1.5 and BusyBox awk in version v1.20.0.git
Uses day of week, last day of month and leapyear routines
<syntaxhighlight lang="batch file">
@echo off
setlocal enabledelayedexpansion
set /p yr= Enter year:
echo.
call:monthdays %yr% list
set mm=1
for %%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
)
pause
exit /b
 
:monthdays yr &list
Takes one or more years from standard input; easy way to generate one year's input, for example:
setlocal
call:isleap %1 ly
for /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=sunday
echo 2013 | lastsunday
setlocal
set/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 expansion
<pre>
set /a "%2=^!(%1%%4)+(^!^!(%1%%100)-^!^!(%1%%400))"
#!/bin/gawk -f
exit /b
BEGIN{
</syntaxhighlight>
# table of days per month accessed as substr(days,2*month,2)
days =" 312831303130313130313031"
}
function dow (year, y){
y=year
y= (y*365+int(y/4) - int(y/100) + int(y/400) +1) %7
# leap year adjustment
leap = 0
if (year % 4 == 0) leap = 1
if (year % 100 == 0) leap = 0
if (year % 400 == 0) leap = 1
y = y - leap
if (y==-1) y=6
if (y==0) y=7
return (y)
}
function prmonth (nmonth, newdow,monsize ,j ){
for ( j=23-newdow; j<=monsize;j=j+7) { last=j }
print nmonth "/" last
}
/q/{
exit }
{
monsize=substr(days,2*1,2)
newdow=dow($1)
print "last Sundays for " $1
# January - December
for (i=1; i<13; i++) {
prmonth(i,newdow,monsize)
newdow=(monsize+newdow) %7
if (newdow == 0) newdow = 7
monsize=substr(days,2+2*i,2)
if (leap == 1 && monsize == 28) monsize = 29
}
}
</pre>
{{out}}
<pre>
Enter year: 2016
last Sundays for 2013
 
1/27
2016-01-31
2/24
2016-02-28
3/31
2016-03-27
4/28
2016-04-24
5/26
2016-05-29
6/30
2016-06-26
7/28
2016-07-31
8/25
2016-08-28
9/29
2016-09-25
10/27
2016-10-30
11/24
2016-11-27
12/29
2016-12-25
</pre>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic">
INSTALL @lib$+"DATELIB"
 
Line 158 ⟶ 993:
NEXT
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 180 ⟶ 1,015:
=={{header|Befunge}}==
This is essentially identical to [[Last_Friday_of_each_month#Befunge|Last Friday of each month]] except for the initial day offset.
<langsyntaxhighlight lang="befunge">":raeY",,,,,&>55+,:::45*:*%\"d"%!*\4%+!3v
v2++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,+*<</langsyntaxhighlight>
 
{{out}}
Line 204 ⟶ 1,039:
 
=={{header|C}}==
Identical to [[Last_Friday_of_each_month#C|Last Friday of each month]] except for removal of the offset day in the output.
{{incorrect|C|It can produce different results depending on the time of day that it is run (amongst other issues).}}
 
<syntaxhighlight lang="c">
<lang C>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main(int argc, char *argv[])
#define NUM_MONTHS 12
 
void LastSundays(int year)
{
int days[] = {31,29,31,30,31,30,31,31,30,31,30,31};
time_t t;
struct tm* datetime int m, y, w;
 
if (argc < 2 || (y = atoi(argv[1])) <= 1752) return 1;
int sunday=0;
days[1] -= (y % 4) || (!(y % 100) && (y % 400));
int dayOfWeek=0;
w = y * 365 + 97 * (y - 1) / 400 + 4;
int month=0;
int monthDay=0;
int isLeapYear=0;
int daysInMonth[NUM_MONTHS]={
31,28,31,30,31,30,31,31,30,31,30,31
};
 
for(m = 0; m < 12; m++) {
isLeapYear=(year%4==0 || ((year%100==0) && (year%400==0)));
w = (w + days[m]) % 7;
printf("%d-%02d-%d\n", y, m + 1,days[m] - w);
}
 
if(isLeapYear) return 0;
}
{
</syntaxhighlight>
daysInMonth[1]=29;
}
 
=={{header|C sharp|C#}}==
time(&t);
<syntaxhighlight lang="csharp">using System;
datetime = localtime(&t);
datetime->tm_year=year-1900;
for(month=0; month<12;month++)
{
datetime->tm_mon=month;
monthDay=daysInMonth[month];
datetime->tm_mday=monthDay;
 
t = mktime(datetime);
dayOfWeek=datetime->tm_wday;
 
namespace LastSundayOfEachMonth
while(dayOfWeek!=sunday)
{
class Program
{
static void Main()
{
monthDay--Console.Write("Year to calculate: ");
datetime->tm_mday=monthDay;
t = mktime(datetime);
dayOfWeek=datetime->tm_wday;
 
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"));
}
}
printf("%d-%02d-%02d\n",year,month+1,monthDay);
}
 
}
</syntaxhighlight>
 
{{out}}
int main()
<pre>Year to calculate: 2013
{
2013-Jan-27
LastSundays(2013);
2013-Feb-24
return 0;
2013-Mar-31
}
2013-Apr-28
 
2013-May-26
</lang>
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <iostream>
Line 368 ⟶ 1,215:
}
//--------------------------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 387 ⟶ 1,234:
</pre>
Other solution, based on the Boost DateTime library:
<langsyntaxhighlight Clang="c++">#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <cstdlib>
Line 409 ⟶ 1,256:
}
return 0 ;
}</langsyntaxhighlight>
{{out}}
<pre>2013-Jan-27
Line 424 ⟶ 1,271:
2013-Dec-29
</pre>
===Using C++20===
Using C++20 this task can be completed without external libraries.
<syntaxhighlight lang="c++">
 
#include <chrono>
=={{header|C sharp|C#}}==
#include <iostream>
<lang csharp>using System;
 
int main() {
namespace LastSundayOfEachMonth
std::cout << "The dates of the last Sunday in each month of 2023:" << std::endl;
{
class Program
{
static void Main()
{
Console.Write("Year to calculate: ");
 
for ( unsigned int m = 1; m <= 12; ++m ) {
string strYear = Console.ReadLine();
std::chrono::days days_in_month = std::chrono::sys_days{std::chrono::year{2023}/m/std::chrono::last}
int year = Convert.ToInt32(strYear);
- std::chrono::sys_days{std::chrono::year{2023}/m/1} + std::chrono::days{1};
 
const unsigned int last_day = days_in_month / std::chrono::days{1};
DateTime date;
std::chrono::year_month_day ymd{std::chrono::year{2023}, std::chrono::month{m}, std::chrono::day{last_day}};
for (int i = 1; i <= 12; i++)
 
{
while ( std::chrono::weekday{ymd} != std::chrono::Sunday ) {
date = new DateTime(year, i, DateTime.DaysInMonth(year, i), System.Globalization.CultureInfo.CurrentCulture.Calendar);
ymd = std::chrono::sys_days{ymd} - std::chrono::days{1};
while (date.DayOfWeek != DayOfWeek.Sunday)
}
{
 
date = date.AddDays(-1);
std::cout << ymd << std::endl;
}
}
Console.WriteLine(date.ToString("yyyy-MM-dd"));
}
}
}
}
</syntaxhighlight>
</lang>
{{ out }}
<pre>
<pre>Year to calculate: 2013
The dates of the last Sunday in each month of 2023:
2013-Jan-27
2023-01-29
2013-Feb-24
2023-02-26
2013-Mar-31
2023-03-26
2013-Apr-28
2023-04-30
2013-May-26
2023-05-28
2013-Jun-30
2023-06-25
2013-Jul-28
2023-07-30
2013-Aug-25
2023-08-27
2013-Sep-29
2023-09-24
2013-Oct-27
2023-10-29
2013-Nov-24
2023-11-26
2013-Dec-29
2023-12-31
</pre>
 
=={{header|Clojure}}==
 
<langsyntaxhighlight lang="clojure">(ns last-sundays.core
(:require [clj-time.core :as time]
[clj-time.periodic :refer [periodic-seq]]
Line 496 ⟶ 1,340:
(defn -main [& args]
(println (last-sundays-of-months (Integer. (first args)))))
</syntaxhighlight>
</lang>
{{out}}
<pre>2013-01-27
Line 511 ⟶ 1,355:
2013-12-29
</pre>
 
=={{header|COBOL}}==
<syntaxhighlight lang="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.
</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|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.
 
<syntaxhighlight lang="lisp">(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)</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">void lastSundays(in uint year) {
import std.stdio, std.datetime;
 
Line 526 ⟶ 1,471:
void main() {
lastSundays(2013);
}</langsyntaxhighlight>
{{out}}
<pre>2013-Jan-27
Line 540 ⟶ 1,485:
2013-Nov-24
2013-Dec-29</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.DateUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Find_the_last_Sunday_of_each_month;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.DateUtils;
 
// ADayOfWeek -> sunday is the first day and is 1
function 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.</syntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func leap year .
return if year mod 4 = 0 and (year mod 100 <> 0 or year mod 400 = 0)
.
func weekday year month day .
normdoom[] = [ 3 7 7 4 2 6 4 1 5 3 7 5 ]
c = year div 100
r = year mod 100
s = r div 12
t = r mod 12
c_anchor = (5 * (c mod 4) + 2) mod 7
doom = (s + t + (t div 4) + c_anchor) mod 7
anchor = normdoom[month]
if leap year = 1 and month <= 2
anchor = (anchor + 1) mod1 7
.
return (doom + day - anchor + 7) mod 7 + 1
.
mdays[] = [ 31 28 31 30 31 30 31 31 30 31 30 31 ]
proc last_sundays year . .
for m to 12
d = mdays[m]
if m = 2 and leap year = 1
d = 29
.
d -= weekday year m d - 1
m$ = m
if m < 10
m$ = "0" & m
.
print year & "-" & m$ & "-" & d
.
.
last_sundays 2023
</syntaxhighlight>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule RC do
def lastSunday(year) do
Enum.map(1..12, fn month ->
Line 556 ⟶ 1,592:
Enum.each(RC.lastSunday(y), fn {year, month, day} ->
:io.format "~4b-~2..0w-~2..0w~n", [year, month, day]
end)</langsyntaxhighlight>
 
{{out}}
Line 574 ⟶ 1,610:
2013-12-29
</pre>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="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)</syntaxhighlight>
{{output}}
<pre>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 </pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( last_date_each_month last_sundays).
 
-export([in_year/1]).
-export( [monday/1, tuesday/1, wednesday/1, thursday/1, friday/1, saturday/1, sunday/1] ).
 
% calculate all the last sundays in a particular year
monday( Year ) -> last( Year, 1 ).
tuesdayin_year( Year ) -> last( Year, 2 ).
wednesday( [lastday(Year, Month, 7) || Month <-> lastlists:seq( Year1, 3 12)].
 
thursday( Year ) -> last( Year, 4 ).
% calculate the date of the last occurrence of a particular weekday
friday( Year ) -> last( Year, 5 ).
lastday(Year, Month, WeekDay) ->
saturday( Year ) -> last( Year, 6 ).
Ldm = calendar:last_day_of_the_month(Year, Month),
sunday( Year ) -> last( Year, 7 ).
Diff = calendar:day_of_the_week(Year, Month, Ldm) rem WeekDay,
{Year, Month, Ldm - Diff}.
 
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|Excel}}==
===LAMBDA===
 
Binding the name '''lastSundayOfEachMonth''' to the following lambda expression in the Name Manager of the Excel WorkBook:
 
(See [https://www.microsoft.com/en-us/research/blog/lambda-the-ultimatae-excel-worksheet-function/ LAMBDA: The ultimate Excel worksheet function])
 
{{Works with|Office 365 betas 2021}}
<syntaxhighlight lang="lisp">lastSundayOfEachMonth
=LAMBDA(y,
LAMBDA(monthEnd,
1 + monthEnd - WEEKDAY(monthEnd)
)(
EDATE(
DATEVALUE(y & "-01-31"),
SEQUENCE(12, 1, 0, 1)
)
)
)</syntaxhighlight>
{{Out}}
The formula in cell B2 defines an array which populates the range '''B2:B13'''.
 
(Any Excel date format can be applied to those cells)
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="2" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=lastSundayOfEachMonth(A2)
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
| style="font-weight:bold" | Year
| style="font-weight:bold" | Last Sundays
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| 2013
| style="background-color:#cbcefb" | 2013-01-27
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
|
| 2013-02-24
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
|
| 2013-03-31
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
|
| 2013-04-27
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
|
| 2013-05-25
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
|
| 2013-06-29
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 8
|
| 2013-07-27
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 9
|
| 2013-08-24
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 10
|
| 2013-09-28
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 11
|
| 2013-10-26
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 12
|
| 2013-11-24
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 13
|
| 2013-12-29
|}
 
=={{header|F_Sharp|F#}}==
<p>We use a transformation from and to the Julian Day Number, see also PARI/GP or Fortran.</p>
<p>The formulars used here come from [http://calendars.wikia.com/wiki/Julian_day_number] (section "Calculation").</p>
<syntaxhighlight lang="fsharp">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</syntaxhighlight>
{{out}}
<pre>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)</pre>
 
=={{header|Factor}}==
This program expects a year passed in via command line argument. In case you are wondering — yes — Factor has a <tt>last-sunday-of-month</tt> word in its calendar vocabulary. This is par for the course when it comes to Factor.
<syntaxhighlight lang="factor">USING: calendar calendar.format command-line io kernel math math.parser
sequences ;
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</syntaxhighlight>
last( Year, Week_day ) ->
Months = lists:seq( 1, 12 ),
Months_days = [{X, Y} || X <- Months, Y <- lists:seq(calendar:last_day_of_the_month(Year, X), calendar:last_day_of_the_month(Year, X) - 7, -1), calendar:valid_date(Year, X, Y), calendar:day_of_the_week(Year, X, Y) =:= Week_day],
[{Year, X, proplists:get_value(X, Months_days)} || X <- Months].
</lang>
{{out}}
<pre>
>factor last-sunday.factor 2013
30> [io:fwrite("~B-~2.10.0B-~B~n", [Y,M,D]) || {Y,M,D} <- last_date_each_month:sunday(2013)].
2013-01-27
2013-02-24
Line 614 ⟶ 1,836:
 
=={{header|FBSL}}==
<langsyntaxhighlight lang="qbasic">#APPTYPE CONSOLE
 
DIM date AS INTEGER, dayname AS STRING
Line 631 ⟶ 1,853:
 
PAUSE
</syntaxhighlight>
</lang>
{{out}}
<pre>2013-1-27
Line 654 ⟶ 1,876:
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 <langsyntaxhighlight Fortranlang="fortran"> D = DAYNUM(Y,M,D) !Daynumber from date.
DAYNUM(Y,M,D) = D !Date parts from a day number.</langsyntaxhighlight>
But alas, only pl/i offers palindromic functions, and only for SUBSTR.
 
<syntaxhighlight lang="fortran">
<lang Fortran>
MODULE DATEGNASH
C Calculate conforming to complex calendarical contortions.
Line 915 ⟶ 2,137:
GO TO 10
END
</syntaxhighlight>
</lang>
And after all that, results:
<pre>
Line 937 ⟶ 2,159:
29/12/2013 : Sunday
What year (non-positive to quit):0
</pre>
 
=={{header|Free Pascal}}==
 
<syntaxhighlight lang="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.
</syntaxhighlight>
 
{{out}}
<pre>
./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
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight FreeBASIClang="freebasic">' version 23-06-2015
' compile with: fbc -s console
 
Line 949 ⟶ 2,229:
 
Function leapyear(Year_ As Integer) As Integer
' from the leapyeatleapyear entry
If (Year_ Mod 4) <> 0 Then Return FALSE
If (Year_ Mod 100) = 0 AndAlso (Year_ Mod 400) <> 0 Then Return FALSE
Line 1,024 ⟶ 2,304:
 
Loop
End</langsyntaxhighlight>
{{out}}
<pre>For what year do you want to find the last Sunday of the month
any number below 1800 stops program, year in YYYY format? 20152017
 
Last Sunday of the month for 20152017
2529 January
2226 February
2926 March
2630 April
3128 May
2825 June
2630 July
3027 August
2724 September
2529 October
2926 November
2731 December</pre>
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">d = parseDate[ARGS@0]
for m = 1 to 12
{
d = beginningOfNextMonth[d]
n = d - parseInt[d -> ### u ###] days
println[n->###yyyy-MM-dd###]
}</syntaxhighlight>
 
{{out}}
<pre>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
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Last_day_of_each_month_of_a_year%2C_being_a_given_weekday}}
 
'''Solution'''
 
The following function retrieves the last day of each month of a year, being a given weekday:
 
[[File:Fōrmulæ - Last day of each month of a year, being a given weekday 01.png]]
 
'''Test case'''
 
[[File:Fōrmulæ - Last day of each month of a year, being a given weekday 02.png]]
 
[[File:Fōrmulæ - Last day of each month of a year, being a given weekday 03.png]]
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
Long y, c, d, i
 
void local fn sunday( m as Short, nd as Short)
if d > nd then d -= 7 // Don't overshoot
print y @"–"m @"–"d
d = d + 35 - nd // Advance 5 weeks minus month length
end fn
 
void local fn month( m as Short )
select m
case 1
if ( y mod 4 > 0 ) or ( y mod 100 == 0 and y mod 400 > 0 )
fn sunday( m, 31)
fn sunday( m + 1, 28)
else
d += 1 // Extra day for leap year
fn sunday( m, 31 )
fn sunday( m + 1, 29 )
end if
case 3, 5, 7, 8, 10, 12
fn sunday( m, 31 )
case 4, 6, 9, 11
fn sunday( m, 30 )
end select
end fn
 
y = 2024
// Concentrate from D. Knuth: CACM 1962;5:209
c = y / 100 + 1
d = ( 3 * c / 4 ) - ( 5 * y / 4 )
d = ( d mod 7 ) + 36 // A Sunday in February
for i = 1 to 12
fn month( i )
next
 
handleevents
</syntaxhighlight>
Output:
<pre>
2024-1-28
2024-2-25
2024-3-31
2024-4-28
2024-5-26
2024-6-30
2024-7-28
2024-8-25
2024-9-29
2024-10-27
2024-11-24
2024-12-29
</pre>
 
=={{header|Gambas}}==
<syntaxhighlight lang="gambas">Public Sub Form_Open()
Dim sYear As String 'To store the year chosen
Dim siDay, siMonth, siWeekday As Short 'Day, Month and Weekday
 
sYear = InputBox("Input year", "Last Sunday of each month") 'Get the user to enter a year
Print "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
Next
Next
 
End</syntaxhighlight>
Output:
<pre>
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
</pre>
 
=={{header|Go}}==
Line 1,047 ⟶ 2,460:
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.
 
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,093 ⟶ 2,506:
}
}
</syntaxhighlight>
</lang>
 
<pre>
Line 1,115 ⟶ 2,528:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">enum Day {
Sun, Mon, Tue, Wed, Thu, Fri, Sat
static Day valueOf(Date d) { Day.valueOf(d.format('EEE')) }
Line 1,130 ⟶ 2,543:
!months[monthStr] ? months + [(monthStr):sunday] : months
}.values().sort()
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">def ymd = { it.format('yyyy-MM-dd') }
def lastSundays = lastWeekDays.curry(Day.Sun)
lastSundays(args[0] as int).each { println (ymd(it)) }</langsyntaxhighlight>
 
Execution (Cygwin on Windows 7):
Line 1,153 ⟶ 2,566:
2013-11-24
2013-12-29</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">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 -> Day
mostRecentWeekday dayOfWeek date =
fromJust
(find p ((`addDays` date) <$> [-6 .. 0]))
where
p x =
let (_, _, day) = toWeekDate x
in dayOfWeek == day</syntaxhighlight>
{{Out}}
<pre>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</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
Line 1,158 ⟶ 2,627:
This is a trivial adaptation of the solution to the "Last Friday of each month" task
and works in both languages:
<langsyntaxhighlight lang="unicon">procedure main(A)
every write(lastsundays(!A))
end
Line 1,177 ⟶ 2,646:
end
link datetime, printf</langsyntaxhighlight>
 
Sample run:
Line 1,211 ⟶ 2,680:
=={{header|J}}==
Same solution as for [[Last_Friday_of_each_month#J]]
<langsyntaxhighlight lang="j">require'dates'
last_sundays=: 12 {. [: ({:/.~ }:"1)@(#~ 0 = weekday)@todate (i.366) + todayno@,&1 1</langsyntaxhighlight>
 
Example use:
<langsyntaxhighlight lang="j"> last_sundays 2013
2013 1 27
2013 2 24
Line 1,227 ⟶ 2,696:
2013 10 27
2013 11 24
2013 12 29</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.Scanner;
 
public class LastSunday
Line 1,301 ⟶ 2,770:
s.close();
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,322 ⟶ 2,791:
</pre>
===Java 8===
<langsyntaxhighlight Javalang="java">import java.time.*;
import java.util.stream.*;
import static java.time.temporal.TemporalAdjusters.*;
Line 1,350 ⟶ 2,819:
}
 
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
===ES5===
<lang javascript>function lastSundayOfEachMonths(year) {
====Iteration====
var lastDay = [31,28,31,30,31,30,31,31,30,31,30,31]
<syntaxhighlight lang="javascript">function lastSundayOfEachMonths(year) {
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) lastDay[2] = 29
var lastDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for (var date = new Date(), month=0; month<12; month+=1) {
var sundays = [];
date.setFullYear(year, month, lastDay[month])
var date, month;
date.setDate(date.getDate()-date.getDay())
if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
document.write(date.toISOString().substring(0,10), '<br>')
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'));</langsyntaxhighlight>
{{output}}
<pre>2013-01-27
Line 1,377 ⟶ 2,853:
2013-11-24
2013-12-29</pre>
 
====Functional composition====
<syntaxhighlight lang="javascript">(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');
 
})();</syntaxhighlight>
 
{{Out}}
<pre>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</pre>
 
===ES6===
<syntaxhighlight lang="javascript">(() => {
'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();
})();</syntaxhighlight>
{{Out}}
<pre>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</pre>
 
=={{header|jq}}==
{{works with|jq|1.4}}
'''Foundations'''
<langsyntaxhighlight lang="jq"># In case your jq does not have "until" defined:
def until(cond; next):
def _until:
Line 1,406 ⟶ 3,092:
| if iso == "iso" or iso == "ISO" then 1 + ((. + 5) % 7)
else . % 7
end ;</langsyntaxhighlight>
'''findLastSundays'''
<langsyntaxhighlight lang="jq"># year and month are numbered conventionally
def findLastSunday(year; month):
def isLeapYear:
Line 1,430 ⟶ 3,116:
 
$year|tonumber|findLastSundays
</syntaxhighlight>
</lang>
'''Example:'''
<langsyntaxhighlight lang="sh">$ jq --arg year 2013 -n -r -f findLastSundays.jq
YEAR: 2013
January 27
Line 1,445 ⟶ 3,131:
October 27
November 24
December 29</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang Julia>
isdefined(:Date) || using Dates
 
Line 1,474 ⟶ 3,160:
end
end
</syntaxhighlight>
</lang>
 
This code uses the <code>Dates</code> module, which is being incorporated into Julian's standard library with the current development version (<tt>0.4</tt>). I've used <code>isdefined</code> to make this code good for the current stable version (<tt>0.3</tt>) as well as for future releases. If <code>Dates</code> is not installed on your instance of Julian try <code>Pkg.add("Dates")</code> from the <tt>REPL</tt>.
Line 1,502 ⟶ 3,188:
 
Year>
</pre>
 
=={{header|K}}==
<syntaxhighlight lang="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}
 
</syntaxhighlight>
The output of a session with the above script is given below:
{{out}}
<pre>
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")
 
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// 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)
}
}
}</syntaxhighlight>
Sample input/output:
{{out}}
<pre>
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
</pre>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">local(
year = integer(web_request -> param('year') || 2013),
date = date(#year + '-1-1'),
Line 1,525 ⟶ 3,291:
}
}
#lastsu -> join('<br />')</langsyntaxhighlight>
<pre>27 January
24 February
Line 1,538 ⟶ 3,304:
24 November
29 December</pre>
 
=={{header|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.
<syntaxhighlight lang="lb">
yyyy=2013: if yyyy<1901 or yyyy>2099 then end
nda$="Lsu"
print "The last Sundays of "; yyyy
for 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 select
next mm
end
 
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 if
end 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 select
end function
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|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).
<langsyntaxhighlight LiveCodelang="livecode">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
Line 1,563 ⟶ 3,430:
sort mydays ascending numeric
return mydays
end lastDay</langsyntaxhighlight>Example<syntaxhighlight lang LiveCode="livecode">put lastDay(2013, 1)</langsyntaxhighlight>Output<pre>1 27
2 24
3 31
Line 1,575 ⟶ 3,442:
11 24
12 29</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function isLeapYear (y)
return (y % 4 == 0 and y % 100 ~=0) or y % 400 == 0
end
 
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)
end
end
 
lastWeekdays("Sunday", tonumber(arg[1]))</syntaxhighlight>
Command line session:
<pre>>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
 
></pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="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);</syntaxhighlight>
{{Out|Output}}
<pre>
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
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">LastSundays[year_] :=
Table[Last@
DayRange[{year, i},
DatePlus[{year, i}, {{1, "Month"}, {-1, "Day"}}], Sunday], {i,
12}]
LastSundays[2013]</langsyntaxhighlight>
{{out}}
<pre>{{2013, 1, 27}, {2013, 2, 24}, {2013, 3, 31}, {2013, 4, 28}, {2013, 5,
Line 1,589 ⟶ 3,529:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import times, 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 timeinfo = getLocalTime getTime()
var lastDay = DaysInMonth[month]
timeinfo.year = paramStr(1).parseInt
for if month in== mJanmFeb ..and mDecyear.isLeapYear: lastDay = 29
var date = initDateTime(lastDay, month, year, 0, 0, 0)
timeinfo.month = month
date = date - days(DayDiffs[date.weekday])
for day in countdown(31, 1):
echo date.format("yyyy-MM-dd")</syntaxhighlight>
timeinfo.monthday = day
let t = getLocalTime(timeInfoToTime timeinfo)
if t.month == month and t.weekday == dSun:
echo t.format "yyyy-MM-dd"
break</lang>
Sample usage:
<pre>./lastsunday 2013
Line 1,617 ⟶ 3,559:
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">
<lang OCaml>
let is_leap_year y =
(* See OCaml solution on Rosetta Code for
Line 1,659 ⟶ 3,601:
2 -> print_last_sundays( int_of_string (Sys.argv.(1)));
|_ -> invalid_arg "Please enter a year";
</syntaxhighlight>
</lang>
Sample usage:
<pre> ocaml sundays.ml 2013
Line 1,676 ⟶ 3,618:
 
=={{header|Oforth}}==
<langsyntaxhighlight Oforthlang="oforth">import: date
 
: lastSunday(y)
Line 1,683 ⟶ 3,625:
Date newDate(y, m, Date.DaysInMonth(y, m))
while(dup dayOfWeek Date.SUNDAY <>) [ addDays(-1) ] println
] ;</langsyntaxhighlight>
 
{{out}}
Line 1,699 ⟶ 3,641:
2013-11-24 00:00:00,000
2013-12-29 00:00:00,000
</pre>
 
=={{header|PARI/GP}}==
 
<syntaxhighlight lang="parigp">\\ Normalized Julian Day Number from date
njd(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 Number
njdate(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)))</syntaxhighlight>
 
Output:<pre>
[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]
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl
use strict ;
use warnings ;
Line 1,715 ⟶ 3,700:
my $ymd = $date->ymd ;
print "$ymd\n" ;
}</langsyntaxhighlight>
{{out}}
<pre>2013-01-27
Line 1,731 ⟶ 3,716:
</pre>
 
=={{header|Perl 6Phix}}==
Requires 0.8.1 (day_of_week() is now ISO 8601 compliant)
{{works with|rakudo|2015-09-10}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Perl6>sub MAIN ($year = Date.new.year) {
<span style="color: #008080;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
for 1..12 -> $mo {
my $month-end = Date.new($year, $mo, Date.days-in-month($year, $mo));
<span style="color: #008080;">constant</span> <span style="color: #000000;">SUNDAY</span><span style="color: #0000FF;">=</span><span style="color: #000000;">7</span>
say $month-end - $month-end.day-of-week % 7;
}
<span style="color: #008080;">procedure</span> <span style="color: #000000;">showlast</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">dow</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">doy</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">timedate</span> <span style="color: #000000;">td</span><span style="color: #0000FF;">)</span>
}</lang>
<span style="color: #000000;">td</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">adjust_timedate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">td</span><span style="color: #0000FF;">,</span><span style="color: #000000;">timedelta</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">:=</span><span style="color: #000000;">doy</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">day</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">td</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">day_of_week</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">day</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">dow</span> <span style="color: #008080;">do</span> <span style="color: #000000;">day</span><span style="color: #0000FF;">-=</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4d-%02d-%02d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">day</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">last_day_of_month</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">dow</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">doy</span>
<span style="color: #000000;">timedate</span> <span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
<span style="color: #000080;font-style:italic;">-- start by finding the 1st of the next month, less 1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">11</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">doy</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">day_of_year</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">showlast</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dow</span><span style="color: #0000FF;">,</span><span style="color: #000000;">doy</span><span style="color: #0000FF;">,</span><span style="color: #000000;">first</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- do December separately, as 1st would be next year</span>
<span style="color: #000000;">doy</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">day_of_year</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">31</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showlast</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dow</span><span style="color: #0000FF;">,</span><span style="color: #000000;">doy</span><span style="color: #0000FF;">,</span><span style="color: #000000;">first</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">last_day_of_month</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2013</span><span style="color: #0000FF;">,</span><span style="color: #000000;">SUNDAY</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>2015-01-25
2013-01-27
2015-02-22
2013-02-24
2015-03-29
2013-03-31
2015-04-26
2013-04-28
2015-05-31
2013-05-26
2015-06-28
2013-06-30
2015-07-26
2013-07-28
2015-08-30
2013-08-25
2015-09-27
2013-09-29
2015-10-25
2013-10-27
2015-11-29
2013-11-24
2015-12-27</pre>
2013-12-29
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight PHPlang="php"><?php
// Created with PHP 7.0
 
Line 1,769 ⟶ 3,776:
 
printLastSundayOfAllMonth($argv[1]);
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,786 ⟶ 3,793:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de lastSundays (Y)
(for M 12
(prinl
Line 1,792 ⟶ 3,799:
(find '((D) (= "Sunday" (day D)))
(mapcar '((D) (date Y M D)) `(range 31 22)) )
"-" ) ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">: (lastSundays 2013)
2013-01-27
2013-02-24
Line 1,806 ⟶ 3,813:
2013-10-27
2013-11-24
2013-12-29</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function last-dayofweek {
param(
Line 1,823 ⟶ 3,830:
}
last-dayofweek 2013 "Sunday"
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 1,840 ⟶ 3,847:
</pre>
 
===Alternate Version===
=={{header|Python}}==
This script finds the first and/or last or all dates of any of the days of week; accepts <code>[Int32]</code> and <code>[DateTime]</code> values for Month and Year parameters; outputs <code>[DateTime]</code> 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.
<lang python>
This script has a syntax as complex as any PowerShell Cmdlet because it attempts to do everything.
#!/usr/bin/python3
<syntaxhighlight lang="powershell">
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,
Output:
Position=1)]
2013-Jan-27
[ValidateRange(1,9999)]
2013-Feb-24
2013-Mar-31 [int]
$Year = (Get-Date).Year,
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
'''
 
[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
}
}
}
}
</syntaxhighlight>
The default is to return <code>[DateTime]</code> objects:
<syntaxhighlight lang="powershell">
1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday
</syntaxhighlight>
{{Out}}
<pre>
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
</pre>
Return the <code>[DateTime]</code> objects as strings (using the default string format):
<syntaxhighlight lang="powershell">
1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday -AsString
</syntaxhighlight>
{{Out}}
<pre>
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
</pre>
Return the <code>[DateTime]</code> objects as strings (specifying the string format):
<syntaxhighlight lang="powershell">
1..12 | Get-Date0fDayOfWeek -Year 2013 -Last -Sunday -AsString -Format yyyy-MM-dd
</syntaxhighlight>
{{Out}}
<pre>
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
</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="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
Next
EndProcedure
 
NewList lf.i()
Define y.i
OpenConsole("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()))
Next
EndIf
Print("...End")
Input()</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">
import sys
import calendar
 
year = 2013
YEAR = sys.argv[-1]
if len(sys.argv) > 1:
try:
try:
year = int(YEAR)
year = int(sys.argv[-1])
except:
yearexcept = 2013ValueError:
YEAR = str(year) pass
 
for month in range(1, 13):
c = calendar.Calendar(firstweekday = 0) # Sunday is day 6.
last_sunday = max(week[-1] for week in calendar.monthcalendar(year, month))
print('{}-{}-{:2}'.format(year, calendar.month_abbr[month], last_sunday))
</syntaxhighlight>
 
<b>Output</b>:
result = []
<syntaxhighlight lang="text">
for month in range(0+1,12+1):
2013-Jan-27
MON = calendar.month_abbr[month]
2013-Feb-24
# list of weeks of tuples has too much structure
2013-Mar-31
# Use the overloaded list.__add__ operator to remove the week structure.
2013-Apr-28
flatter = sum(c.monthdays2calendar(year, month), [])
2013-May-26
# make a dictionary keyed by number of day of week,
2013-Jun-30
# successively overwriting values.
2013-Jul-28
SUNDAY = {b: a for (a, b) in flatter if a}[6]
2013-Aug-25
result.append('{}-{}-{:2}'.format(YEAR, MON, SUNDAY))
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29
</syntaxhighlight>
 
=={{header|QuickBASIC 4.5}}==
print('\n'.join(result))
QuickBASIC 4.5 doesn't have a way to manage dates easily. Following you'll see my solution for this task in QuickBASIC/QBASIC
</lang>
<syntaxhighlight lang="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.
 
' Var
DIM iWY AS INTEGER
DIM A AS STRING
DIM iWM AS INTEGER
DIM iWD AS INTEGER
DIM strF AS STRING
 
' SUBs and FUNCTIONs
DECLARE FUNCTION LastSundayOfMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER)
DECLARE FUNCTION FirstDayOfWeekOnMonth% (WhichMonth AS INTEGER, WhichYear AS INTEGER)
 
' Gets the year from the command line
iWY = 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 iWM
ELSE
PRINT "Incorrect year."
PRINT "Usage: LASTSQB1 Year"
PRINT
PRINT "Where Year is a value between 1753 and 2078."
END IF
PRINT
PRINT "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 = iDoW
END 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
</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
==={{header|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.
<syntaxhighlight lang="qbasic">
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.
 
' Var
DIM iWY AS INTEGER
DIM A AS STRING
DIM iWM AS INTEGER
DIM iWD AS INTEGER
 
' SUBs and FUNCTIONs
DECLARE FUNCTION LastSundayOfMonth (WhichMonth AS INTEGER, WhichYear AS INTEGER) AS INTEGER
 
' Initialize
iWY = 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 iWM
ELSE
PRINT "Incorrect year. Please, specify a value between 1753 and 2078."
END IF
 
PRINT
PRINT "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 = iLSoM
END FUNCTION
</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ over 3 < if [ 1 - ]
dup 4 / over +
over 100 / -
swap 400 / +
swap 1 -
[ table
0 3 2 5 0 3
5 1 4 6 2 4 ]
+ + 7 mod ] is dayofweek ( day month year --> weekday )
 
[ 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</syntaxhighlight>
 
{{out}}
 
<pre>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</pre>
 
=={{header|R}}==
<syntaxhighlight lang="rsplus">
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)
</syntaxhighlight>
{{out}}
<pre>
[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"
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require srfi/19 math)
Line 1,929 ⟶ 4,455:
(for ([d (last-sundays 2013)])
(displayln (~a (date->string d "~a ~d ~b ~Y"))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,945 ⟶ 4,471:
Sun 29 Dec 2013
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
{{works with|rakudo|2018.03}}
<syntaxhighlight lang="raku" line>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;
}
}</syntaxhighlight>
 
{{out|input=2018}}
<pre>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</pre>
 
=={{header|REBOL}}==
<langsyntaxhighlight REBOLlang="rebol">#!/usr/bin/env rebol
 
last-sundays-of-year: function [
Line 1,963 ⟶ 4,514:
 
foreach sunday last-sundays-of-year to-integer system/script/args [print sunday]
</syntaxhighlight>
</lang>
{{out}}
<pre>./last-sundays.reb 2013
Line 1,985 ⟶ 4,536:
except for the innards of the first '''DO''' loop. <br><br>
The &nbsp; '''lastDOW''' &nbsp; subroutine can be used for any day-of-the-week for any month for any year.
<langsyntaxhighlight lang="rexx">/*REXX program displays dates of last Sundays of each month for any year*/
parse arg yyyy
do j=1 for 12
Line 2,063 ⟶ 4,614:
.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. */</langsyntaxhighlight>
{{out}}|output|text=&nbsp; when using the default input &nbsp; (the current year, &nbsp; 2013):}}
<pre>
<pre style="overflow:scroll">
2013-01-27
2013-02-24
Line 2,078 ⟶ 4,629:
2013-11-24
2013-12-29
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
see "What year to calculate (yyyy) : "
give year
see "Last Sundays in " + year + " are on :" + nl
month = 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 ok
m = ((year-1900)%7) + floor(leap/4) % 7
for n = 1 to 12
month[n] = (mo[n] + m) % 7
next
for 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
next
next
</syntaxhighlight>
Output:
<pre>
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
</pre>
 
=={{header|RPL}}==
<code>WKDAY</code> is defined at [[Day of the week#RPL|Day of the week]]
{{works with|HP|48}}
≪ → year
≪ { }
.02 .13 '''FOR''' month
1 month .13 == DUP .01 month IFTE SWAP year + 1000000 / + + <span style="color:grey">@ Generate 1st day of the following month</span>
DUP <span style="color:blue">WKDAY</span> NEG DATE+ +
.01 '''STEP'''
2 FIX <span style="color:grey">@ Display October Sunday as ##.10 and not as ##.1</span>
≫ ≫ '<span style="color:blue">LSTSU</span>' STO
 
2013 <span style="color:blue">LSTSU</span>
{{out}}
<pre>
1: { 27.01 24.02 24.03 28.04 26.05 30.06 28.07 25.08 29.09 27.10 24.11 29.12 }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'date'
 
def last_sundays_of_year(year = Date.today.year)
Line 2,090 ⟶ 4,698:
end
 
puts last_sundays_of_year(2013)</langsyntaxhighlight>
 
{{out}}
Line 2,108 ⟶ 4,716:
</pre>
Results before the year 1581 may differ from other languages - the Date library takes the Julian reform into account.
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">input "What year to calculate (yyyy) : ";year
print "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 - 1904
m = ((year-1900) mod 7) + int(leap/4) mod 7
for n = 1 to 12
month(n) = (val(word$(mo$,n)) + m) mod 7
month(n) = (val(word$(mo$,n)) + m) mod 7
next
for 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
next
next</syntaxhighlight>
<pre>
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</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="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);
});
}</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|S-BASIC}}==
<syntaxhighlight lang="basic">
rem - return p mod q
function mod(p, q = integer) = integer
end = p - q * (p/q)
 
comment
return day of week (Sun = 0, Mon = 1, etc.) for a
given Gregorian calendar date using Zeller's congruence
end
function dayofweek (mo, da, yr = integer) = integer
var y, c, z = integer
if mo < 3 then
begin
mo = mo + 10
yr = yr - 1
end
else mo = mo - 2
y = mod(yr,100)
c = int(yr / 100)
z = int((26 * mo - 2) / 10)
z = z + da + y + int(y/4) + int(c/4) - 2 * c + 777
z = mod(z,7)
end = z
 
rem - return true if y is a leap year
function isleap(y = integer) = integer
end = mod(y,4)=0 and mod(y,100)<>0 or mod(y,400)=0
 
rem - return number of days in specified month
function 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 = 31
end = 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 year
end
function 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 name
function shortmonth (m = integer) = string
end = mid("JanFebMarAprMayJunJulAugSepOctNovDec", m*3-2, 3)
 
rem - main program starts here
 
$constant SUNDAY = 0
var m, y = integer
input "Display last Sundays in what year"; y
for m = 1 to 12
print shortmonth(m);" ";lastkday(SUNDAY, m, y)
next m
end</syntaxhighlight>
{{out}}
<pre>
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</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object FindTheLastSundayOfEachMonth extends App {
import java.util.Calendar._
val cal = getInstance
Line 2,124 ⟶ 4,887:
val fmt = new java.text.SimpleDateFormat("yyyy-MM-dd")
println(lastSundaysOf(year).map(fmt.format) mkString "\n")
}</langsyntaxhighlight>
===Java 8===
<langsyntaxhighlight Scalalang="scala">object FindTheLastSundayOfEachMonth extends App {
def lastSundaysOf(year: Int) = (1 to 12).map{month =>
import java.time._; import java.time.temporal.TemporalAdjusters._
Line 2,133 ⟶ 4,896:
val year = args.headOption.map(_.toInt).getOrElse(java.time.LocalDate.now.getYear)
println(lastSundaysOf(year) mkString "\n")
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 2,140 ⟶ 4,903:
Applicable to any day of the week, cf. [[http://rosettacode.org/wiki/Last_Friday_of_each_month#Seed7]].
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "time.s7i";
include "duration.s7i";
Line 2,169 ⟶ 4,932:
end for;
end if;
end func;</langsyntaxhighlight>
 
{{out}} when called with <tt>s7 rosetta/lastWeekdayInMonth 7 2013</tt>:
Line 2,188 ⟶ 4,951:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">var dt = require('DateTime');
var (year=20152016) = @ARGV.map{.to_i};...
 
for i in (1 .. 12) {
Line 2,202 ⟶ 4,965:
 
say date.ymd;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,218 ⟶ 4,981:
2013-11-24
2013-12-29
</pre>
 
=={{header|Smalltalk}}==
<syntaxhighlight lang="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 ] ] ]
</syntaxhighlight>
{{out}}
<pre>
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)
</pre>
 
=={{header|Stata}}==
<syntaxhighlight lang="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 |
+-----------+</syntaxhighlight>
 
=={{header|Swift}}==
<syntaxhighlight lang="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"))</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc lastSundays {{year ""}} {
if {$year eq ""} {
set year [clock format [clock seconds] -gmt 1 -format "%Y"]
Line 2,234 ⟶ 5,092:
return $result
}
puts [join [lastSundays {*}$argv] "\n"]</langsyntaxhighlight>
{{out}}
When called as: “<code>tclsh lastSundays.tcl 2013</code>” (or with the year argument omitted during 2013)
Line 2,251 ⟶ 5,109:
2013-12-29
</pre>
 
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
 
This uses the programs awk and cal, which are usually installed on any POSIXlike system.
 
<syntaxhighlight lang="sh">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
}</syntaxhighlight>
 
{{Out}}
<pre>$ 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</pre>
 
=={{header|VBScript}}==
{{works with|Windows Script Host|*}}
<syntaxhighlight lang="vbscript">
<lang VBScript>
strYear = WScript.StdIn.ReadLine
 
Line 2,261 ⟶ 5,146:
WScript.Echo d - Weekday(d) + 1
Next
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
{{libheader|Wren-date}}
<syntaxhighlight lang="wren">import "os" for Process
import "./date" for Date
var args = Process.arguments
if (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.isoDate
for (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))
}
}</syntaxhighlight>
 
{{out}}
<pre>
$ wren Find_the_last_Sunday_of_each_month.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 Find_the_last_Sunday_of_each_month.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
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="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 line
for 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);
];
]</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|zkl}}==
1,983

edits