Last Friday of each month: Difference between revisions

Added Easylang
(Added Easylang)
 
(89 intermediate revisions by 44 users not shown)
Line 3:
 
;Task:
Write a program or a script that returns the date of the last Fridays 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).
Line 30:
* [[Find the last Sunday of each month]]
<br><br>
 
=={{header|360 Assembly}}==
The program uses one ASSIST macro (XPRNT) to keep the code as short as possible.
<syntaxhighlight lang="360asm">* Last Friday of each month 17/07/2016
LASTFRI CSECT
USING LASTFRI,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,44 44
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=44+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'2016' <== 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 LASTFRI</syntaxhighlight>
{{out}}
<pre>
2016-01-29
2016-02-26
2016-03-25
2016-04-29
2016-05-27
2016-06-24
2016-07-29
2016-08-26
2016-09-30
2016-10-28
2016-11-25
2016-12-30
</pre>
 
=={{header|Action!}}==
<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)=5 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/Last_Friday_of_each_month.png Screenshot from Atari 8-bit computer]
<pre>
Input year in range 1753...9999: 2021
2021-01-29
2021-02-26
2021-03-26
2021-04-30
2021-05-28
2021-06-25
2021-07-30
2021-08-27
2021-09-24
2021-10-29
2021-11-26
2021-12-31
</pre>
 
=={{header|Ada}}==
Line 35 ⟶ 216:
Uses GNAT. Applicable to any day of the week, cf. [[http://rosettacode.org/wiki/Find_last_sunday_of_each_month#Ada]].
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, GNAT.Calendar.Time_IO, Ada.Command_Line,
Ada.Calendar.Formatting, Ada.Calendar.Arithmetic;
 
Line 64 ⟶ 245:
Put_Line(Selected);
end loop;
end Last_Weekday_In_Month;</langsyntaxhighlight>
{{out}}
<pre>>./last_weekday_in_month friday 2012
Line 80 ⟶ 261:
2012-12-28</pre>
 
=={{header|ALGOL 68}}==
Basically the same as the "Find the Last Sunday Of Each Month" task solution.
{{Trans|ALGOL W}}
<syntaxhighlight lang="algol68">BEGIN # find the last Friday 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 Friday of each month in year #
PROC last fridays = ( 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 Friday #
[ 1 : 12 ]INT last;
FOR m pos TO 12 DO
INT dow := day of week( last days[ m pos ], m pos, year );
# dow = 1 Sun, 2 Mon, ... , 6 Fri, 0 Sat #
# change to 2 Sun, 3 Mon, ... , 0 Fri, 1 Sat #
dow := ( dow + 1 ) MOD 7;
# offset the last day to the last Friday #
last[ m pos ] := last days[ m pos ] - dow
OD;
last
END # last fridays # ;
# test the last fridays procedure #
INT year = 2021;
[]INT last = last fridays( 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-29
2021-02-26
2021-03-26
2021-04-30
2021-05-28
2021-06-25
2021-07-30
2021-08-27
2021-09-24
2021-10-29
2021-11-26
2021-12-31
</pre>
 
=={{Headerheader|AppleScriptALGOL W}}==
Basically the same as the "Find the Last Sunday Of Each Month" task solution, uses the Day_of_week and isLeapYear procedures from the the day-of-the-week and leap-year tasks (included here for convenience).
<syntaxhighlight lang="algolw">begin % find the last Friday 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, Friday = 6, Saturday = 0 %
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 Friday %
% of each month in year %
procedure lastFridays ( 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 Friday %
for mPos := 1 until 12 do begin
integer dow;
dow := Day_of_week( lastDays( mPos ), mPos, year );
% dow = 1 Sun, 2 Mon, ... , 6 Fri, 0 Sat %
% change to 2 Sun, 3 Mon, ... , 0 Fri, 1 Sat %
dow := ( dow + 1 ) rem 7;
% offset the last day to the last Friday %
last( mPos ) := lastDays( mPos ) - dow
end for_mPos
end lastFridays ;
begin
% test the lastFridays procedure %
integer array last ( 1 :: 12 );
integer year;
year := 2020;
lastFridays( 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-31
2020-02-28
2020-03-27
2020-04-24
2020-05-29
2020-06-26
2020-07-31
2020-08-28
2020-09-25
2020-10-30
2020-11-27
2020-12-25
</pre>
 
=={{header|AppleScript}}==
 
{{Trans|JavaScript}}
<syntaxhighlight lang="applescript">-- LAST FRIDAYS OF YEAR ------------------------------------------------------
 
-- lastFridaysOfYear :: Int -> [Date]
on lastFridaysOfYear(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, Friday as integer)
end lastFridaysOfYear
 
 
<lang AppleScript>on run argv
-- TEST ----------------------------------------------------------------------
on run argv
intercalate(linefeed, ¬
Line 92 ⟶ 456:
transpose(map(lastFridaysOfYear, ¬
apply(cond(class of argv is list and argv ≠ {}, ¬
singleYearOrRange, fiveCurrentYears), argIntegers(argv))))))¬
argIntegers(argv))))))
end run
 
 
-- ARGUMENT HANDLING
-- 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)
-- from two years ago, to two years ahead)
 
-- ~ $ osascript ~/Desktop/lastFridays.scpt
Line 107 ⟶ 474:
-- singleYearOrRange :: [Int] -> [Int]
on singleYearOrRange(argv)
apply(cond(length of argv > 0, my rangeenumFromTo, my fiveCurrentYears), argv)
end singleYearOrRange
 
Line 113 ⟶ 480:
on fiveCurrentYears(_)
set intThisYear to year of (current date)
rangeenumFromTo({intThisYear - 2, intThisYear + 2})
end fiveCurrentYears
 
-- argIntegers :: maybe [String] -> [Int]
on argIntegers(argv)
-- parseInt :: String -> Int
script parseInt
on |λ|(s)
s as integer
end |λ|
end script
if class of argv is list and argv ≠ {} then
{map(my parseInt, argv)}
else
{}
Line 126 ⟶ 500:
 
 
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- DERIVATION OF LAST FRIDAYS
 
-- lastFridaysOfYear :: Int -> [Date]
on lastFridaysOfYear(y)
lastWeekDaysOfYear(y, Friday as integer)
end lastFridaysOfYear
 
 
-- lastWeekDaysOfYear :: Int -> Int -> [Date]
on lastWeekDaysOfYear(intYear, iWeekday)
map(mclosure(my lastWeekDay, ¬
{intYear:intYear, iWeekday:iWeekday}), my lastDaysOfMonths(intYear))
end lastWeekDaysOfYear
 
 
-- lastWeekDay :: Int -> Int -> Date
on lastWeekDay(iLastDay, iMonth)
set iYear to intYear of my closure
calendarDate(iYear, iMonth, iLastDay - ¬
(((weekday of calendarDate(iYear, iMonth, iLastDay)) as integer) + ¬
(7 - (iWeekday of my closure))) mod 7)
end lastWeekDay
 
 
-- lastDaysOfMonths :: Int -> [Int]
on lastDaysOfMonths(y)
{31, cond(isLeapYear(y), 29, 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
end lastDaysOfMonths
 
-- isLeapYear :: Int -> Bool
on isLeapYear(y)
(0 = y mod 4) and (0 ≠ y mod 100) or (0 = y mod 400)
end isLeapYear
 
 
 
 
-- GENERIC FUNCTIONS
 
-- Dates and date strings ----------------------------------------------------
 
-- calendarDate :: Int -> Int -> Int -> Date
Line 186 ⟶ 522:
end isoDateString
 
-- Testing and tabulation ----------------------------------------------------
-- parseInt :: String -> Int
on parseInt(s)
s as integer
end parseInt
 
-- apply (a -> b) -> a -> b
-- Testing and tabulation
on apply(f, a)
mReturn(f)'s |λ|(a)
end apply
 
-- transposecond :: [[Bool -> (a]] -> [[b) -> (a]] -> b) -> (a -> b)
on transposecond(xssbool, f, g)
scriptif mfbool then
on lambdaCol(_, iCol)f
else
map(mclosure(my closure's mf's lambdaRow, ¬
g
{iCol:iCol}), my closure's xss)
end lambdaColif
end cond
 
on lambdaRow(row)
-- enumFromTo :: Int -> Int -> [Int]
item (my closure's iCol) of row
on enumFromTo(m, n)
end lambdaRow
endif scriptm > n then
set d to -1
map(mclosure(mf's lambdaCol, {xss:xss, mf:mf}), item 1 of xss)
else
end transpose
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
Line 221 ⟶ 565:
intercalate(tab, map(my isoDateString, lstDate))
end isoRow
 
-- range :: (Int, Int) -> [Int]
on range(tuple)
if tuple = {} then return {}
if length of tuple > 1 then
set {m, n} to tuple
else
return item 1 of tuple
end if
set lng to (n - m) + 1
set base to m - 1
set lst to {}
repeat with i from 1 to lng
set end of lst to i + base
end repeat
return lst
end range
 
-- Higher-order functions
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
set mf totell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to lambda|λ|(item i of xs, i, xs) of mf
end repeat
return lst
end tell
end map
 
Line 255 ⟶ 581:
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then return f
script
property lambda : f
end script
end mReturn
 
-- Handler -> Record -> Script
on mclosure(f, recBindings)
script
property closure : recBindings
property lambda : f
end script
end mclosure
 
-- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)
on cond(bool, f, g)
if bool then
f
else
gscript
property |λ| : f
end script
end if
end condmReturn
 
-- apply (a -> b) -> a -> b
on apply(f, a)
mReturn(f)'s lambda(a)
end apply
 
</lang>
 
 
-- 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>2014-01-31 2015-01-30 2016-01-29 2017-01-27 2018-01-26
2014-02-28 2015-02-27 2016-02-26 2017-02-24 2018-02-23
Line 300 ⟶ 619:
2014-11-28 2015-11-27 2016-11-25 2017-11-24 2018-11-30
2014-12-26 2015-12-25 2016-12-30 2017-12-29 2018-12-28</pre>
 
----
 
A 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 lastFridayOfEachMonthInYear(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_fridays " & 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 Friday 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 lastFridayOfThisMonth to firstDayOfNextMonth - (1 + (firstDayOfNextMonth's weekday) mod 7) * days
-- Append the required details to the output text.
set {month:m, day:d} to lastFridayOfThisMonth
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 lastFridayOfEachMonthInYear
 
lastFridayOfEachMonthInYear(2020)</syntaxhighlight>
 
{{Out}}
<pre>"./last_fridays 2020
2020-01-31
2020-02-28
2020-03-27
2020-04-24
2020-05-29
2020-06-26
2020-07-31
2020-08-28
2020-09-25
2020-10-30
2020-11-27
2020-12-25"</pre>
 
The above is of course hard-coded for Fridays. It can be made more flexible by taking an AppleScript weekday constant as a parameter:
 
<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(Friday, 2020)</syntaxhighlight>
{{Out}}
<pre>"./last_Fridays 2020
2020-01-31
2020-02-28
2020-03-27
2020-04-24
2020-05-29
2020-06-26
2020-07-31
2020-08-28
2020-09-25
2020-10-30
2020-11-27
2020-12-25"</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">lastFridayForMonth: function [m][
ensure -> in? m 1..12
 
daysOfMonth: [0 31 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" ~"2012-|m|-|d|"
if dt\Day = "Friday" -> return dt
]
]
loop 1..12 'month [
print to :string.format:"yyyy-MM-dd" lastFridayForMonth month
]</syntaxhighlight>
 
{{out}}
 
<pre>2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AHKlang="ahk">if 1 = ; no parameter passed
{
InputBox, 1, Last Fridays of year, Enter a year:, , , , , , , , %A_YYYY%
Line 330 ⟶ 767:
stmp += 1, days
}
MsgBox % res</langsyntaxhighlight>
{{out}} for 2012:
<pre>2012-01-27
Line 347 ⟶ 784:
=={{header|AutoIt}}==
 
<syntaxhighlight lang="autoit">
<lang AutoIt>
#include <Date.au3>
 
Line 370 ⟶ 807:
ConsoleWrite($sResult)
EndFunc ;==>_GetFridays
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 390 ⟶ 827:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f LAST_FRIDAY_OF_EACH_MONTH.AWK year
# converted from Fortran
Line 408 ⟶ 845:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 424 ⟶ 861:
2012-12-28
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "DATELIB"
 
INPUT "What year to calculate (YYYY)? " Year%
 
PRINT '"Last Fridays in ";Year% " are on:"
FOR Month%=1 TO 12
PRINT Year% "-" RIGHT$("0" + STR$Month%, 2) "-"; \
\ FN_dim(Month%, Year%) - (FN_dow(FN_mjd(FN_dim(Month%, Year%), Month%, Year%)) + 2) MOD 7
NEXT</syntaxhighlight>
{{out}}
<pre>What year to calculate (YYYY)? 2023
 
Last Fridays in 2023 are on:
2023-01-27
2023-02-24
2023-03-31
2023-04-28
2023-05-26
2023-06-30
2023-07-28
2023-08-25
2023-09-29
2023-10-27
2023-11-24
2023-12-29</pre>
 
=={{header|Befunge}}==
Line 429 ⟶ 894:
The algorithm has been slightly simplified to avoid the additional day adjustment inside the loop, and the year is obtained from stdin rather than via the command line.
 
<langsyntaxhighlight lang="befunge">":raeY",,,,,&>55+,:::45*:*%\"d"%!*\4%+!3v
v2++1**"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 455 ⟶ 920:
Doesn't work with Julian calendar (then again, you probably don't need to plan your weekends for middle ages).
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 474 ⟶ 939:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Globalization;
Line 514 ⟶ 979:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>01/27/2012
Line 532 ⟶ 997:
{{libheader|Boost}}
called with <code>./last_fridays 2012</code>
<langsyntaxhighlight lang="cpp">#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>
#include <cstdlib>
Line 548 ⟶ 1,013:
}
return 0 ;
}</langsyntaxhighlight>
{{out}}
<pre>2012-Jan-27
Line 562 ⟶ 1,027:
2012-Nov-30
2012-Dec-28
</pre>
===Using C++20===
Using C++20 this task can be completed without external libraries.
<syntaxhighlight lang="c++">
 
#include <chrono>
#include <iostream>
 
int main() {
std::cout << "The dates of the last Friday in each month of 2023:" << std::endl;
 
for ( unsigned int m = 1; m <= 12; ++m ) {
std::chrono::days days_in_month = std::chrono::sys_days{std::chrono::year{2023}/m/std::chrono::last}
- 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};
std::chrono::year_month_day ymd{std::chrono::year{2023}, std::chrono::month{m}, std::chrono::day{last_day}};
 
while ( std::chrono::weekday{ymd} != std::chrono::Friday ) {
ymd = std::chrono::sys_days{ymd} - std::chrono::days{1};
}
 
std::cout << ymd << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
The dates of the last Friday in each month of 2023:
2023-01-27
2023-02-24
2023-03-31
2023-04-28
2023-05-26
2023-06-30
2023-07-28
2023-08-25
2023-09-29
2023-10-27
2023-11-24
2023-12-29
</pre>
 
Line 567 ⟶ 1,073:
{{libheader|clj-time}}
 
<langsyntaxhighlight lang="clojure">(use '[clj-time.core :only [last-day-of-the-month day-of-week minus days]]
'[clj-time.format :only [unparse formatters]])
 
Line 577 ⟶ 1,083:
 
(defn last-fridays-formatted [year]
(sort (map #(unparse (formatters :year-month-day) %) (last-fridays year))))</langsyntaxhighlight>
 
{{out}}
Line 595 ⟶ 1,101:
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol">
<lang COBOL>
program-id. last-fri.
data division.
Line 644 ⟶ 1,150:
.
end program last-fri.
</syntaxhighlight>
</lang>
 
{{out}}
Line 663 ⟶ 1,169:
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
last_friday_of_month = (year, month) ->
# month is 1-based, JS API is 0-based, then we use
Line 682 ⟶ 1,188:
year = parseInt process.argv[2]
print_last_fridays_of_month year
</syntaxhighlight>
</lang>
{{out}}
<syntaxhighlight lang="text">
> coffee last_friday.coffee 2012
Fri Jan 27 2012
Line 698 ⟶ 1,204:
Fri Nov 30 2012
Fri Dec 28 2012
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 704 ⟶ 1,210:
The command-line argument processing is the only CLISP-specific code.
 
<langsyntaxhighlight lang="lisp">(defun friday-before (year month day)
(let*
((timestamp (encode-universal-time 0 0 12 day month year))
Line 717 ⟶ 1,223:
 
(let* ((year (read-from-string (car *args*))))
(format t "~{~{~a-~2,'0d-~2,'0d~}~%~}" (last-fridays year)))</langsyntaxhighlight>
 
Sample run for the year 2015:
Line 735 ⟶ 1,241:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.datetime, std.traits;
 
void lastFridays(in uint year) {
Line 749 ⟶ 1,255:
void main() {
lastFridays(2012);
}</langsyntaxhighlight>
<pre>2012-Jan-27
2012-Feb-24
Line 762 ⟶ 1,268:
2012-Nov-30
2012-Dec-28</pre>
 
=={{header|Delphi}}==
Uses the standard Delphi library.
<syntaxhighlight lang="delphi">program LastFridayOfMonth;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils, System.DateUtils;
 
var
Year: Word;
Month: Word;
D1: TDateTime;
D2: Word;
 
begin
Write('Enter year: ');
ReadLn(Year);
 
for Month := MonthJanuary to MonthDecember do begin
D1 := EndOfAMonth(Year, Month);
D2 := DayOfTheWeek(D1);
while D2 <> DayFriday do begin
D1 := IncDay(D1, -1);
D2 := DayOfTheWeek(D1);
end;
WriteLn(DateToStr(D1));
end;
end.</syntaxhighlight>
{{out}}
<pre>Enter year: 2019
25.01.2019
22.02.2019
29.03.2019
26.04.2019
31.05.2019
28.06.2019
26.07.2019
30.08.2019
27.09.2019
25.10.2019
29.11.2019
27.12.2019</pre>
 
=={{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_fridays year . .
for m to 12
d = mdays[m]
if m = 2 and leap year = 1
d = 29
.
d -= (weekday year m d - 6) mod 7
m$ = m
if m < 10
m$ = "0" & m
.
print year & "-" & m$ & "-" & d
.
.
last_fridays 2023
</syntaxhighlight>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule RC do
def lastFriday(year) do
Enum.map(1..12, fn month ->
Line 778 ⟶ 1,365:
Enum.each(RC.lastFriday(y), fn {year, month, day} ->
:io.format "~4b-~2..0w-~2..0w~n", [year, month, day]
end)</langsyntaxhighlight>
 
{{out}}
Line 795 ⟶ 1,382:
2012-12-28
</pre>
 
=={{header|Elm}}==
<langsyntaxhighlight lang="elm">import Html exposing (Html, Attribute, text, div, input)
import Html.App exposing (beginnerProgram)
import Html.Attributes exposing (placeholder, value, style)
Line 862 ⟶ 1,450:
, view = view
, update = update
}</langsyntaxhighlight>
Link to live demo: http://dc25.github.io/lastFridayOfMonthElm/
 
Line 880 ⟶ 1,468:
December 26, 2003
</pre>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">(require 'calendar)
 
(defun last-friday (year)
"Print the last Friday 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))
(lastfriday (1+ (cl-position 5 weekdays :from-end t))))
(insert (format "%i-%02i-%02i \n" year month lastfriday))))
(number-sequence 1 12)))
 
(last-friday 2012)</syntaxhighlight>
{{output}}
<pre>2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28 </pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( last_date_each_month ).
 
Line 901 ⟶ 1,518:
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].
</syntaxhighlight>
</lang>
{{out}}
<pre>
32> [io:fwrite("~B-~2.10.0B-~B~n", [Y,M,D]) || {Y,M,D} <- last_date_each_month:friday(2012)].
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
</pre>
 
=={{header|Factor}}==
{{works with|Factor|0.98}}
The <code>last-friday-of-month</code> word in the <code>calendar</code> vocabulary does most of the work. This program expects the year as a command line argument.
<syntaxhighlight lang="factor">USING: calendar calendar.format command-line io kernel math.parser sequences ;
IN: rosetta-code.last-fridays
 
(command-line) second string>number <year> 12 <iota>
[ months time+ last-friday-of-month ] with map
[ timestamp>ymd print ] each</syntaxhighlight>
{{out}}
<pre>
>factor last-fridays.factor 2012
2012-01-27
2012-02-24
Line 922 ⟶ 1,565:
 
Algorithm: compute day of week for last day of month, then subtract just enough to get to the preceding friday. Do this for each month. To simplify computations further, we only need to compute day of week of january 1st (the others are found by adding month lengths). Since day of week need only be known modulo 7, we do not compute modulo at all except once when subtracting.
<langsyntaxhighlight lang="fortran">program fridays
implicit none
integer :: days(1:12) = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/)
Line 935 ⟶ 1,578:
end do
end program
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight FreeBasiclang="freebasic">' version 23-06-2015
' compile with: fbc -s console
 
Line 947 ⟶ 1,590:
 
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,022 ⟶ 1,665:
 
Loop
End</langsyntaxhighlight>
{{out}}
<pre>For what year do you want to find the last Friday of the month
any number below 1800 stops program, year in YYYY format? 20152017
 
Last Friday of the month for 20152017
3027 January
2724 February
2731 March
2428 April
2926 May
2630 June
3128 July
2825 August
2529 September
3027 October
2724 November
2529 December</pre>
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">d = parseDate[ARGS@0]
for m = 1 to 12
{
d = beginningOfNextMonth[d]
n = d - (((parseInt[d -> ### u ###] + 1) mod 7) + 1) days
println[n -> ### yyyy-MM-dd ###]
}</syntaxhighlight>
 
{{out}}
<pre>2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
</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 04.png]]
 
[[File:Fōrmulæ - Last day of each month of a year, being a given weekday 05.png]]
 
=={{header|Gambas}}==
<syntaxhighlight lang="gambas">Public Sub Form_Open()
Dim siYear As Short = InputBox("Please input a year", "Last Friday of each month")
Dim siMonth, siDay As Short
Dim dDay As Date
 
For siMonth = 1 To 12
For siDay = 31 DownTo 22
Try dDay = Date(siYear, siMonth, siDay)
If Error Then Continue
If WeekDay(dDay) = 5 Then
Print Format(dDay, "yyyy-mm-dd");;
Print Space(6) & Format(dDay, "dddd dd mmmm yyyy")
Break
End If
Next
Next
 
Me.Close
 
End</syntaxhighlight>
Output:
<pre>
1925-01-30 Friday 30 January 1925
1925-02-27 Friday 27 February 1925
1925-03-27 Friday 27 March 1925
1925-04-24 Friday 24 April 1925
1925-05-29 Friday 29 May 1925
1925-06-26 Friday 26 June 1925
1925-07-31 Friday 31 July 1925
1925-08-28 Friday 28 August 1925
1925-09-25 Friday 25 September 1925
1925-10-30 Friday 30 October 1925
1925-11-27 Friday 27 November 1925
1925-12-25 Friday 25 December 1925
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,063 ⟶ 1,783:
fmt.Println(d.Format("2006-01-02"))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,085 ⟶ 1,805:
 
Test:
<langsyntaxhighlight lang="groovy">def ymd = { it.format('yyyy-MM-dd') }
def lastFridays = lastWeekDays.curry(Day.Fri)
lastFridays(args[0] as int).each { println (ymd(it)) }</langsyntaxhighlight>
 
Execution (Cygwin on Windows 7):
Line 1,107 ⟶ 1,827:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.Time.Calendar
(Day, addDays, showGregorian, fromGregorian, gregorianMonthLength)
import Data.Time.Calendar.WeekDate
import Data.Time.Calendar.WeekDate (toWeekDate)
import Data.List (transpose, intercalate)
 
-- [1 .. 7] for [Mon .. Sun]
findFriday date = head $ filter isFriday $ map toDate [-6 .. 0]
findWeekDay :: Int -> Day -> Day
where
findWeekDay dayOfWeek date =
toDate ago = addDays ago date
head
isFriday theDate = let (_ , _ , day) = toWeekDate theDate
(filter
in day == 5
(\x ->
let (_, _, day) = toWeekDate x
in day == dayOfWeek)
((`addDays` date) <$> [-6 .. 0]))
 
weekDayDates :: Int -> Integer -> [String]
fridayDates year = map (showGregorian . findFriday) lastDaysInMonth
weekDayDates dayOfWeek year =
where
((showGregorian . findWeekDay dayOfWeek) .
lastDaysInMonth = map findLastDay [1 .. 12]
findLastDay month = (fromGregorian year month<*> (gregorianMonthLength year)) month)<$>
[1 .. 12]
 
main =:: doIO ()
main =
putStrLn "Please enter a year!"
mapM_
year <- getLine
mapM_ putStrLn $ fridayDates (read year)</lang>
(intercalate " " <$> transpose (weekDayDates 5 <$> [2012 .. 2017]))</syntaxhighlight>
{{out}}
{{Out}}
<pre>Please enter a year!
<pre>2012-01-27 2013-01-25 2014-01-31 2015-01-30 2016-01-29 2017-01-27
2012
2012-02-24 2013-02-22 2014-02-28 2015-02-27 2016-02-26 2017-02-24
2012-01-27
2012-03-30 2013-03-29 2014-03-28 2015-03-27 2016-03-25 2017-03-31
2012-02-24
2012-04-27 2013-04-26 2014-04-25 2015-04-24 2016-04-29 2017-04-28
2012-03-30
2012-05-25 2013-05-31 2014-05-30 2015-05-29 2016-05-27 2017-05-26
2012-04-27
2012-06-29 2013-06-28 2014-06-27 2015-06-26 2016-06-24 2017-06-30
2012-05-25
2012-07-27 2013-07-26 2014-07-25 2015-07-31 2016-07-29 2017-07-28
2012-06-29
2012-08-31 2013-08-30 2014-08-29 2015-08-28 2016-08-26 2017-08-25
2012-07-27
2012-09-28 2013-09-27 2014-09-26 2015-09-25 2016-09-30 2017-09-29
2012-08-31
2012-10-26 2013-10-25 2014-10-31 2015-10-30 2016-10-28 2017-10-27
2012-09-28
2012-11-30 2013-11-29 2014-11-28 2015-11-27 2016-11-25 2017-11-24
2012-10-26
2012-12-28 2013-12-27 2014-12-26 2015-12-25 2016-12-30 2017-12-29</pre>
2012-11-30
2012-12-28</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
This will write the last fridays for every year given as an argument. There is no error checking on the year.
<langsyntaxhighlight Iconlang="icon">procedure main(A)
every write(lastfridays(!A))
end
Line 1,162 ⟶ 1,888:
end
 
link datetime, printf</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 1,185 ⟶ 1,911:
=={{header|J}}==
 
<langsyntaxhighlight lang="j">require 'dates'
last_fridays=: 12 {. [: ({:/.~ }:"1)@(#~ 5 = weekday)@todate (i.366) + todayno@,&1 1</langsyntaxhighlight>
 
In other words, start from January 1 of the given year, and count forward for 366 days, keeping the Fridays. Then pick the last remaining day within each represented month (which will be a Friday because we only kept the Fridays). Then pick the first 12 (since on a non-leap year which ends on a Thursday we would get an extra Friday).
Line 1,192 ⟶ 1,918:
Example use:
 
<langsyntaxhighlight lang="j"> last_fridays 2012
2012 1 27
2012 2 24
Line 1,204 ⟶ 1,930:
2012 10 26
2012 11 30
2012 12 28</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.text.*;
import java.util.*;
 
Line 1,233 ⟶ 1,959:
}
}
}</langsyntaxhighlight>
{{out}} (for <code>java LastFridays 2012</code>):
<pre>2012 Jan 27
Line 1,248 ⟶ 1,974:
2012 Dec 28</pre>
 
=={{header|JavaScript}}==
 
==JavaScript=ES5===
====Iteration====
 
===Imperative===
 
{{works with|Nodejs}}
<syntaxhighlight lang="javascript">var last_friday_of_month, print_last_fridays_of_month;
<lang javascript>
var last_friday_of_month, print_last_fridays_of_month;
 
last_friday_of_month = function(year, month) {
Line 1,282 ⟶ 2,005:
year = parseInt(process.argv[2]);
return print_last_fridays_of_month(year);
})();</syntaxhighlight>
{{Out}}
 
<pre>>node lastfriday.js 2015
</lang>
{{out}}
<lang>
>node lastfriday.js 2015
Fri Jan 30 2015
Fri Feb 27 2015
Line 1,299 ⟶ 2,019:
Fri Oct 30 2015
Fri Nov 27 2015
Fri Dec 25 2015</pre>
</lang>
 
====Functional composition====
 
<syntaxhighlight lang="javascript">(function () {
===Functional (ES 5)===
 
<lang JavaScript>(function () {
'use strict';
 
Line 1,330 ⟶ 2,047:
});
}
 
 
 
 
// isoDateString :: Date -> String
Line 1,368 ⟶ 2,082:
 
// TEST
 
return transpose(
range(2012, 2016)
Line 1,379 ⟶ 2,092:
})
.join('\n');
})();</syntaxhighlight>
 
})();</lang>
 
{{Out}}
Line 1,395 ⟶ 2,107:
2012-11-30 2013-11-29 2014-11-28 2015-11-27 2016-11-25
2012-12-28 2013-12-27 2014-12-26 2015-12-25 2016-12-30</pre>
 
===ES6===
<syntaxhighlight lang="javascript">(() => {
"use strict";
 
// ------------ LAST FRIDAY OF EACH MONTH ------------
 
// lastWeekDaysOfYear :: Int -> Int -> [Date]
const lastWeekDaysOfYear = iWeekDay =>
y => {
const isLeap = n => (
(0 === n % 4) && (0 !== n % 100)) || (
0 === y % 400
);
 
return [
31, isLeap(y) ? 29 : 28,
31, 30, 31, 30, 31, 31, 30, 31, 30, 31
]
.map((d, m) =>
new Date(Date.UTC(
y, m, d - ((
new Date(Date.UTC(
y, m, d
))
.getDay() + (7 - iWeekDay)
) % 7)
))
);
};
 
 
const days = {
sunday: 0,
monday: 1,
tuesday: 2,
wednesday: 3,
thursday: 4,
friday: 5,
saturday: 6
};
 
// ---------------------- TEST -----------------------
const main = () =>
transpose(
enumFromTo(2015)(2019)
.map(lastWeekDaysOfYear(days.friday))
)
.map(
row => row.map(isoDateString).join("\t")
)
.join("\n");
 
 
// ---------------- GENERIC FUNCTIONS ----------------
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
 
 
// isoDateString :: Date -> String
const isoDateString = dte =>
dte.toISOString()
.substr(0, 10);
 
 
// transpose :: [[a]] -> [[a]]
const transpose = rows =>
// The columns of the input transposed
// into new rows.
0 < rows.length ? rows[0].map(
(x, i) => rows.flatMap(
v => v[i]
)
) : [];
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>2015-01-30 2016-01-29 2017-01-27 2018-01-26 2019-01-25
2015-02-27 2016-02-26 2017-02-24 2018-02-23 2019-02-22
2015-03-27 2016-03-25 2017-03-31 2018-03-30 2019-03-29
2015-04-24 2016-04-29 2017-04-28 2018-04-27 2019-04-26
2015-05-29 2016-05-27 2017-05-26 2018-05-25 2019-05-31
2015-06-26 2016-06-24 2017-06-30 2018-06-29 2019-06-28
2015-07-31 2016-07-29 2017-07-28 2018-07-27 2019-07-26
2015-08-28 2016-08-26 2017-08-25 2018-08-31 2019-08-30
2015-09-25 2016-09-30 2017-09-29 2018-09-28 2019-09-27
2015-10-30 2016-10-28 2017-10-27 2018-10-26 2019-10-25
2015-11-27 2016-11-25 2017-11-24 2018-11-30 2019-11-29
2015-12-25 2016-12-30 2017-12-29 2018-12-28 2019-12-27</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):
Line 1,425 ⟶ 2,232:
| if iso == "iso" or iso == "ISO" then 1 + ((. + 5) % 7)
else . % 7
end ;</langsyntaxhighlight>
'''findLastFridays'''
<langsyntaxhighlight lang="jq"># year and month are numbered conventionally
def findLastFriday(year; month):
def isLeapYear:
Line 1,448 ⟶ 2,255:
(range(0;12) | "\(months[.]) \(findLastFriday($year; .+1))") ;
 
$year|tonumber|findLastFridays</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq --arg year 2012 -n -r -f findLastFridays.jq
YEAR: 2012
January 27
Line 1,463 ⟶ 2,270:
October 26
November 30
December 28</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Dates
<lang Julia>
isdefined(:Date) || using Dates
 
const wday = Dates.Fri
Line 1,492 ⟶ 2,298:
end
end
</syntaxhighlight>{{out}}
</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>.
 
{{out}}
<pre>
This script will print the last Fridays of each month of the year given.
Line 1,520 ⟶ 2,322:
 
Year>
</pre>
 
=={{header|K}}==
<syntaxhighlight lang="k">
/ List the dates of last Fridays of each month of
/ a given year
/ lastfridt.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)}
lfd: {[m;y]; wdme[m;y];:[mewd>3;jd::jd+(4-mewd);jd::jd-(3+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))}
lfd1: {[y];arr::(); m:1; do[12;lfd[m;y];m+:1]}
main: {[y]; lfd1[y];`0: ,"Dates of last Fridays of ",($y);12 10#arr}
 
</syntaxhighlight>
The output of a session is given below:
 
{{out}}
<pre>
K Console - Enter \ for help
 
\l lastfridt
main 2012
Dates of last Fridays of 2012
("2012- 1-27"
"2012- 2-24"
"2012- 3-30"
"2012- 4-27"
"2012- 5-25"
"2012- 6-29"
"2012- 7-27"
"2012- 8-31"
"2012- 9-28"
"2012-10-26"
"2012-11-30"
"2012-12-28")
 
</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 Fridays 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)
var offset = calendar[Calendar.DAY_OF_WEEK] - Calendar.FRIDAY
if (offset < 0) offset += 7
val lastFriday = daysInMonth - offset
println("$year-" + "%02d-".format(month) + "%02d".format(lastFriday))
if (month < 12) {
calendar.add(Calendar.DAY_OF_MONTH, 1)
calendar.add(Calendar.MONTH, 1)
calendar.add(Calendar.DAY_OF_MONTH, -1)
}
}
}</syntaxhighlight>
 
{{out}}
<pre>
Enter a year : 2012
The last Fridays of each month in 2012 are as follows:
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
</pre>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">define isLeapYear(y::integer) => {
#y % 400 == 0 ? return true
#y % 100 == 0 ? return false
Line 1,546 ⟶ 2,431:
with f in fridays(2012) do => {^
#f->format('%Q') + '\r'
^}</langsyntaxhighlight>
 
{{out}}
Line 1,561 ⟶ 2,446:
2012-11-30
2012-12-28</pre>
 
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">function lastFriday yyyy
-- 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,586 ⟶ 2,470:
sort fridays ascending numeric
return fridays
end lastFriday</langsyntaxhighlight>
Example<langsyntaxhighlight LiveCodelang="livecode">put lastFriday("2012")</langsyntaxhighlight>Output<langsyntaxhighlight LiveCodelang="livecode">1 27
2 24
3 30
Line 1,598 ⟶ 2,482:
10 26
11 30
12 28</langsyntaxhighlight>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">; Determine if a Gregorian calendar year is leap
to leap? :year
output (and
Line 1,645 ⟶ 2,529:
print reduce [(word ?1 "- ?2)] (list :year :month :day)
]
bye</langsyntaxhighlight>
 
{{out}}
Line 1,663 ⟶ 2,547:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function isLeapYear (y)
return (y % 4 == 0 and y % 100 ~=0) or y % 400 == 0
end
Line 1,682 ⟶ 2,566:
end
 
lastWeekdays("Friday", tonumber(arg[1]))</langsyntaxhighlight>
Command line session:
<pre>>lua lastFridays.lua 2012
Line 1,700 ⟶ 2,584:
></pre>
 
=={{header|MathematicaM2000 Interpreter}}==
 
<lang Mathematica>FridaysOfYear[Y_] :=
<syntaxhighlight lang="m2000 interpreter">
module lastfriday {
string year
integer y%
input "Year (e.g. 2023):", y%
year=str$(y%,"")
date a="1/1/"+year
date a1="31/12/"+year
double i, b=a, c=a1
for i=b to b+6
if val(date$(i, 1033, "d"))=6 then exit for
next
document result$="Last Friday per month for year " + year + {:
}
for i=i+7 to c step 7
if val(date$(i, 1033, "M")) <>val(date$(i+7, 1033, "M")) then
result$=date$(i, 1033, "M"+chr$(9)+"dd") + {
}
end if
next
report result$
clipboard result$
}
lastfriday
</syntaxhighlight>
 
{{out}}
<pre>
Year (e.g. 2023):2023
Last Friday per month for year 2023:
1 27
2 24
3 31
4 28
5 26
6 30
7 28
8 25
9 29
10 27
11 24
12 29
 
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">fridays := 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) = 6) then
change := -(Calendar:-DayOfWeek(dt) mod 7)-1;
end if;
dt := Calendar:-AdjustDateField(dt, "date", change);
printf("%d-%d-%d\n", year, Month(dt), DayOfMonth(dt));
end do;
end proc;
 
fridays(2012);</syntaxhighlight>
{{Out|Output}}
<pre>2012-1-27
2012-2-24
2012-3-30
2012-4-27
2012-5-25
2012-6-29
2012-7-27
2012-8-31
2012-9-28
2012-10-26
2012-11-30
2012-12-28</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">FridaysOfYear[Y_] :=
NestWhile[(DaysPlus[#, - 1]) &, #, (DateString[#, "DayName"] != "Friday") &] & /@
Most@Reverse@NestList [DaysPlus[# /. {x_, y_, X_} -> {x, y, 1}, - 1] &, {Y + 1, 1, 1}, 12]
Column@FridaysOfYear[2012]</langsyntaxhighlight>
{{out}}
<pre>{2012,1,27}
Line 1,721 ⟶ 2,686:
=={{header|MATLAB}} / {{header|Octave}}==
 
<langsyntaxhighlight Matlablang="matlab"> function t = last_fridays_of_year(y)
t1 = datenum([y,1,1,0,0,0]);
t2 = datenum([y,12,31,0,0,0]);
Line 1,730 ⟶ 2,695:
 
datestr(last_fridays_of_year(2012),'yyyy-mm-dd')
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,748 ⟶ 2,713:
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">weekday(year, month, day) := block([m: month, y: year, k],
if m < 3 then (m: m + 12, y: y - 1),
k: 1 + remainder(day + quotient((m + 1)*26, 10) + y + quotient(y, 4)
Line 1,767 ⟶ 2,732:
lastfridays(2012);
["2012-1-27", "2012-2-24", "2012-3-30", "2012-4-27", "2012-5-25", "2012-6-29",
"2012-7-27","2012-8-31", "2012-9-28", "2012-10-26", "2012-11-30", "2012-12-28"]</langsyntaxhighlight>
 
=={{header|Nanoquery}}==
<syntaxhighlight lang="nanoquery">import Nanoquery.Util
// a function to check if a year is a leap year
def isLeapYear(year)
if (year % 100 = 0)
return (year % 400 = 0)
else
return (year % 4 = 0)
end
end
// a function to format 1-digit numbers as "0x"
def form(num)
if (num > 9)
return str(num)
else
return "0" + str(num)
end
end
// get a year from the console
print "enter year: "
year = int(input())
// build a list of the expected amount of days for each month
days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if isLeapYear($year)
days[1] = 29
end
// loop through each month
for month in range(1, len($days))
// loop through each day of the month
friday = null
for day in range(1, days[month - 1])
// create a date object for this date
date = new(Date)
date.setYear(year).setMonth(month).setDay(day)
// check if it's a friday
if (date.getDayOfWeek() = "Friday")
// if it is, keep it
friday = new(Date, date)
end
end for
// display the last friday found
print friday.getYear() + "-"
print form(friday.getMonth()) + "-"
println form(friday.getDay())
end</syntaxhighlight>
 
=={{header|NetRexx}}==
Line 1,773 ⟶ 2,791:
{{trans|C}}
Implements the algorithms from both the [[#Java|Java]] and [[#C|C]] implementations.
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
 
Line 1,849 ⟶ 2,867:
end
return
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,884 ⟶ 2,902:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import times, os, strutils, times
 
const
var timeinfo = getLocalTime getTime()
DaysInMonth: array[Month, int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
timeinfo.year = paramStr(1).parseInt
DayDiffs: array[WeekDay, int] = [3, 4, 5, 6, 0, 1, 2]
for month in mJan .. mDec:
 
timeinfo.month = month
let year = paramStr(1).parseInt
for day in countdown(31, 1):
 
timeinfo.monthday = day
for month in mJan..mDec:
let t = getLocalTime(timeInfoToTime timeinfo)
var lastDay = DaysInMonth[month]
if t.month == month and t.weekday == dFri:
if month == mFeb and year.isLeapYear: lastDay = 29
echo t.format "yyyy-MM-dd"
var date = initDateTime(lastDay, month, year, 0, 0, 0)
break</lang>
date = date - days(DayDiffs[date.weekday])
Sample usage:
echo date.format("yyyy-MM-dd")</syntaxhighlight>
<pre>./lastfriday 2012
 
{{out}}
Sample usage: ./lastfridays 2012
<pre>
2012-01-27
2012-02-24
Line 1,915 ⟶ 2,937:
Using the module [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html Unix] from the standard OCaml library:
 
<langsyntaxhighlight lang="ocaml">#load "unix.cma"
open Unix
 
Line 1,950 ⟶ 2,972:
done;
done;
Array.iter print_date fridays</langsyntaxhighlight>
 
{{out}}
Line 1,970 ⟶ 2,992:
{{libheader|OCaml Calendar Library}}
 
<langsyntaxhighlight lang="ocaml">open CalendarLib
 
let usage() =
Line 1,994 ⟶ 3,016:
aux num_days
done;
List.iter print_date (List.rev !fridays)</langsyntaxhighlight>
 
Run this script with the command:
 
ocaml unix.cma str.cma -I +calendar calendarLib.cma last_fridays.ml 2012
 
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">import: date
 
: lastFridays(y)
Line 2,011 ⟶ 3,032:
while(dup dayOfWeek Date.FRIDAY <>) [ addDays(-1) ]
println
] ;</langsyntaxhighlight>
 
{{out}}
Line 2,031 ⟶ 3,052:
=={{header|PARI/GP}}==
 
<langsyntaxhighlight lang="parigp">\\ Normalized Julian Day Number from date
njd(D) =
{
Line 2,057 ⟶ 3,078:
}
 
for (m=1, 12, a=njd([2012,m+1,0]); print(njdate(a-(a+1)%7)))</langsyntaxhighlight>
 
Output:<pre>
Line 2,072 ⟶ 3,093:
[2012, 11, 30]
[2012, 12, 28]</pre>
 
=={{header|Pascal}}==
{{works with|Free Pascal}}
Using Free Pascal's DateUtils library would dramatically simplify the coding (see the Delphi example) but for older Pascal implementations the needed routines are the programmer's responsibility.
<syntaxhighlight lang="pascal">
program LastFriday;
 
{$mode objfpc}{$H+}
 
uses
SysUtils;
 
type
weekdays = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
 
var
m, d, y : integer;
 
function IsLeapYear(Year : integer) : boolean;
begin
if Year mod 4 <> 0 { quick exit in most likely case }
then IsLeapYear := false
else if Year mod 400 = 0
then IsLeapYear := true
else if Year mod 100 = 0
then IsLeapYear := false
else { non-century year and divisible by 4 }
IsLeapYear := true;
end;
 
 
function DaysInMonth(Month, Year : integer) : integer;
const
LastDay : array[1..12] of integer =
(31,28,31,30,31,30,31,31,30,31,30,31);
begin
if (Month = 2) and (IsLeapYear(Year)) then
DaysInMonth := 29
else
DaysInMonth := LastDay[Month];
end;
 
{ return day of week (Sun = 0, Mon = 1, etc.) for a }
{ given mo, da, and yr using Zeller's congruence }
function DayOfWeek(mo, da, yr : integer) : weekdays;
var
y, c, z : integer;
begin
if mo < 3 then
begin
mo := mo + 10;
yr := yr - 1
end
else mo := mo - 2;
y := yr mod 100;
c := yr div 100;
z := (26 * mo - 2) div 10;
z := z + da + y + (y div 4) + (c div 4) - 2 * c + 777;
DayOfWeek := weekdays(z mod 7);
end;
 
{ return the calendar day of the last occurrence of the }
{ specified weekday in the given month and year }
function LastWeekday(k : weekdays; m, y : integer) : integer;
var
d : integer;
w : weekdays;
begin
{ determine weekday for the last day of the month }
d := DaysInMonth(m, y);
w := DayOfWeek(m, d, y);
{ back up as needed to desired weekday }
if w >= k then
LastWeekday := d - (ord(w) - ord(k))
else
LastWeekday := d - (7 - ord(k)) - ord(w);
end;
 
 
begin { main program }
write('Find last Fridays in what year? ');
readln(y);
writeln;
writeln('Month Last Fri');
for m := 1 to 12 do
begin
d := LastWeekday(Fri, m, y);
writeln(m:5,' ',d:5);
end;
end.
</syntaxhighlight>
{{out}}
<pre>
Find last Fridays in what year? 2020
Month Last Fri
1 31
2 28
3 27
4 24
5 29
6 26
7 31
8 28
9 25
10 30
11 27
12 25
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl -w
use strict ;
use DateTime ;
Line 2,085 ⟶ 3,214:
}
say $dt->ymd ;
}</langsyntaxhighlight>
{{out}}
<pre>2012-01-27
Line 2,100 ⟶ 3,229:
2012-12-28
</pre>
 
=={{header|Perl 6}}==
<lang perl6>sub MAIN (Int $year = Date.today.year) {
my @fri;
for Date.new("$year-01-01") .. Date.new("$year-12-31") {
@fri[.month] = .Str if .day-of-week == 5;
}
.say for @fri[1..12];
}</lang>
 
Example:
<pre>$ ./lastfri 2038
2038-01-29
2038-02-26
2038-03-26
2038-04-30
2038-05-28
2038-06-25
2038-07-30
2038-08-27
2038-09-24
2038-10-29
2038-11-26
2038-12-31</pre>
 
A solution without a result array to store things in:
 
<lang perl6>sub MAIN (Int $year = Date.today.year) {
say ~.value.reverse.first: *.day-of-week == 5
for classify *.month, Date.new("$year-01-01") .. Date.new("$year-12-31");
}</lang>
 
Here, <code>classify</code> sorts the dates into one bin per month (but preserves the order in each bin). We then take the list inside each bin (<code>.value</code>) and find the last (<code>.reverse.first</code>) date which is a Friday.
 
Another variation where the data flow can be read left to right using feed operators:
 
<lang perl6>sub MAIN (Int $year = Date.today.year) {
.say for Date.new("$year-01-01") .. Date.new("$year-12-31") ==> classify *.month ==>
map *.value.reverse.first: *.day-of-week == 5
}</lang>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include timedate.e
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</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;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dow</span><span style="color: #0000FF;">)</span>
constant FRIDAY=6
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">days_in_month</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">),</span>
procedure showlast(integer dow, integer doy, timedate td)
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dow</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">day_of_week</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
td = adjust_timedate(td,timedelta(days:=doy-1))
<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;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">a</span><span style="color: #0000FF;">-</span><span style="color: #000000;">7</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span><span style="color: #0000FF;">)})</span>
integer {year,month,day} = td
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
while day_of_week(year,month,day)!=dow do day-=1 end while
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
printf(1,"%4d-%02d-%02d\n",{year,month,day})
<span style="color: #008080;">constant</span> <span style="color: #000000;">FRIDAY</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span>
end procedure
<span style="color: #000080;font-style:italic;">--prompt_number() is not compatible with pwa/p2js
 
procedure --last_day_of_month(integer yearprompt_number("Year:",{1752,9999}), integer dowFRIDAY)</span>
<span style="color: #000000;">last_day_of_month</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2012</span><span style="color: #0000FF;">,</span><span style="color: #000000;">FRIDAY</span><span style="color: #0000FF;">)</span>
integer doy
<!--</syntaxhighlight>-->
timedate first = {year,1,1,0,0,0,0,0}
-- start by finding the 1st of the next month, less 1
for i=1 to 11 do
doy = day_of_year(year,i+1,1)-1
showlast(dow,doy,first)
end for
-- do December separately, as 1st would be next year
doy = day_of_year(year,12,31)
showlast(dow,doy,first)
end procedure
last_day_of_month(2012,FRIDAY)</lang>
{{out}}
<pre>
Line 2,181 ⟶ 3,260:
2012-12-28
</pre>
 
 
=={{header|PHP}}==
PHP is generally used for web apps, so I am not implementing the command-line component of this task.
 
<langsyntaxhighlight PHPlang="php"><?php
function last_friday_of_month($year, $month) {
$day = 0;
Line 2,207 ⟶ 3,285:
$year = 2012;
print_last_fridays_of_month($year);
?></langsyntaxhighlight>
 
{{out}}
Line 2,224 ⟶ 3,302:
2012-12-28
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">% for command line argument
main(ARGV) =>
if ARGV.length > 0 then
Year = ARGV[1].to_integer(),
show_year(Year),
nl
end.
 
% Without command line argument
main => go.
 
go =>
show_year(2022),
nl.
 
% Show the months
show_year(Year) =>
foreach(Date in get_months(Year))
println(format_date(Date))
end,
nl.
 
% Format date to YYYY-DD-MM
format_date(Date) = to_fstring("%4d-%02d-%02d",Date[1],Date[2],Date[3]).
 
 
% Return the last Fridays of each month for year Year
get_months(Year) =
[ [ [Year,Month,Day] : Day in 1..max_days_in_month(Year,Month),
dow(Year, Month, Day) == 5].last() : Month in 1..12].
 
 
% Day of week, Sakamoto's method
dow(Y, M, D) = R =>
T = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4],
if M < 3 then
Y := Y - 1
end,
R = (Y + Y // 4 - Y // 100 + Y // 400 + T[M] + D) mod 7.
 
% Maximum days in month
max_days_in_month(Year,Month) = Days =>
if member(Month, [1,3,5,7,8,10,12]) then
Days = 31
elseif member(Month,[4,6,9,11]) then
Days = 30
else
if leap_year(Year) then
Days = 29
else
Days = 28
end
end.
 
% Is Year a leap year?
leap_year(Year) =>
(Year mod 4 == 0, Year mod 100 != 0)
;
Year mod 400 == 0. </syntaxhighlight>
 
===Running the program===
There are several ways to run this program; let's call it "last_friday_of_each_month.pi":
 
===From Picat's shell===
<pre>$ picat
Picat> cl(last_friday_of_each_month)
Picat> show_year(2022)
2022-01-28
2022-02-25
2022-03-25
2022-04-29
2022-05-27
2022-06-24
2022-07-29
2022-08-26
2022-09-30
2022-10-28
2022-11-25
2022-12-30</pre>
 
===From the command line, year as parameter===
Via <code>main(ARGV)</code>.
<pre>$ picat last_friday_of_each_month.pi 2022</pre>
 
===From the command line, as a goal===
<pre>$ picat -g "show_year(2022)" last_friday_of_each_month.pi</pre>
 
===Run the default goal (go/0))===
<pre>$ picat last_friday_of_each_month.pi</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de lastFridays (Y)
(for M 12
(prinl
Line 2,232 ⟶ 3,401:
(find '((D) (= "Friday" (day D)))
(mapcar '((D) (date Y M D)) `(range 31 22)) )
"-" ) ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">: (lastFridays 2012)
2012-01-27
2012-02-24
Line 2,246 ⟶ 3,415:
2012-10-26
2012-11-30
2012-12-28</langsyntaxhighlight>
 
=={{header|Pike}}==
<langsyntaxhighlight Pikelang="pike">int(0..1) last_friday(object day)
{
return day->week_day() == 5 &&
Line 2,260 ⟶ 3,429:
write("%{%s\n%}", days->format_ymd());
return 0;
}</langsyntaxhighlight>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
Fridays: procedure (year) options (main); /* 8 January 2013 */
declare year character (4) varying;
Line 2,286 ⟶ 3,455:
end;
end Fridays;
</syntaxhighlight>
</lang>
The command: FRIDAYS /2008 produces:
<pre>
Line 2,321 ⟶ 3,490:
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function last-dayofweek {
param(
Line 2,335 ⟶ 3,504:
}
last-dayofweek 2012 "Friday"
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 2,351 ⟶ 3,520:
2012-12-28
</pre>
 
===Alternate Version===
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.
This script has a syntax as complex as any PowerShell Cmdlet because it attempts to do everything.
<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,
Position=1)]
[ValidateRange(1,9999)]
[int]
$Year = (Get-Date).Year,
 
[Parameter(Mandatory=$true, ParameterSetName="Sunday")]
[switch]
$Sunday,
 
[Parameter(Mandatory=$true, ParameterSetName="Monday")]
[switch]
$Monday,
 
[Parameter(Mandatory=$true, ParameterSetName="Tuesday")]
[switch]
$Tuesday,
 
[Parameter(Mandatory=$true, ParameterSetName="Wednesday")]
[switch]
$Wednesday,
 
[Parameter(Mandatory=$true, ParameterSetName="Thursday")]
[switch]
$Thursday,
 
[Parameter(Mandatory=$true, ParameterSetName="Friday")]
[switch]
$Friday,
 
[Parameter(Mandatory=$true, ParameterSetName="Saturday")]
[switch]
$Saturday,
 
[switch]
$First,
 
[switch]
$Last,
 
[switch]
$AsString,
 
[Parameter(Mandatory=$false)]
[ValidateNotNullOrEmpty()]
[string]
$Format = "dd-MMM-yyyy"
)
 
Process
{
[datetime[]]$dates = 1..[DateTime]::DaysInMonth($Year,$Month) | ForEach-Object {
Get-Date -Year $Year -Month $Month -Day $_ -Hour 0 -Minute 0 -Second 0 |
Where-Object -Property DayOfWeek -Match $PSCmdlet.ParameterSetName
}
 
if ($First -or $Last)
{
if ($AsString)
{
if ($First) {$dates[0].ToString($Format)}
if ($Last) {$dates[-1].ToString($Format)}
}
else
{
if ($First) {$dates[0]}
if ($Last) {$dates[-1]}
}
}
else
{
if ($AsString)
{
$dates | ForEach-Object {$_.ToString($Format)}
}
else
{
$dates
}
}
}
}
</syntaxhighlight>
The default is to return <code>[DateTime]</code> objects:
<syntaxhighlight lang="powershell">
1..12 | Get-Date0fDayOfWeek -Year 2012 -Last -Friday
</syntaxhighlight>
{{Out}}
<pre>
Friday, January 27, 2012 12:00:00 AM
Friday, February 24, 2012 12:00:00 AM
Friday, March 30, 2012 12:00:00 AM
Friday, April 27, 2012 12:00:00 AM
Friday, May 25, 2012 12:00:00 AM
Friday, June 29, 2012 12:00:00 AM
Friday, July 27, 2012 12:00:00 AM
Friday, August 31, 2012 12:00:00 AM
Friday, September 28, 2012 12:00:00 AM
Friday, October 26, 2012 12:00:00 AM
Friday, November 30, 2012 12:00:00 AM
Friday, December 28, 2012 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 2012 -Last -Friday -AsString
</syntaxhighlight>
{{Out}}
<pre>
27-Jan-2012
24-Feb-2012
30-Mar-2012
27-Apr-2012
25-May-2012
29-Jun-2012
27-Jul-2012
31-Aug-2012
28-Sep-2012
26-Oct-2012
30-Nov-2012
28-Dec-2012
</pre>
Return the <code>[DateTime]</code> objects as strings (specifying the string format):
<syntaxhighlight lang="powershell">
1..12 | Get-Date0fDayOfWeek -Year 2012 -Last -Friday -AsString -Format yyyy-MM-dd
</syntaxhighlight>
{{Out}}
<pre>
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">Procedure LastFridayOfEachMonth(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)=5
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 Friday of each month")
Print("Input Year [ 1971 < y < 2038 ]: ")
y=Val(Input())
If y>1971 And y<2038
PrintN("Last Friday of each month...")
LastFridayOfEachMonth(y,lf())
ForEach lf()
PrintN(FormatDate("%dd.%mm.%yyyy",lf()))
Next
EndIf
Print("...End")
Input()</syntaxhighlight>
{{out}}
<pre>Input Year [ 1971 < y < 2038 ]: 2017
Last Friday of each month...
27.01.2017
24.02.2017
31.03.2017
28.04.2017
26.05.2017
30.06.2017
28.07.2017
25.08.2017
29.09.2017
27.10.2017
24.11.2017
29.12.2017
...End</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">import calendar
 
def lastFridayslast_fridays(year):
for month in range(1, 13):
last_friday = max(week[calendar.FRIDAY]
for week in calendar.monthcalendar(year, month))
print('{:4d}-{:02d}-{:02d}'.format(year, month, last_friday))</langsyntaxhighlight>
 
{{out}}
<pre>>>> lastFridayslast_fridays(2012)
2012-01-27
2012-02-24
Line 2,376 ⟶ 3,757:
2012-12-28</pre>
Another solution
<langsyntaxhighlight lang="python">import calendar
c=calendar.Calendar()
fridays={}
Line 2,390 ⟶ 3,771:
for item in sorted((month+"-"+day for month,day in fridays.items()),
key=lambda x:int(x.split("-")[1])):
print item</langsyntaxhighlight>
 
Using reduce
 
<langsyntaxhighlight lang="python">import calendar
c=calendar.Calendar()
fridays={}
Line 2,407 ⟶ 3,788:
for item in sorted((month+"-"+day for month,day in fridays.items()),
key=lambda x:int(x.split("-")[1])):
print item</langsyntaxhighlight>
 
using itertools
 
<langsyntaxhighlight lang="python">import calendar
from itertools import chain
f=chain.from_iterable
Line 2,427 ⟶ 3,808:
for item in sorted((month+"-"+day for month,day in fridays.items()),
key=lambda x:int(x.split("-")[1])):
print item</langsyntaxhighlight>
 
=={{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 --> )
 
[ 5 lastwkdays ] is lastfridays ( year --> )
 
2012 lastfridays</syntaxhighlight>
 
{{out}}
 
<pre>2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28</pre>
 
=={{header|R}}==
<langsyntaxhighlight lang="rsplus">year = commandArgs(T)
d = as.Date(paste0(year, "-01-01"))
fridays = d + seq(by = 7,
Line 2,436 ⟶ 3,883:
364 + (months(d + 30 + 29) == "February"))
message(paste(collapse = "\n", fridays[tapply(
seq_along(fridays), as.POSIXlt(fridays)$mon, max)]))</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require srfi/19 math)
Line 2,481 ⟶ 3,928:
(for ([d (last-fridays 2012)])
(displayln (~a (date->string d "~a ~d ~b ~Y"))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,497 ⟶ 3,944:
Fri 28 Dec 2012
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub MAIN (Int $year = Date.today.year) {
my @fri;
for Date.new("$year-01-01") .. Date.new("$year-12-31") {
@fri[.month] = .Str if .day-of-week == 5;
}
.say for @fri[1..12];
}</syntaxhighlight>
 
Example:
<pre>$ ./lastfri 2038
2038-01-29
2038-02-26
2038-03-26
2038-04-30
2038-05-28
2038-06-25
2038-07-30
2038-08-27
2038-09-24
2038-10-29
2038-11-26
2038-12-31</pre>
 
A solution without a result array to store things in:
 
<syntaxhighlight lang="raku" line>sub MAIN (Int $year = Date.today.year) {
say ~.value.reverse.first: *.day-of-week == 5
for classify *.month, Date.new("$year-01-01") .. Date.new("$year-12-31");
}</syntaxhighlight>
 
Here, <code>classify</code> sorts the dates into one bin per month (but preserves the order in each bin). We then take the list inside each bin (<code>.value</code>) and find the last (<code>.reverse.first</code>) date which is a Friday.
 
Another variation where the data flow can be read left to right using feed operators:
 
<syntaxhighlight lang="raku" line>sub MAIN (Int $year = Date.today.year) {
.say for Date.new("$year-01-01") .. Date.new("$year-12-31") ==> classify *.month ==>
map *.value.reverse.first: *.day-of-week == 5
}</syntaxhighlight>
 
=={{header|REBOL}}==
The longer version:
<langsyntaxhighlight REBOLlang="rebol">leap-year?: function [year] [to-logic attempt [to-date reduce [29 2 year]]]
 
days-in-feb: function [year] [either leap-year? year [29] [28]]
Line 2,522 ⟶ 4,010:
year: to-integer input
repeat month 12 [print last-friday-of-month month year]
</syntaxhighlight>
</lang>
{{out}}
<pre>rebol last-fridays.reb <<< 2012
Line 2,539 ⟶ 4,027:
</pre>
A shorter version:
<langsyntaxhighlight REBOLlang="rebol">last-fridays-of-year: function [year] [
collect [
repeat month 12 [
Line 2,551 ⟶ 4,039:
 
foreach friday last-fridays-of-year to-integer input [print friday]
</syntaxhighlight>
</lang>
NB. See "Find the last Sunday of each month" Rosetta for alternative (even more succinct) solution
 
Line 2,558 ⟶ 4,046:
<br>It wasn't optimized just to find a particular day-of-week.
 
The documentation for the &nbsp; '''lastDOW''' &nbsp; function &nbsp; (used in the REXX program below):
 
<pre>
╔════════════════════════════════════════════════════════════════════════════════════════════════╗
╔════════════════════════════════════════════════════════════════════╗
║ lastDOW: procedure to return the date of the last day─of─week of any particular month of any
║ particular year. any particular month of any particular year.
║ The day─of─week must be specified (it can be in any case, (lower─/mixed─/upper─case) as an
║ English name of the spelled day of the week, with a minimum length that causes no ambiguity. ║
║ (lower─/mixed─/upper─case) as an English name of the spelled day ║
║ ║
║ of the week, with a minimum length that causes no ambiguity. ║
║ I.E.: TU for Tuesday. W for Wednesday, Sa for Saturday, Su for Sunday ...
║ The month can be specified as an integer 1 ──► 12
║ 1=January 2=February 3=March 4=April 5=May 6=June ... 12=December
║ or the English name of the month, with a minimum length that causes no ambiguity.
I.E.: causesJA no ambiguity.for January, I.E.:AP Junfor April, JUN for June, DJUL for December.July, D for December.
║ If omitted [or an asterisk(*)], the current month is used.
║ The year is specified as an integer or just the last two digits (two digit years are assumed
(two digit years are assumed to be in the current century, and there is no windowing for a two─digit year). If omitted
there[or isan noasterisk(*)], windowing forthe a two─digitcurrent year). is used. Years < 100 must be specified with (at
║ least 2) leading zeroes. ║
║ If omitted [or an asterisk(*)], the current year is used. ║
║ ║
║ Years < 100 must be specified with (at least 2) leading zeroes.║
║ The method used is: find the "day number" of the 1st of the next month and then subtract one ║
║ ║
Method(this used: findgives the "day number" of the 1stlast day of the next month, bypassing the leapday mess). The
║ last day─of─week is then obtained straightforwardly, or via subtraction. ║
║ then subtract one (this gives the "day number" of the last day of ║
╚════════════════════════════════════════════════════════════════════════════════════════════════╝
║ the month, bypassing the leapday mess). The last day─of─week is ║
<syntaxhighlight lang="rexx">/*REXX program displays the dates of the last Fridays of each month for any given year.*/
║ then obtained straightforwardly, or via subtraction. ║
parse arg yyyy /*obtain optional argument from the CL.*/
╚════════════════════════════════════════════════════════════════════╝
do j=1 for 12 /*traipse through all the year's months*/
</pre>
<lang rexx>/*REXX program displays the dates of the last Fridays of each month for any given year.*/
parse arg yyyy
do j=1 for 12
say lastDOW('Friday', j, yyyy) /*find last Friday for the Jth month.*/
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
lastDOW: procedure; arg dow .,mm .,yy .; parse arg a.1,a.2,a.3 /*DOW = day of week*/
if mm=='' | mm=='*' then mm= left( date('U'), 2) /*use default month*/
if yy=='' | yy=='*' then yy= left( date('S'), 4) /*use default year */
if length(yy)==2 then yy= left( date('S'), 2)yy /*append century. */
/*Note mandatory leading blank in strings below*/
$=" Monday TUesday Wednesday THursday Friday SAturday SUnday"
!=" JAnuary February MARch APril MAY JUNe JULy AUgust September October November December"
upper $ ! /*uppercase strings*/
if dow=='' then call .er "wasn't specified", 1 /*no month given ? */
if arg()>3 then call .er 'arguments specified', 4 /*too many args ? */
 
do j=1 for 3 /*any plural args ?*/
if words( arg(j) ) > 1 then call .er 'is illegal:', j /*check if plural. */
end
/*find DOW in list.*/
dw= pos(' 'dow, $) /*find day-of-week*/
if dw==0 then call .er 'is invalid:' , 1 /*no DOW was found?*/
if dw\==lastpos(' 'dow,$) then call .er 'is ambiguous:', 1 /*check min length.*/
 
dw=posif datatype('mm, 'dow,$M') then do /*findis MM day-of-weekalphabetic?*/
if dw==0 then call .er m= pos('is invalid:'mm,1 !) /*maybe its good...*/
if dw\m==lastpos('0 'dow,$) then call .er 'is ambigiousinvalid:' , 1
if m\==lastpos(' 'mm,!) then call .er 'is ambiguous:', 2
mm= wordpos( word( substr(!,m), 1), !)-1 /*now, use true Mon*/
end
 
if \datatype(mm, 'MW') then call .er "isn't an integer:", 2 /*isMM MM(mon) alphabetic?¬integer*/
if \datatype(yy, 'W') then call .er "isn't an integer:", 3 /*YY (yr) ¬integer*/
do
if mm<1 m=pos('| 'mm,!) >12 then call .er "isn't in range 1──►12:", 2 /*maybeMM itsout─of─range. good...*/
if m=yy=0 then call .er "can'ist invalidbe 0 (zero):'",1 3 /*YY can't be zero.*/
if yy<0 if m\==lastpos(' 'mm,!) then call .er "can'ist ambigiousbe negative:'",2 3 /* " " " neg. */
if yy>9999 mm=wordpos( word( substr(!, m), 1), !) - 1 then call .er "can't be > 9999:", 3 /*now, use" " true" Monhuge.*/
end
 
tdow= wordpos( word( substr($, dw), 1), $) - 1 /*target DOW, 0──►6*/
if \datatype(mm,'W') then call .er "isn't an integer:",2
if \datatype(yy,'W') then call .er "isn't an integer:",3
if mm<1 | mm>12 then call .er "isn't in range 1──►12:",2
if yy=0 then call .er "can't be 0 (zero):",3
if yy<0 then call .er "can't be negative:",3
if yy>9999 then call .er "can't be > 9999:",3
 
tdow=wordpos(word(substr($,dw),1),$)-1 /*target DOW, 0──►6*/
/*day# of last dom.*/
_= date('B', right(yy + (mm=12), 4)right(mm // 12 + 1, 2, 0)"01", 'S') - 1
?= _ // 7 /*calc. DOW, 0──►6*/
if ?\==tdow then _= _ - ? - 7 + tdow + 7 * (?>tdow) /*not DOW? Adjust.*/
return date('weekday', _, "B") date(, _, 'B') /*return the answer*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.er: arg ,_; say; say '***error*** (in LASTDOW)'; say say /*tell error, and */
say word('day-of-week month year excess', arg(2)) arg(1) a._ /*plug in a choice.*/
say; exit 13 /*...··· then exit. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the following input of: &nbsp; &nbsp; <tt> 2012 </tt> &nbsp; &nbsp; or &nbsp; &nbsp; <tt> 12 </tt> }}
<pre>
Friday 27 Jan 2012
Line 2,655 ⟶ 4,139:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
see "What year to calculate (yyyy) : "
give year
Line 2,677 ⟶ 4,161:
next
 
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,694 ⟶ 4,178:
2012-11-30
2012-12-28
</pre>
 
=={{header|RPL}}==
With the release of the HP-48, RPL gained some basic functions for calculating the date, but nothing for directly obtaining the day of the week.
{{works with|HP|48}}
≪ { "MON" TUE" "WED" "THU" "FRI" "SAT" "SUN" }
SWAP 0 TSTR 1 3 SUB POS
≫ '<span style="color:blue">WKDAY</span>' STO <span style="color:grey">@ ( dd.mmyyyy → 1..7 )</span>
≪ → year
≪ { }
.02 .13 '''FOR''' month
1 month .13 == DUP .01 month IFTE SWAP year + 1000000 / + +
DUP <span style="color:blue">WKDAY</span> 1 + 7 MOD 1 + NEG DATE+ 2 TRNC +
0.01 '''STEP''' 2 FIX
≫ ≫ '<span style="color:blue">TGIF</span>' STO
 
2012 <span style="color:blue">TGIF</span>
{{out}}
<pre>
1: {27.01 24.02 30.03 27.04 25.05 29.06 27.07 31.08 28.09 26.10 30.11 28.12 }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'date'
 
def last_friday(year, month)
Line 2,706 ⟶ 4,211:
 
year = Integer(ARGV.shift)
(1..12).each {|month| puts last_friday(year, month)}</langsyntaxhighlight>
 
Friday is <code>d.wday == 5</code>; the expression <code>(d.wday - 5) % 7</code> counts days after Friday.
Line 2,726 ⟶ 4,231:
 
Or get the last day of the month and go to the previous day until it's a Friday.
<langsyntaxhighlight lang="ruby">require 'date'
 
def last_friday(year, month)
Line 2,733 ⟶ 4,238:
d
end
</syntaxhighlight>
</lang>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">input "Year:";yr
dayOne$ = "01-01-";yr
n1 = date$(dayOne$)
Line 2,750 ⟶ 4,255:
wend
print date$(n1) ' print last Friday's date
next i</langsyntaxhighlight>
<pre>Year:?2013
01/25/2013
Line 2,764 ⟶ 4,269:
11/29/2013
12/27/2013</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) % 7) + 1);
println!("{}", date - days_back);
});
}</syntaxhighlight>
 
{{out}}
<pre>
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">import java.util.Calendar
import java.text.SimpleDateFormat
 
Line 2,789 ⟶ 4,326:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>2012-Jan-27
Line 2,809 ⟶ 4,346:
Applicable to any day of the week, cf. [[http://rosettacode.org/wiki/Find_last_sunday_of_each_month#Seed7]].
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "time.s7i";
include "duration.s7i";
Line 2,838 ⟶ 4,375:
end for;
end if;
end func;</langsyntaxhighlight>
 
{{out}} when called with <tt>s7 rosetta/lastWeekdayInMonth 5 2013</tt>:
Line 2,854 ⟶ 4,391:
2013-11-29
2013-12-27
</pre>
 
=={{header|SenseTalk}}==
<syntaxhighlight lang="sensetalk">
ask "What year?"
put it into year
 
put !"The last Fridays of each month in [[year]] are:"
 
set lastDayOfMonth to year & "-01-31" -- start with January 31 of the year
 
repeat 12 times
set lastFriday to lastDayOfMonth
repeat until weekdayName of lastFriday is "Friday"
subtract a day from lastFriday -- work back to Friday
end repeat
put the monthName of lastFriday && ordinalWords of the day of lastFriday
add a month to lastDayOfMonth -- advance to last day of next month
end repeat
</syntaxhighlight>
{{out}}
<pre>
The last Fridays of each month in 2008 are:
January twenty-fifth
February twenty-ninth
March twenty-eighth
April twenty-fifth
May thirtieth
June twenty-seventh
July twenty-fifth
August twenty-ninth
September twenty-sixth
October thirty-first
November twenty-eighth
December twenty-sixth
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">require('DateTime');
var (year=20152016) = ARGV».map{.to_i»()}...;
 
 
rangefor month (1, ..12).each { |month|
var dt = %s'O<DateTime'>.last_day_of_month(year => year, month => month);
while (dt.day_of_week  != 5) {
dt.subtract(days => 1);
};
say dt.ymd;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,887 ⟶ 4,461:
=={{header|Smalltalk}}==
 
<syntaxhighlight lang="smalltalk">
<lang Smalltalk>
Pharo Smalltalk
 
Line 2,897 ⟶ 4,471:
thenSelect: [ :each |
(((Date daysInMonth: each monthIndex forYear: yr) - each dayOfMonth) <= 6) and: [ each year = yr ] ] ]
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,905 ⟶ 4,479:
 
=={{header|SQL}}==
<syntaxhighlight lang="sql">
<lang SQL>
select to_char( next_day( last_day( add_months( to_date(
:yr||'01','yyyymm' ),level-1))-7,'Fri') ,'yyyy-mm-dd Dy') lastfriday
from dual
connect by level <= 12;
</syntaxhighlight>
</lang>
<pre>
LASTFRIDAY
Line 2,928 ⟶ 4,502:
 
12 rows selected.
</pre>
 
=={{header|Stata}}==
<syntaxhighlight lang="stata">program last_fridays
args year
clear
qui set obs 12
gen day=dofm(mofd(mdy(_n,1,`year'))+1)-1
qui replace day=day-mod(dow(day)-5,7)
format %td day
list, noobs noheader sep(6)
end
 
last_fridays 2012
 
+-----------+
| 27jan2012 |
| 24feb2012 |
| 30mar2012 |
| 27apr2012 |
| 25may2012 |
| 29jun2012 |
|-----------|
| 27jul2012 |
| 31aug2012 |
| 28sep2012 |
| 26oct2012 |
| 30nov2012 |
| 28dec2012 |
+-----------+</syntaxhighlight>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">
import Foundation
 
func lastFridays(of year: Int) -> [Date] {
let calendar = Calendar.current
var dates = [Date]()
for month in 2...13 {
let lastDayOfMonth = DateComponents(calendar: calendar,
year: year,
month: month,
day: 0,
hour: 12)
let date = calendar.date(from: lastDayOfMonth)!
let isFriday = calendar.component(.weekday, from: date) == 6
if isFriday {
dates.append(calendar.date(from: lastDayOfMonth)!)
} else {
let lastWeekofMonth = calendar.ordinality(of: .weekOfMonth,
in: .month,
for: date)!
let lastWithFriday = lastWeekofMonth - (calendar.component(.weekday, from: date) > 6 ? 0 : 1)
let lastFridayOfMonth = DateComponents(calendar: calendar,
year: year,
month: month - 1,
hour: 12,
weekday: 6,
weekOfMonth: lastWithFriday)
dates.append(calendar.date(from: lastFridayOfMonth)!)
}
}
return dates
}
 
var dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
 
print(lastFridays(of: 2013).map(dateFormatter.string).joined(separator: "\n"))
</syntaxhighlight>
<pre>
1/27/12
2/24/12
3/30/12
4/27/12
5/25/12
6/29/12
7/27/12
8/31/12
9/28/12
10/26/12
11/30/12
12/28/12
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
set year [lindex $argv 0]
foreach dm {02/1 03/1 04/1 05/1 06/1 07/1 08/1 09/1 10/1 11/1 12/1 12/32} {
Line 2,938 ⟶ 4,607:
# Print the interesting part
puts [clock format $t -format "%Y-%m-%d" -gmt 1]
}</langsyntaxhighlight>
Sample execution:
<pre>
Line 2,957 ⟶ 4,626:
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT
year=2012
Line 2,969 ⟶ 4,638:
ENDLOOP
ENDLOOP
</syntaxhighlight>
</lang>
{{out}}
<pre style='height:30ex;overflow:scroll'>
Line 2,988 ⟶ 4,657:
=={{header|UNIX Shell}}==
Using <code>ncal</code>. Will switch to Julian calender as ncal sees fit, and will not calculate past year 9999 (chances are you'll be too dead by then to worry about weekends anyway).
<langsyntaxhighlight lang="bash">#!/bin/sh
 
if [ -z $1 ]; then exit 1; fi
Line 2,996 ⟶ 4,665:
for m in 01 02 03 04 05 06 07 08 09 10 11 12; do
echo $1-$m-`ncal $m $1 | grep Fr | sed 's/.* \([0-9]\)/\1/'`
done</langsyntaxhighlight>
 
 
For systems without ncal:
<langsyntaxhighlight lang="sh">#!/bin/sh
 
# usage: last_fridays [ year]
Line 3,016 ⟶ 4,685:
# Strip leading zeros to avoid octal interpretation
month=$(( 1 + ${month#0} ))
done</langsyntaxhighlight>
 
 
Using <code>date --date</code> from GNU date??? This code is not portable.
 
<langsyntaxhighlight lang="bash">#!/bin/sh
 
# Free code, no limit work
Line 3,090 ⟶ 4,759:
 
# main
last_fridays ${1:-2012}</langsyntaxhighlight>
 
Sample execution:
Line 3,110 ⟶ 4,779:
 
=={{header|Visual FoxPro}}==
<langsyntaxhighlight lang="vfp">
*!* OOP implementaion
LOCAL lnYear As Integer, oCalc As fricalc
Line 3,145 ⟶ 4,814:
 
ENDDEFINE
</syntaxhighlight>
</lang>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">import time
import os
 
fn main() {
mut year := 0
mut t := time.now()
year = os.input("Please select a year: ").int()
println("Last Fridays of each month of $year")
println("==================================")
for i in 1..13 {
mut j := time.month_days[i-1]
if i == 2 {
if time.is_leap_year(year) {j = 29}
}
for {
t = time.parse('$year-${i:02}-$j 12:30:00')!
if t.weekday_str() == 'Fri' {
println("${time.long_months[i-1]}: $j")
break
}
j--
}
}
}</syntaxhighlight>
{{out}}
<pre>Please select a year: 2012
Last Fridays of each month of 2012
==================================
January: 27
February: 24
March: 30
April: 27
May: 25
June: 29
July: 27
August: 31
September: 28
October: 26
November: 30
December: 28
</pre>
 
=={{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 Fridays 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 == 5) {
System.print(dt)
} else if (wd > 5) {
System.print(dt.addDays(-wd + 5))
} else {
System.print(dt.addDays(-wd - 2))
}
}</syntaxhighlight>
 
{{out}}
<pre>
$ wren last_friday.wren 2012
The dates of the last Fridays in the month for 2012 are:
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28
 
$ wren last_friday.wren 2020
The dates of the last Fridays in the month for 2020 are:
2020-01-31
2020-02-28
2020-03-27
2020-04-24
2020-05-29
2020-06-26
2020-07-31
2020-08-28
2020-09-25
2020-10-30
2020-11-27
2020-12-25
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
func WeekDay(Year, Month, Day); \Return day of week (0=Sun, 1=Mon ... 6=Sat)
Line 3,170 ⟶ 4,941:
IntOut(0, LastDay); CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 3,190 ⟶ 4,961:
=={{header|zkl}}==
Gregorian calendar
<langsyntaxhighlight lang="zkl">var [const] D=Time.Date;
fcn lastDay(y,_dd){[1..12].pump(Console.println,
[1..12].pump(List,'wrap(m){D.daysInMonth(y // 12 months,m) :closure for y & d
[_D.daysInMonth(y,m)..1,-1].pump(Void,'wrap(d_d){ // work backwards
D.weekDay(y,m,d_d) :
if (_==_dd) return(Void.Stop,"%d-%02d-%02d"D.fmttoYMDString(y,m,d_d))
})
})
}
lastDay(2012,D.Friday).concat("\n").println();</langsyntaxhighlight>
For each month in year y, count back from the last day in the month
until a Friday is found and print that date.
2,052

edits