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]].
<
Ada.Calendar.Formatting, Ada.Calendar.Arithmetic;
Line 64 ⟶ 245:
Put_Line(Selected);
end loop;
end Last_Weekday_In_Month;</
{{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>
=={{
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
-- 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))))))
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/lastFridays.scpt
Line 107 ⟶ 474:
-- singleYearOrRange :: [Int] -> [Int]
on singleYearOrRange(argv)
apply(cond(length of argv > 0, my
end singleYearOrRange
Line 113 ⟶ 480:
on fiveCurrentYears(_)
set intThisYear to year of (current date)
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(
else
{}
Line 126 ⟶ 500:
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- Dates and date strings ----------------------------------------------------
-- calendarDate :: Int -> Int -> Int -> Date
Line 186 ⟶ 522:
end isoDateString
-- Testing and tabulation ----------------------------------------------------
-- apply (a -> b) -> a -> b
on apply(f, a)
mReturn(f)'s |λ|(a)
end apply
--
on
else
g
end cond
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
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
Line 221 ⟶ 565:
intercalate(tab, map(my isoDateString, lstDate))
end isoRow
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to
end repeat
return lst
end tell
end map
Line 255 ⟶ 581:
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
property |λ| : f
end script
end if
end
-- 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}}==
<
{
InputBox, 1, Last Fridays of year, Enter a year:, , , , , , , , %A_YYYY%
Line 330 ⟶ 767:
stmp += 1, days
}
MsgBox % res</
{{out}} for 2012:
<pre>2012-01-27
Line 347 ⟶ 784:
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">
#include <Date.au3>
Line 370 ⟶ 807:
ConsoleWrite($sResult)
EndFunc ;==>_GetFridays
</syntaxhighlight>
{{out}}
<pre>
Line 390 ⟶ 827:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f LAST_FRIDAY_OF_EACH_MONTH.AWK year
# converted from Fortran
Line 408 ⟶ 845:
exit(0)
}
</syntaxhighlight>
{{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.
<
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,+*<</
{{out}}
Line 455 ⟶ 920:
Doesn't work with Julian calendar (then again, you probably don't need to plan your weekends for middle ages).
<
#include <stdlib.h>
Line 474 ⟶ 939:
return 0;
}</
=={{header|C sharp}}==
<
using System.Collections.Generic;
using System.Globalization;
Line 514 ⟶ 979:
}
}
}</
{{out}}
<pre>01/27/2012
Line 532 ⟶ 997:
{{libheader|Boost}}
called with <code>./last_fridays 2012</code>
<
#include <iostream>
#include <cstdlib>
Line 548 ⟶ 1,013:
}
return 0 ;
}</
{{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}}
<
'[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))))</
{{out}}
Line 595 ⟶ 1,101:
=={{header|COBOL}}==
<syntaxhighlight lang="cobol">
program-id. last-fri.
data division.
Line 644 ⟶ 1,150:
.
end program last-fri.
</syntaxhighlight>
{{out}}
Line 663 ⟶ 1,169:
=={{header|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>
{{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>
=={{header|Common Lisp}}==
Line 704 ⟶ 1,210:
The command-line argument processing is the only CLISP-specific code.
<
(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)))</
Sample run for the year 2015:
Line 735 ⟶ 1,241:
=={{header|D}}==
<
void lastFridays(in uint year) {
Line 749 ⟶ 1,255:
void main() {
lastFridays(2012);
}</
<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}}==
<
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)</
{{out}}
Line 795 ⟶ 1,382:
2012-12-28
</pre>
=={{header|Elm}}==
<
import Html.App exposing (beginnerProgram)
import Html.Attributes exposing (placeholder, value, style)
Line 862 ⟶ 1,450:
, view = view
, update = update
}</
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">
-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>
{{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.
<
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>
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 947 ⟶ 1,590:
Function leapyear(Year_ As Integer) As Integer
' from the
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</
{{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?
Last Friday of the month for
=={{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}}==
<
import (
Line 1,063 ⟶ 1,783:
fmt.Println(d.Format("2006-01-02"))
}
}</
{{out}}
<pre>
Line 1,085 ⟶ 1,805:
Test:
<
def lastFridays = lastWeekDays.curry(Day.Fri)
lastFridays(args[0] as int).each { println (ymd(it)) }</
Execution (Cygwin on Windows 7):
Line 1,107 ⟶ 1,827:
=={{header|Haskell}}==
<
(Day, addDays, showGregorian, fromGregorian, gregorianMonthLength)
import Data.Time.Calendar.WeekDate (toWeekDate)
import Data.List (transpose, intercalate)
-- [1 .. 7] for [Mon .. Sun]
findWeekDay :: Int -> Day -> Day
findWeekDay dayOfWeek date =
head
(filter
(\x ->
let (_, _, day) = toWeekDate x
in day == dayOfWeek)
((`addDays` date) <$> [-6 .. 0]))
weekDayDates :: Int -> Integer -> [String]
weekDayDates dayOfWeek year =
((showGregorian . findWeekDay dayOfWeek) .
[1 .. 12]
main
main =
mapM_
(intercalate " " <$> transpose (weekDayDates 5 <$> [2012 .. 2017]))</syntaxhighlight>
{{Out}}
<pre>2012-01-27 2013-01-25 2014-01-31 2015-01-30 2016-01-29 2017-01-27
2012-02-24 2013-02-22 2014-02-28 2015-02-27 2016-02-26 2017-02-24
2012-03-30 2013-03-29 2014-03-28 2015-03-27 2016-03-25 2017-03-31
2012-04-27 2013-04-26 2014-04-25 2015-04-24 2016-04-29 2017-04-28
2012-05-25 2013-05-31 2014-05-30 2015-05-29 2016-05-27 2017-05-26
2012-06-29 2013-06-28 2014-06-27 2015-06-26 2016-06-24 2017-06-30
2012-07-27 2013-07-26 2014-07-25 2015-07-31 2016-07-29 2017-07-28
2012-08-31 2013-08-30 2014-08-29 2015-08-28 2016-08-26 2017-08-25
2012-09-28 2013-09-27 2014-09-26 2015-09-25 2016-09-30 2017-09-29
2012-10-26 2013-10-25 2014-10-31 2015-10-30 2016-10-28 2017-10-27
2012-11-30 2013-11-29 2014-11-28 2015-11-27 2016-11-25 2017-11-24
2012-12-28 2013-12-27 2014-12-26 2015-12-25 2016-12-30 2017-12-29</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.
<
every write(lastfridays(!A))
end
Line 1,162 ⟶ 1,888:
end
link datetime, printf</
{{libheader|Icon Programming Library}}
Line 1,185 ⟶ 1,911:
=={{header|J}}==
<
last_fridays=: 12 {. [: ({:/.~ }:"1)@(#~ 5 = weekday)@todate (i.366) + todayno@,&1 1</
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:
<
2012 1 27
2012 2 24
Line 1,204 ⟶ 1,930:
2012 10 26
2012 11 30
2012 12 28</
=={{header|Java}}==
{{works with|Java|1.5+}}
<
import java.util.*;
Line 1,233 ⟶ 1,959:
}
}
}</
{{out}} (for <code>java LastFridays 2012</code>):
<pre>2012 Jan 27
Line 1,248 ⟶ 1,974:
2012 Dec 28</pre>
=={{header|JavaScript}}==
==
====Iteration====
{{works with|Nodejs}}
<syntaxhighlight 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
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>
====Functional composition====
<syntaxhighlight 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>
{{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'''
<
def until(cond; next):
Line 1,425 ⟶ 2,232:
| if iso == "iso" or iso == "ISO" then 1 + ((. + 5) % 7)
else . % 7
end ;</
'''findLastFridays'''
<
def findLastFriday(year; month):
def isLeapYear:
Line 1,448 ⟶ 2,255:
(range(0;12) | "\(months[.]) \(findLastFriday($year; .+1))") ;
$year|tonumber|findLastFridays</
{{out}}
<
YEAR: 2012
January 27
Line 1,463 ⟶ 2,270:
October 26
November 30
December 28</
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Dates
const wday = Dates.Fri
Line 1,492 ⟶ 2,298:
end
end
</syntaxhighlight>{{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}}==
<
#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'
^}</
{{out}}
Line 1,561 ⟶ 2,446:
2012-11-30
2012-12-28</pre>
=={{header|LiveCode}}==
<
-- 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</
Example<
2 24
3 30
Line 1,598 ⟶ 2,482:
10 26
11 30
12 28</
=={{header|Logo}}==
<
to leap? :year
output (and
Line 1,645 ⟶ 2,529:
print reduce [(word ?1 "- ?2)] (list :year :month :day)
]
bye</
{{out}}
Line 1,663 ⟶ 2,547:
=={{header|Lua}}==
<
return (y % 4 == 0 and y % 100 ~=0) or y % 400 == 0
end
Line 1,682 ⟶ 2,566:
end
lastWeekdays("Friday", tonumber(arg[1]))</
Command line session:
<pre>>lua lastFridays.lua 2012
Line 1,700 ⟶ 2,584:
></pre>
=={{header|
<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]</
{{out}}
<pre>{2012,1,27}
Line 1,721 ⟶ 2,686:
=={{header|MATLAB}} / {{header|Octave}}==
<
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>
{{out}}
Line 1,748 ⟶ 2,713:
=={{header|Maxima}}==
<
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"]</
=={{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.
<
options replace format comments java crossref symbols nobinary
Line 1,849 ⟶ 2,867:
end
return
</syntaxhighlight>
{{out}}
<pre>
Line 1,884 ⟶ 2,902:
=={{header|Nim}}==
<
const
DaysInMonth: array[Month, int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
DayDiffs: array[WeekDay, int] = [3, 4, 5, 6, 0, 1, 2]
let year = paramStr(1).parseInt
for month in mJan..mDec:
var lastDay = DaysInMonth[month]
if month == mFeb and year.isLeapYear: lastDay = 29
var date = initDateTime(lastDay, month, year, 0, 0, 0)
date = date - days(DayDiffs[date.weekday])
echo date.format("yyyy-MM-dd")</syntaxhighlight>
{{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:
<
open Unix
Line 1,950 ⟶ 2,972:
done;
done;
Array.iter print_date fridays</
{{out}}
Line 1,970 ⟶ 2,992:
{{libheader|OCaml Calendar Library}}
<
let usage() =
Line 1,994 ⟶ 3,016:
aux num_days
done;
List.iter print_date (List.rev !fridays)</
Run this script with the command:
ocaml unix.cma str.cma -I +calendar calendarLib.cma last_fridays.ml 2012
=={{header|Oforth}}==
<
: lastFridays(y)
Line 2,011 ⟶ 3,032:
while(dup dayOfWeek Date.FRIDAY <>) [ addDays(-1) ]
println
] ;</
{{out}}
Line 2,031 ⟶ 3,052:
=={{header|PARI/GP}}==
<
njd(D) =
{
Line 2,057 ⟶ 3,078:
}
for (m=1, 12, a=njd([2012,m+1,0]); print(njdate(a-(a+1)%7)))</
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}}==
<
use strict ;
use DateTime ;
Line 2,085 ⟶ 3,214:
}
say $dt->ymd ;
}</
{{out}}
<pre>2012-01-27
Line 2,100 ⟶ 3,229:
2012-12-28
</pre>
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<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>
<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>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">FRIDAY</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span>
<span style="color: #000080;font-style:italic;">--prompt_number() is not compatible with pwa/p2js
<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>
<!--</syntaxhighlight>-->
{{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.
<
function last_friday_of_month($year, $month) {
$day = 0;
Line 2,207 ⟶ 3,285:
$year = 2012;
print_last_fridays_of_month($year);
?></
{{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}}==
<
(for M 12
(prinl
Line 2,232 ⟶ 3,401:
(find '((D) (= "Friday" (day D)))
(mapcar '((D) (date Y M D)) `(range 31 22)) )
"-" ) ) ) )</
Test:
<
2012-01-27
2012-02-24
Line 2,246 ⟶ 3,415:
2012-10-26
2012-11-30
2012-12-28</
=={{header|Pike}}==
<
{
return day->week_day() == 5 &&
Line 2,260 ⟶ 3,429:
write("%{%s\n%}", days->format_ymd());
return 0;
}</
=={{header|PL/I}}==
<syntaxhighlight 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>
The command: FRIDAYS /2008 produces:
<pre>
Line 2,321 ⟶ 3,490:
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function last-dayofweek {
param(
Line 2,335 ⟶ 3,504:
}
last-dayofweek 2012 "Friday"
</syntaxhighlight>
<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}}==
<
def
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))</
{{out}}
<pre>>>>
2012-01-27
2012-02-24
Line 2,376 ⟶ 3,757:
2012-12-28</pre>
Another solution
<
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</
Using reduce
<
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</
using itertools
<
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</
=={{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}}==
<
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)]))</
=={{header|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>
{{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:
<
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>
{{out}}
<pre>rebol last-fridays.reb <<< 2012
Line 2,539 ⟶ 4,027:
</pre>
A shorter version:
<
collect [
repeat month 12 [
Line 2,551 ⟶ 4,039:
foreach friday last-fridays-of-year to-integer input [print friday]
</syntaxhighlight>
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 '''lastDOW''' function (used in the REXX program below):
╔════════════════════════════════════════════════════════════════════════════════════════════════╗
║ particular year.
║
║ English name of the spelled day of the week, with a minimum length that causes no ambiguity. ║
║ ║
║
║ I.E.:
║
║ least 2) leading zeroes. ║
║ ║
║ The method used is: find the "day number" of the 1st of the next month and then subtract one ║
║ last day─of─week is then obtained straightforwardly, or via subtraction. ║
╚════════════════════════════════════════════════════════════════════════════════════════════════╝
<syntaxhighlight lang="rexx">/*REXX program displays the dates of the last Fridays of each month for any given year.*/
parse arg yyyy /*obtain optional argument from the CL.*/
do j=1 for 12 /*traipse through all the year's months*/
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
if mm=='' | mm=='*' then mm= left( date('U'), 2)
if yy=='' | yy=='*' then yy= left( date('S'), 4)
if length(yy)==2 then yy= left( date('S'), 2)yy
/*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
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.*/
if
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, '
if \datatype(yy, 'W') then call .er "isn't an integer:", 3 /*YY (yr) ¬integer*/
if mm<1
if yy<0
if yy>9999
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
if ?\==tdow then _= _ - ? - 7 + tdow + 7 * (?>tdow)
return date('weekday', _, "B") date(, _, 'B') /*return the answer*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.er: arg ,_; say; say '***error*** (in LASTDOW)';
say word('day-of-week month year excess', arg(2)) arg(1) a._ /*plug in a choice.*/
say; exit 13
<pre>
Friday 27 Jan 2012
Line 2,655 ⟶ 4,139:
=={{header|Ring}}==
<
see "What year to calculate (yyyy) : "
give year
Line 2,677 ⟶ 4,161:
next
</syntaxhighlight>
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}}==
<
def last_friday(year, month)
Line 2,706 ⟶ 4,211:
year = Integer(ARGV.shift)
(1..12).each {|month| puts last_friday(year, month)}</
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.
<
def last_friday(year, month)
Line 2,733 ⟶ 4,238:
d
end
</syntaxhighlight>
=={{header|Run BASIC}}==
<
dayOne$ = "01-01-";yr
n1 = date$(dayOne$)
Line 2,750 ⟶ 4,255:
wend
print date$(n1) ' print last Friday's date
next i</
<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}}==
<
import java.text.SimpleDateFormat
Line 2,789 ⟶ 4,326:
}
}
}</
{{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]].
<
include "time.s7i";
include "duration.s7i";
Line 2,838 ⟶ 4,375:
end for;
end if;
end func;</
{{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}}
<
var (year=
var dt = %
while (dt.day_of_week
dt.subtract(days => 1)
}
say dt.ymd
}</
{{out}}
<pre>
Line 2,887 ⟶ 4,461:
=={{header|Smalltalk}}==
<syntaxhighlight 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>
{{out}}
<pre>
Line 2,905 ⟶ 4,479:
=={{header|SQL}}==
<syntaxhighlight 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>
<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}}==
<
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]
}</
Sample execution:
<pre>
Line 2,957 ⟶ 4,626:
=={{header|TUSCRIPT}}==
<
$$ MODE TUSCRIPT
year=2012
Line 2,969 ⟶ 4,638:
ENDLOOP
ENDLOOP
</syntaxhighlight>
{{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).
<
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</
For systems without ncal:
<
# usage: last_fridays [ year]
Line 3,016 ⟶ 4,685:
# Strip leading zeros to avoid octal interpretation
month=$(( 1 + ${month#0} ))
done</
Using <code>date --date</code> from GNU date??? This code is not portable.
<
# Free code, no limit work
Line 3,090 ⟶ 4,759:
# main
last_fridays ${1:-2012}</
Sample execution:
Line 3,110 ⟶ 4,779:
=={{header|Visual FoxPro}}==
<
*!* OOP implementaion
LOCAL lnYear As Integer, oCalc As fricalc
Line 3,145 ⟶ 4,814:
ENDDEFINE
</syntaxhighlight>
=={{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}}==
<
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);
];
]</
{{out}}
Line 3,190 ⟶ 4,961:
=={{header|zkl}}==
Gregorian calendar
<
fcn lastDay(y,
[1..12].pump(List,'wrap(m){
[
D.weekDay(y,m,
if (_==
})
})
}
lastDay(2012,D.Friday).concat("\n").println();</
For each month in year y, count back from the last day in the month
until a Friday is found and print that date.
|