fbpx

C++: Find the Last Sunday of Each Month

Bjarne-stroustrup
 

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

#include <windows.h>
#include <iostream>
#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;
}
//--------------------------------------------------------------------------------------------------
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:

#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
#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 ;
}
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

SOURCE

Content is available under GNU Free Documentation License 1.2.