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

Example of an expected output:

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


Related tasks
 Day of the week
 Five weekends
 Last Friday of each month


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