Last Friday of each month: Difference between revisions

Content added Content deleted
m (→‎{{header|Factor}}: update to Factor 0.98)
m (→‎{{header|REXX}}: added/changed whitespace and comments, used a template for the output section.)
Line 3,227: Line 3,227:


The documentation for the '''lastDOW''' function   (used in the REXX program below):
The documentation for the '''lastDOW''' function   (used in the REXX program below):

<pre>
╔════════════════════════════════════════════════════════════════════╗
╔════════════════════════════════════════════════════════════════════╗
║ lastDOW: procedure to return the date of the last day─of─week of ║
║ lastDOW: procedure to return the date of the last day─of─week of ║
Line 3,254: Line 3,254:
║ then obtained straightforwardly, or via subtraction. ║
║ then obtained straightforwardly, or via subtraction. ║
╚════════════════════════════════════════════════════════════════════╝
╚════════════════════════════════════════════════════════════════════╝
</pre>
<lang rexx>/*REXX program displays the dates of the last Fridays of each month for any given year.*/
<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.*/
parse arg yyyy
do j=1 for 12
do j=1 for 12 /*traipse through all the year's months*/
say lastDOW('Friday', j, yyyy) /*find last Friday for the Jth month.*/
say lastDOW('Friday', j, yyyy) /*find last Friday for the Jth month.*/
end /*j*/
end /*j*/
exit /*stick a fork in it, we're all done. */
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*/
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 mm=='' | mm=='*' then mm= left( date('U'), 2) /*use default month*/
if yy=='' | yy=='*' then yy=left( date('S'), 4) /*use default year */
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. */
if length(yy)==2 then yy= left( date('S'), 2)yy /*append century. */
/*Note mandatory leading blank in strings below*/
/*Note mandatory leading blank in strings below*/
$=" Monday TUesday Wednesday THursday Friday SAturday SUnday"
$=" Monday TUesday Wednesday THursday Friday SAturday SUnday"
!=" JAnuary February MARch APril MAY JUNe JULy AUgust September October November December"
!=" JAnuary February MARch APril MAY JUNe JULy AUgust September October November December"
upper $ ! /*uppercase strings*/
upper $ ! /*uppercase strings*/
if dow=='' then call .er "wasn't specified",1
if dow=='' then call .er "wasn't specified", 1 /*no month given ? */
if arg()>3 then call .er 'arguments specified',4
if arg()>3 then call .er 'arguments specified', 4 /*too many args ? */


do j=1 for 3 /*any plural args ?*/
do j=1 for 3 /*any plural args ?*/
if words(arg(j))>1 then call .er 'is illegal:',j
if words( arg(j) ) > 1 then call .er 'is illegal:', j /*check if plural. */
end
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=pos(' 'dow,$) /*find day-of-week*/
if datatype(mm, 'M') then do /*is MM alphabetic?*/
if dw==0 then call .er 'is invalid:',1
m= pos(' 'mm, !) /*maybe its good...*/
if dw\==lastpos(' 'dow,$) then call .er 'is ambigious:',1
if m==0 then call .er 'is invalid:' , 1
if m\==lastpos(' 'mm,!) then call .er 'is ambiguous:', 2

if datatype(mm,'M') then /*is MM alphabetic?*/
mm= wordpos( word( substr(!,m), 1), !)-1 /*now, use true Mon*/
end
do
m=pos(' 'mm,!) /*maybe its good...*/
if m==0 then call .er 'is invalid:',1
if m\==lastpos(' 'mm,!) then call .er 'is ambigious:',2
mm=wordpos( word( substr(!, m), 1), !) - 1 /*now, use true Mon*/
end


if \datatype(mm,'W') then call .er "isn't an integer:",2
if \datatype(mm, 'W') then call .er "isn't an integer:", 2 /*MM (mon) ¬integer*/
if \datatype(yy,'W') then call .er "isn't an integer:",3
if \datatype(yy, 'W') then call .er "isn't an integer:", 3 /*YY (yr) ¬integer*/
if mm<1 | mm>12 then call .er "isn't in range 1──►12:",2
if mm<1 | mm>12 then call .er "isn't in range 1──►12:", 2 /*MM out─of─range. */
if yy=0 then call .er "can't be 0 (zero):",3
if yy=0 then call .er "can't be 0 (zero):", 3 /*YY can't be zero.*/
if yy<0 then call .er "can't be negative:",3
if yy<0 then call .er "can't be negative:", 3 /* " " " neg. */
if yy>9999 then call .er "can't be > 9999:",3
if yy>9999 then call .er "can't be > 9999:", 3 /* " " " huge.*/


tdow=wordpos(word(substr($,dw),1),$)-1 /*target DOW, 0──►6*/
tdow= wordpos( word( substr($, dw), 1), $) - 1 /*target DOW, 0──►6*/
/*day# of last dom.*/
/*day# of last dom.*/
_=date('B',right(yy+(mm=12),4)right(mm//12+1,2,0)"01",'S')-1
_= date('B', right(yy + (mm=12), 4)right(mm // 12 + 1, 2, 0)"01", 'S') - 1
?=_ // 7 /*calc. DOW, 0──►6*/
?= _ // 7 /*calc. DOW, 0──►6*/
if ?\==tdow then _=_ - ? - 7 + tdow + 7 * (?>tdow) /*not DOW? Adjust.*/
if ?\==tdow then _= _ - ? - 7 + tdow + 7 * (?>tdow) /*not DOW? Adjust.*/
return date('weekday', _, "B") date(, _, 'B') /*return the answer*/
return date('weekday', _, "B") date(, _, 'B') /*return the answer*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.er: arg ,_; say; say '***error*** (in LASTDOW)'; say /*tell error, and */
.er: arg ,_; say; say '***error*** (in LASTDOW)'; say /*tell error, and */
say word('day-of-week month year excess',arg(2)) arg(1) a._
say word('day-of-week month year excess', arg(2)) arg(1) a._ /*plug in a choice.*/
say; exit 13 /*... then exit. */</lang>
say; exit 13 /*··· then exit. */</lang>
'''output''' &nbsp; when using the following input: &nbsp; <tt> 2012 </tt> &nbsp; &nbsp; or &nbsp; &nbsp; <tt> 12 </tt>
{{out|output|text=&nbsp; when using the following input of: &nbsp; &nbsp; <tt> 2012 </tt> &nbsp; &nbsp; or &nbsp; &nbsp; <tt> 12 </tt}}
<pre>
<pre>
Friday 27 Jan 2012
Friday 27 Jan 2012