Find the last Sunday of each month: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Go}}: minor function change)
(Nimrod -> Nim)
Line 881: Line 881:
29}, {2013, 10, 27}, {2013, 11, 24}, {2013, 12, 29}}</pre>
29}, {2013, 10, 27}, {2013, 11, 24}, {2013, 12, 29}}</pre>


=={{header|Nimrod}}==
=={{header|Nim}}==
<lang nimrod>import times, os, strutils
<lang nim>import times, os, strutils


var timeinfo = getLocalTime getTime()
var timeinfo = getLocalTime getTime()

Revision as of 22:52, 3 January 2015

Task
Find the last Sunday of each month
You are encouraged to solve this task according to the task description, using any language you may know.

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
Cf.

Ada

The program from [[1]] solves this task, as well.

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

AutoHotkey

<lang AutoHotkey>InputBox, Year, , Enter a year., , 300, 135 Date := Year . "0101"

while SubStr(Date, 1, 4) = Year {

   FormatTime, WD, % Date, WDay
   if (WD = 1)
       MM := LTrim(SubStr(Date, 5, 2), "0"), Day%MM% := SubStr(Date, 7, 2)
   Date += 1, Days

}

Gui, Font, S10, Courier New Gui, Add, Text, , % "Last Sundays of " Year ":`n---------------------"

Loop, 12 {

   FormatTime, Month, % Year (A_Index > 9 ? "" : "0") A_Index, MMMM
   Gui, Add, Text, y+1, % Month (StrLen(Month) > 7 ? "" : "`t") "`t" Day%A_Index%

}

Gui, Show return</lang>

Output:
Last Sundays of 2013:
---------------------
January		27
February	24
March		31
April		28
May		26
June		30
July		28
August		25
September	29
October		27
November	24
December	29

AWK

Works with GNU awk version 3.1.5 and BusyBox awk in version v1.20.0.git

Takes one or more years from standard input; easy way to generate one year's input, for example:

echo 2013 | lastsunday

#!/bin/gawk -f
BEGIN{
  #  table of days per month accessed as substr(days,2*month,2)
  days =" 312831303130313130313031"
  }
function dow (year, y){
  y=year
  y= (y*365+int(y/4) - int(y/100) + int(y/400) +1) %7
# leap year adjustment
  leap = 0
  if (year % 4 == 0)   leap = 1
  if (year % 100 == 0) leap = 0
  if (year % 400 == 0) leap = 1
  y = y - leap
  if (y==-1) y=6
  if (y==0) y=7
  return (y)
  }
function prmonth (nmonth, newdow,monsize   ,j ){
  for ( j=23-newdow; j<=monsize;j=j+7) { last=j } 
  print nmonth "/" last
}
/q/{
  exit }
{ 
  monsize=substr(days,2*1,2)
  newdow=dow($1)
  print "last Sundays for " $1
  # January - December
  for (i=1; i<13; i++) {
  prmonth(i,newdow,monsize)
  newdow=(monsize+newdow) %7
  if (newdow == 0) newdow = 7
  monsize=substr(days,2+2*i,2)
  if (leap == 1 && monsize == 28) monsize = 29
  }
 }
Output:
last Sundays for 2013
1/27
2/24
3/31
4/28
5/26
6/30
7/28
8/25
9/29
10/27
11/24
12/29

BBC BASIC

<lang bbcbasic> INSTALL @lib$+"DATELIB"

INPUT "What year to calculate (YYYY)? " Year%

PRINT '"Last Sundays 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%))

NEXT END </lang>

Output:
What year to calculate (YYYY)? 2013

Last Sundays in 2013 are on:
      2013-01-27
      2013-02-24
      2013-03-31
      2013-04-28
      2013-05-26
      2013-06-30
      2013-07-28
      2013-08-25
      2013-09-29
      2013-10-27
      2013-11-24
      2013-12-29

C++

<lang cpp>

  1. include <windows.h>
  2. include <iostream>
  3. include <string>

//-------------------------------------------------------------------------------------------------- using namespace std;

//-------------------------------------------------------------------------------------------------- class lastSunday { public:

   lastSunday()
   {

m[0] = "JANUARY: "; m[1] = "FEBRUARY: "; m[2] = "MARCH: "; m[3] = "APRIL: "; m[4] = "MAY: "; m[5] = "JUNE: "; m[6] = "JULY: "; m[7] = "AUGUST: "; m[8] = "SEPTEMBER: "; m[9] = "OCTOBER: "; m[10] = "NOVEMBER: "; m[11] = "DECEMBER: ";

   }
   void findLastSunday( int y )
   {

year = y; isleapyear();

int days[] = { 31, isleap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, d; for( int i = 0; i < 12; i++ ) { d = days[i]; while( true ) { if( !getWeekDay( i, d ) ) break; d--; } lastDay[i] = d; }

display();

   }

private:

   void isleapyear()
   {

isleap = false; if( !( year % 4 ) ) { if( year % 100 ) isleap = true; else if( !( year % 400 ) ) isleap = true; }

   }
   void display()
   {

system( "cls" ); cout << " YEAR " << year << endl << "=============" << endl; for( int x = 0; x < 12; x++ ) cout << m[x] << lastDay[x] << endl;

cout << endl << endl;

   }
   int getWeekDay( int m, int d )
   {

int y = year;

int f = y + d + 3 * m - 1; m++; if( m < 3 ) y--; else f -= int( .4 * m + 2.3 );

f += int( y / 4 ) - int( ( y / 100 + 1 ) * 0.75 ); f %= 7;

return f;

   }
   int lastDay[12], year;
   string m[12];
   bool isleap;

}; //-------------------------------------------------------------------------------------------------- int main( int argc, char* argv[] ) {

   int y;
   lastSunday ls;
   while( true )
   {

system( "cls" ); cout << "Enter the year( yyyy ) --- ( 0 to quit ): "; cin >> y; if( !y ) return 0;

ls.findLastSunday( y );

system( "pause" );

   }
   return 0;

} //-------------------------------------------------------------------------------------------------- </lang>

Output:
  YEAR 2013
=============
JANUARY:   27
FEBRUARY:  24
MARCH:     31
APRIL:     28
MAY:       26
JUNE:      30
JULY:      28
AUGUST:    25
SEPTEMBER: 29
OCTOBER:   27
NOVEMBER:  24
DECEMBER:  29

Other solution, based on the Boost DateTime library: <lang C++>#include <iostream>

  1. include <boost/date_time/gregorian/gregorian.hpp>
  2. include <cstdlib>

int main( int argc , char* argv[ ] ) {

  using namespace boost::gregorian ;
  int year =  std::atoi( argv[ 1 ] ) ;
  for ( int i = 1 ; i < 13 ; i++ ) {
     try { 

date d( year , i , 1 ) ; d = d.end_of_month( ) ; day_iterator d_itr ( d ) ; while ( d_itr->day_of_week( ) != Sunday ) { --d_itr ; } std::cout << to_simple_string ( *d_itr ) << std::endl ;

     } catch ( bad_year by ) {

std::cout << "Terminated because of " << by.what( ) << "\n" ;

     }
  }
  return 0 ;

}</lang>

Output:
2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29

C#

<lang csharp>using System;

namespace LastSundayOfEachMonth {

   class Program
   {
       static void Main()
       {
           Console.Write("Year to calculate: ");
           string strYear = Console.ReadLine();
           int year = Convert.ToInt32(strYear);
           DateTime date;
           for (int i = 1; i <= 12; i++)
           {
               date = new DateTime(year, i, DateTime.DaysInMonth(year, i), System.Globalization.CultureInfo.CurrentCulture.Calendar);
               while (date.DayOfWeek != DayOfWeek.Sunday)
               {
                   date = date.AddDays(-1);
               }
               Console.WriteLine(date.ToString("yyyy-MM-dd"));
           }
       }
   }

} </lang>

Output:
Year to calculate: 2013
2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29

Clojure

<lang clojure>(ns last-sundays.core

 (:require [clj-time.core :as time]
           [clj-time.periodic :refer [periodic-seq]]
           [clj-time.format :as fmt])
 (:import (org.joda.time DateTime DateTimeConstants))
 (:gen-class))

(defn sunday? [t]

 (= (.getDayOfWeek t) (DateTimeConstants/SUNDAY)))

(defn sundays [year]

 (take-while #(= (time/year %) year)
             (filter sunday? (periodic-seq (time/date-time year 1 1) (time/days 1)))))

(defn last-sundays-of-months [year]

 (->> (sundays year)
      (group-by time/month)
      (vals)
      (map (comp first #(sort-by time/day > %)))
      (map #(fmt/unparse (fmt/formatters :year-month-day) %))
      (interpose "\n")
      (apply str)))

(defn -main [& args]

 (println (last-sundays-of-months (Integer. (first args)))))

</lang>

Output:
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

D

<lang d>void lastSundays(in uint year) {

   import std.stdio, std.datetime;
   foreach (immutable month; 1 .. 13) {
       auto date = Date(year, month, 1);
       date.day(date.daysInMonth);
       date.roll!"days"(-(date.dayOfWeek + 7) % 7);
       date.writeln;
   }

}

void main() {

   lastSundays(2013);

}</lang>

Output:
2013-Jan-27
2013-Feb-24
2013-Mar-31
2013-Apr-28
2013-May-26
2013-Jun-30
2013-Jul-28
2013-Aug-25
2013-Sep-29
2013-Oct-27
2013-Nov-24
2013-Dec-29

Erlang

<lang Erlang> -module( last_date_each_month ).

-export( [monday/1, tuesday/1, wednesday/1, thursday/1, friday/1, saturday/1, sunday/1] ).

monday( Year ) -> last( Year, 1 ). tuesday( Year ) -> last( Year, 2 ). wednesday( Year ) -> last( Year, 3 ). thursday( Year ) -> last( Year, 4 ). friday( Year ) -> last( Year, 5 ). saturday( Year ) -> last( Year, 6 ). sunday( Year ) -> last( Year, 7 ).


last( Year, Week_day ) ->

   Months = lists:seq( 1, 12 ),
   Months_days = [{X, Y} || X <- Months, Y <- lists:seq(calendar:last_day_of_the_month(Year, X), calendar:last_day_of_the_month(Year, X) - 7, -1), calendar:valid_date(Year, X, Y), calendar:day_of_the_week(Year, X, Y) =:= Week_day],
   [{Year, X, proplists:get_value(X, Months_days)} || X <- Months].

</lang>

Output:
30> [io:fwrite("~B-~2.10.0B-~B~n", [Y,M,D]) || {Y,M,D} <- last_date_each_month:sunday(2013)].
2013-01-27
2013-02-24
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

FBSL

<lang qbasic>#APPTYPE CONSOLE

DIM date AS INTEGER, dayname AS STRING FOR DIM i = 1 TO 12

   FOR DIM j = 31 DOWNTO 1
       date = 20130000 + (i * 100) + j
       IF CHECKDATE(i, j, 2013) THEN
           dayname = DATECONV(date, "dddd")
           IF dayname = "Sunday" THEN
               PRINT 2013, " ", i, " ", j
               EXIT FOR
           END IF
       END IF
   NEXT

NEXT

PAUSE </lang>

Output:
2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29

Press any key to continue...

Go

This is different from the Go code for Last Friday of each month. It uses the fact that time functions in Go correct for dates: if you enter 32nd of october, Go corrects to 1st of November. So that if 29th of February is corrected to 1st of March, chosen year is not a leap year.

<lang go>package main

import ( "fmt" "time" )

func main() {

var year int var t time.Time var lastDay = [12]int { 31,29,31,30,31,30,31,31,30,31,30,31 }

for { fmt.Print("Please select a year: ") _, err := fmt.Scanf("%d", &year) if err != nil { fmt.Println(err) continue } else { break } }

fmt.Println("Last Sundays of each month of", year) fmt.Println("==================================")

for i := 1;i < 13; i++ { j := lastDay[i-1] if i == 2 { if time.Date(int(year), time.Month(i), j, 0, 0, 0, 0, time.UTC).Month() == time.Date(int(year), time.Month(i), j-1, 0, 0, 0, 0, time.UTC).Month() { j = 29 } else { j = 28 } } for { t = time.Date(int(year), time.Month(i), j, 0, 0, 0, 0, time.UTC) if t.Weekday() == 0 { fmt.Printf("%s: %d\n", time.Month(i), j) break } j = j - 1 } } } </lang>

Please select a year: 2013
Last Sundays of each month of 2013
==================================
January: 27
February: 24
March: 31
April: 28
May: 26
June: 30
July: 28
August: 25
September: 29
October: 27
November: 24
December: 29

Groovy

Solution: <lang groovy>enum Day {

   Sun, Mon, Tue, Wed, Thu, Fri, Sat
   static Day valueOf(Date d) { Day.valueOf(d.format('EEE')) }

}

def date = Date.&parse.curry('yyyy-MM-dd') def month = { it.format('MM') } def days = { year -> (date("${year}-01-01")..<date("${year+1}-01-01")) } def weekDays = { dayOfWeek, year -> days(year).findAll { Day.valueOf(it) == dayOfWeek } }

def lastWeekDays = { dayOfWeek, year ->

   weekDays(dayOfWeek, year).reverse().inject([:]) { months, sunday ->
       def monthStr = month(sunday)
       !months[monthStr]  ?  months + [(monthStr):sunday]  :  months
   }.values().sort()

}</lang>

Test: <lang groovy>def ymd = { it.format('yyyy-MM-dd') } def lastSundays = lastWeekDays.curry(Day.Sun) lastSundays(args[0] as int).each { println (ymd(it)) }</lang>

Execution (Cygwin on Windows 7):

[2201] groovy lastSundays.groovy 2013
Output:
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

Icon and Unicon

This is a trivial adaptation of the solution to the "Last Friday of each month" task and works in both languages: <lang unicon>procedure main(A) every write(lastsundays(!A)) end

procedure lastsundays(year) every m := 1 to 12 do {

  d := case m of {
     2        : if IsLeapYear(year) then 29 else 28
     4|6|9|11 : 30
     default  : 31
     }                          # last day of month

  z := 0  
  j := julian(m,d,year) + 1     # first day of next month
  until (j-:=1)%7 = 6 do z -:=1 # backup to last sunday (6)
  suspend sprintf("%d-%d-%d",year,m,d+z)
  }

end

link datetime, printf</lang>

Sample run:

->lsem 2013 2014
2013-1-27
2013-2-24
2013-3-31
2013-4-28
2013-5-26
2013-6-30
2013-7-28
2013-8-25
2013-9-29
2013-10-27
2013-11-24
2013-12-29
2014-1-26
2014-2-23
2014-3-30
2014-4-27
2014-5-25
2014-6-29
2014-7-27
2014-8-31
2014-9-28
2014-10-26
2014-11-30
2014-12-28
->

J

Same solution as for Last_Friday_of_each_month#J <lang j>require'dates' last_sundays=: 12 {. [: ({:/.~ }:"1)@(#~ 0 = weekday)@todate (i.366) + todayno@,&1 1</lang>

Example use: <lang j> last_sundays 2013 2013 1 27 2013 2 24 2013 3 31 2013 4 28 2013 5 26 2013 6 30 2013 7 28 2013 8 25 2013 9 29 2013 10 27 2013 11 24 2013 12 29</lang>

Java

<lang java>import java.util.Scanner;

public class LastSunday { static final String[] months={"January","February","March","April","May","June","July","August","September","October","November","December"};

public static int[] findLastSunday(int year) { boolean isLeap = isLeapYear(year);

int[] days={31,isLeap?29:28,31,30,31,30,31,31,30,31,30,31}; int[] lastDay=new int[12];

for(int m=0;i<12;i++) { int d; for(d=days[m]; getWeekDay(year,m,d)!=0; d--) ; lastDay[m]=d; }

return lastDay; }

private static boolean isLeapYear(int year) { if(year%4==0) { if(year%100!=0) return true; else if (year%400==0) return true; } return false; }

private static int getWeekDay(int y, int m, int d) { int f=y+d+3*m-1; m++;

if(m<3) y--; else f-=(int)(0.4*m+2.3);

f+=(int)(y/4)-(int)((y/100+1)*0.75); f%=7;

return f; }

private static void display(int year, int[] lastDay) { System.out.println("\nYEAR: "+year); for(int m=0;i<12;i++) System.out.println(months[m]+": "+lastDay[m]); }

public static void main(String[] args) throws Exception { System.out.print("Enter year: "); Scanner s=new Scanner(System.in);

int y=Integer.parseInt(s.next());

int[] lastDay = findLastSunday(y); display(y, lastDay);

s.close(); } }</lang>

Output:
Enter year: 2013

YEAR: 2013
January: 27
February: 24
March: 31
April: 28
May: 26
June: 30
July: 28
August: 25
September: 29
October: 27
November: 24
December: 29

Java 8

<lang Java>import java.time.*; import java.util.stream.*; import static java.time.temporal.TemporalAdjusters.*;

public class FindTheLastSundayOfEachMonth {

   public static Stream<LocalDate> lastSundaysOf(int year) {
       return IntStream.rangeClosed(1, 12).mapToObj(month ->
           LocalDate.of(year, month, 1).with(lastDayOfMonth())
           .with(previousOrSame(DayOfWeek.SUNDAY))
       );
   }
   public static java.util.List<LocalDate> listLastSundaysOf(int year) {
       return lastSundaysOf(year).collect(Collectors.toList());
   }
   public static void main(String[] args) throws Exception {
       int year = args.length > 0 ? Integer.parseInt(args[0]) : LocalDate.now().getYear();
       for (LocalDate d : listLastSundaysOf(year)) {
           System.out.println(d);
       };
       String result = lastSundaysOf(2013).map(LocalDate::toString).collect(Collectors.joining("\n"));
       String test = "2013-01-27\n2013-02-24\n2013-03-31\n2013-04-28\n2013-05-26\n2013-06-30\n2013-07-28\n2013-08-25\n2013-09-29\n2013-10-27\n2013-11-24\n2013-12-29";
       if (!test.equals(result)) throw new AssertionError("test failure");
   }

}</lang>

Lasso

<lang Lasso>local( year = integer(web_request -> param('year') || 2013), date = date(#year + '-1-1'), lastsu = array, lastday )

with month in generateseries(1,12) do { #date -> day = 1 #date -> month = #month #lastday = #date -> month(-days) #date -> day = #lastday loop(7) => { if(#date -> dayofweek == 1) => { #lastsu -> insert(#date -> format(`dd MMMM`)) loop_abort } #date -> day-- } }

  1. lastsu -> join('
    ')</lang>
27 January
24 February
31 March
28 April
26 May
30 June
28 July
25 August
29 September
27 October
24 November
29 December

Mathematica

<lang mathematica>LastSundays[year_] :=

Table[Last@
  DayRange[{year, i}, 
   DatePlus[{year, i}, {{1, "Month"}, {-1, "Day"}}], Sunday], {i, 
  12}]

LastSundays[2013]</lang>

Output:
{{2013, 1, 27}, {2013, 2, 24}, {2013, 3, 31}, {2013, 4, 28}, {2013, 5,
   26}, {2013, 6, 30}, {2013, 7, 28}, {2013, 8, 25}, {2013, 9, 
  29}, {2013, 10, 27}, {2013, 11, 24}, {2013, 12, 29}}

Nim

<lang nim>import times, os, strutils

var timeinfo = getLocalTime getTime() timeinfo.year = paramStr(1).parseInt for month in mJan .. mDec:

 timeinfo.month = month
 for day in countdown(31, 1):
   timeinfo.monthday = day
   let t = getLocalTime(timeInfoToTime timeinfo)
   if t.month == month and t.weekday == dSun:
     echo t.format "yyyy-MM-dd"
     break</lang>

Sample usage:

./lastsunday 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

Perl

<lang Perl>#!/usr/bin/perl use strict ; use warnings ; use DateTime ;

for my $i( 1..12 ) {

  my $date = DateTime->last_day_of_month( year => $ARGV[ 0 ] , 

month => $i ) ;

  while ( $date->dow != 7 ) {
     $date = $date->subtract( days => 1 ) ;
  }
  my $ymd = $date->ymd ;
  print "$ymd\n" ;

}</lang>

Output:
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

Perl 6

<lang Perl6>for (1..12) -> $i {

  my $lastDay = Date.days-in-month( @*ARGS[ 0 ].Int , $i ) ;
  my $lastDate = Date.new( @*ARGS[ 0 ].Int , $i , $lastDay ) ;
  while $lastDate.day-of-week != 7 {
     $lastDate -= 1 ;
  }
  $lastDate.say ;

}</lang>

Output:
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

PicoLisp

<lang PicoLisp>(de lastSundays (Y)

  (for M 12
     (prinl
        (dat$
           (find '((D) (= "Sunday" (day D)))
              (mapcar '((D) (date Y M D)) `(range 31 22)) )
           "-" ) ) ) )</lang>

Test: <lang PicoLisp>: (lastSundays 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</lang>

Python

<lang python>

  1. !/usr/bin/python3

   Output:
   2013-Jan-27
   2013-Feb-24
   2013-Mar-31
   2013-Apr-28
   2013-May-26
   2013-Jun-30
   2013-Jul-28
   2013-Aug-25
   2013-Sep-29
   2013-Oct-27
   2013-Nov-24
   2013-Dec-29

import sys import calendar

YEAR = sys.argv[-1] try:

   year = int(YEAR)

except:

   year = 2013
   YEAR = str(year)

c = calendar.Calendar(firstweekday = 0) # Sunday is day 6.

result = [] for month in range(0+1,12+1):

   MON = calendar.month_abbr[month]
   # list of weeks of tuples has too much structure
   # Use the overloaded list.__add__ operator to remove the week structure.
   flatter = sum(c.monthdays2calendar(year, month), [])
   # make a dictionary keyed by number of day of week,
   # successively overwriting values.
   SUNDAY = {b: a for (a, b) in flatter if a}[6]
   result.append('{}-{}-{:2}'.format(YEAR, MON, SUNDAY))

print('\n'.join(result)) </lang>

Racket

<lang racket>

  1. lang racket

(require srfi/19 math)

(define (days-in-month m y)

 (define lengths #(0 31 #f 31 30 31 30 31 31 30 31 30 31))
 (define d (vector-ref lengths m))
 (or d (days-in-feb y)))

(define (leap-year? y)

 (and (divides? 4 y)
      (or (not (divides? 100 y))
          (divides? 400 y))))

(define (days-in-feb y)

 (if (leap-year? y) 29 28))

(define (last-day-in-month m y)

 (make-date 0 0 0 0 (days-in-month m y) m y 0))

(define (week-day date)

 (define days #(sun mon tue wed thu fri sat))
 (vector-ref days (date-week-day date)))

(define (last-sundays y)

 (for/list ([m (in-range 1 13)])
   (prev-sunday (last-day-in-month m y))))

(define 24hours (make-time time-duration 0 (* 24 60 60)))

(define (prev-day d)

 (time-utc->date
  (subtract-duration 
   (date->time-utc d) 24hours)))

(define (prev-sunday d)

 (if (eq? (week-day d) 'sun)
     d
     (prev-sunday (prev-day d))))

(for ([d (last-sundays 2013)])

 (displayln (~a (date->string d "~a ~d ~b ~Y"))))

</lang>

Output:
Sun 27 Jan 2013
Sun 24 Feb 2013
Sun 31 Mar 2013
Sun 28 Apr 2013
Sun 26 May 2013
Sun 30 Jun 2013
Sun 28 Jul 2013
Sun 25 Aug 2013
Sun 29 Sep 2013
Sun 27 Oct 2013
Sun 24 Nov 2013
Sun 29 Dec 2013

REXX

This REXX example is an exact replication of the Rosetta Code

  • find last Fridays of each month for any year

except for the innards of the first DO loop.

The   lastDOW   subroutine can be used for any day-of-the-week for any month for any year. <lang rexx>/*REXX program displays dates of last Sundays of each month for any year*/ parse arg yyyy

                  do j=1 for  12
                  _ = lastDOW('Sunday', j, yyyy)
                  say right(_,4)'-'right(j,2,0)"-"left(word(_,2),2)
                  end  /*j*/

exit /*stick a fork in it, we're done.*/ /*┌────────────────────────────────────────────────────────────────────┐

 │ lastDOW:  procedure to return the date of the  last day-of-week of │
 │           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.     │
 │ I.E.:   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     ...     12=December    │
 │ or the English  name  of the month,  with a minimum length that    │
 │ causes no ambiguity.    I.E.:  Jun  for June,   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 to be in the current century,  and    │
 │ there is no windowing for a two-digit year).                       │
 │ If omitted  [or an asterisk(*)],  the current year is used.        │
 │ Years < 100   must be specified with  (at least 2)  leading zeroes.│
 │                                                                    │
 │ Method used: find the "day number" of the 1st of the next month,   │
 │ 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 │
 │ then obtained straightforwardly,   or  via subtraction.            │
 └────────────────────────────────────────────────────────────────────┘*/

lastdow: procedure; arg dow .,mm .,yy . /*DOW = day of week*/ parse arg a.1,a.2,a.3 /*orig args, errmsg*/ 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 if arg()>3 then call .er 'arguments specified',4

 do j=1 for 3                                       /*any plural args ?*/
 if words(arg(j))>1       then call .er 'is illegal:',j
 end

dw=pos(' 'dow,$) /*find day-of-week*/ if dw==0 then call .er 'is invalid:',1 if dw\==lastpos(' 'dow,$) then call .er 'is ambigious:',1

if datatype(mm,'month') then /*if MM is alpha...*/

 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(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 /*tell error, and */

 say word('day-of-week month year excess',arg(2)) arg(1) a._
 say; exit 13                                       /*... then exit.   */</lang>
Output:

when using the default input (the current year, 2013)

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

Ruby

<lang ruby>require 'date'

def last_sundays_of_year(year = Date.today.year)

 (1..12).map do |month|
   d = Date.new(year, month, -1) # -1 means "last".
   d -= 1 until d.sunday?
   d
 end

end

puts last_sundays_of_year(2013)</lang>

Output:
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

Results before the year 1581 may differ from other languages - the Date library takes the Julian reform into account.

Scala

<lang Scala>object FindTheLastSundayOfEachMonth extends App {

 import java.util.Calendar._
 val cal = getInstance
 def lastSundaysOf(year: Int) =
   (JANUARY to DECEMBER).map{month =>
     cal.set(year, month + 1, 1) // first day of next month
     (1 to 7).find{_ => cal.add(DAY_OF_MONTH, -1); cal.get(DAY_OF_WEEK) == SUNDAY}
     cal.getTime
   }
 val year = args.headOption.map(_.toInt).getOrElse(cal.get(YEAR))
 val fmt = new java.text.SimpleDateFormat("yyyy-MM-dd")
 println(lastSundaysOf(year).map(fmt.format) mkString "\n")

}</lang>

Java 8

<lang Scala>object FindTheLastSundayOfEachMonth extends App {

 def lastSundaysOf(year: Int) = (1 to 12).map{month =>
   import java.time._; import java.time.temporal.TemporalAdjusters._
   LocalDate.of(year, month, 1).`with`(lastDayOfMonth).`with`(previousOrSame(DayOfWeek.SUNDAY))}
 val year = args.headOption.map(_.toInt).getOrElse(java.time.LocalDate.now.getYear)
 println(lastSundaysOf(year) mkString "\n")

}</lang>

Seed7

Uses the libraries time.s7i and duration.s7i. Applicable to any day of the week, cf. [[2]].

<lang seed7>$ include "seed7_05.s7i";

 include "time.s7i";
 include "duration.s7i";

const proc: main is func

 local
   var integer: weekday is 1; # 1 for monday, 2 for tuesday, and so on up to 7 for sunday.
   var integer: year is 0;
   var integer: month is 1;
   var time: aDate is time.value;
   var time: selected is time.value;
 begin
   if length(argv(PROGRAM)) <> 2 then
     writeln("usage: lastWeekdayInMonth weekday year");
     writeln("  weekday: 1 for monday, 2 for tuesday, and so on up to 7 for sunday.");
   else
     weekday := integer parse (argv(PROGRAM)[1]);
     year := integer parse (argv(PROGRAM)[2]);
     for month range 1 to 12 do
       aDate := date(year, month, 1);
       while aDate.month = month do
         if dayOfWeek(aDate) = weekday then
           selected := aDate;
         end if;
         aDate +:= 1 . DAYS;
       end while;
       writeln(strDate(selected));
     end for;
   end if;
 end func;</lang>
Output:

when called with s7 rosetta/lastWeekdayInMonth 7 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

Tcl

<lang tcl>proc lastSundays Template:Year "" {

   if {$year eq ""} {

set year [clock format [clock seconds] -gmt 1 -format "%Y"]

   }
   foreach month {2 3 4 5 6 7 8 9 10 11 12 13} {

set d [clock add [clock scan "$month/1/$year" -gmt 1] -1 day] while {[clock format $d -gmt 1 -format "%u"] != 7} { set d [clock add $d -1 day] } lappend result [clock format $d -gmt 1 -format "%Y-%m-%d"]

   }
   return $result

} puts [join [lastSundays {*}$argv] "\n"]</lang>

Output:

When called as: “tclsh lastSundays.tcl 2013” (or with the year argument omitted during 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-20
2013-11-24
2013-12-29

VBScript

Works with: Windows Script Host version *

<lang VBScript> strYear = WScript.StdIn.ReadLine

For i = 1 To 12 d = DateSerial(strYear, i + 1, 1) - 1 WScript.Echo d - Weekday(d) + 1 Next </lang>

zkl

The program from [[3]] solves this task, as well.

Output:
var [const] D=Time.Date;
lastDay(2013,D.Sunday)
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