randomfox (randomfox) wrote,
randomfox
randomfox

Yearly Calendar in C#

C# program that prints out the calendar for one year. It uses Zeller's congruence to determine the day of the week for each date, and so it is incorrect for any date before the start of the Gregorian calendar.


// calendar - Perpetual calendar program
// Author: Po Shan Cheah
// Last updated: August 19, 2003
// 
// Compile with: csc /doc:calendar.xml calendar.cs

namespace Calendar {

using System;

class Calendar {
    const string USAGE = "Usage: calendar year (1-9999)";

    /// <summary>Uses Zeller's congruence to determine the day of the week
    /// for a specified date.</summary>
    /// <param name="day">Day of month</param>
    /// <param name="month">Month of the year</param>
    /// <param name="year">Year</param>
    /// <returns>0-6 representing Sun-Sat</returns>
    int dayofweek(int day, int month, int year) {
	if (month <= 2) {
	    month += 10;
	    --year;
	}
	else
	    month -= 2;

	int century = year / 100;
	int yr = year % 100;

	return ((26 * month - 2) / 10 + day + yr + yr / 4 + century / 4 +
		203 - 2 * century) % 7;
    }

    /// <summary>Is this a leap year?</summary>
    /// <param name="year">Year to check</param>
    /// <returns>true if that year is a leap year</returns>
    bool leapyear(int year) {
	return (year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0);
    }

    /// <summary>Get last day of the month</summary>
    /// <param name="month">Month of year</param>
    /// <param name="year">The year</param>
    /// <returns>Last day of that month</returns>
    int getmaxday(int month, int year) {
	int[] monthlen = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	int maxday = monthlen[month - 1];
	if (month == 2 && leapyear(year))
	    ++maxday;
	return maxday;
    }

    /// <summary>Generates a yearly calendar</summary>
    /// <param name="year">The year for which the calendar should be
    /// generated.</param>
    void GenerateCalendar(int year) {
	string[] monthnames = { 
	    "January", "February", "March", "April", "May", "June", "July",
	    "August", "September", "October", "November", "December" 
	};

	Console.WriteLine("{0,37}", year);
	Console.WriteLine();

	for (int row = 0; row <= 3; ++row) {
	    for (int col = 0; col <= 2; ++col) {
		string monthname = monthnames[row * 3 + col];
		int spacebefore = (19 - monthname.Length) / 2 + 2;

		Console.Write("{0," + spacebefore.ToString() + "}", "");
		Console.Write(monthname);
		Console.Write("{0," + (24 - monthname.Length - 
				       spacebefore).ToString() + "}", "");
	    }
	    Console.WriteLine();
	    Console.WriteLine();
	    
	    for (int col = 0; col <= 2; ++col) 
		Console.Write("  S  M  T  W  T  F  S   ");
	    Console.WriteLine();

	    for (int vcell = 0; vcell <= 5; ++vcell) {
		for (int col = 0; col <= 2; ++col) {
		    int month = row * 3 + col + 1;
		    int maxday = getmaxday(month, year);
		    for (int hcell = 0; hcell <= 6; ++hcell) {
			int day = vcell * 7 + hcell + 1 -
			    dayofweek(1, month, year);
			if (day > 0 && day <= maxday)
			    Console.Write("{0,3}", day);
			else
			    Console.Write("   ");
		    }
		    Console.Write("   ");
		}
		Console.WriteLine();
	    }
	    Console.WriteLine();
	}
    } // GenerateCalendar

    static int Main(string[] args) {
	if (args.Length < 1) {
	    Console.Error.WriteLine(USAGE);
	    return 1;
	}

	int year;

	try {
	    year = int.Parse(args[0]);
	}
	catch (FormatException) {
	    Console.Error.WriteLine(USAGE);
	    return 1;
	}

	if (year < 1 || year > 9999) {
	    Console.Error.WriteLine(USAGE);
	    return 1;
	}

	new Calendar().GenerateCalendar(year);

	return 0;
    }
} // class Calendar

}
// The End


Example:
C:\cs>calendar 2005
                                 2005

        January                February                  March

  S  M  T  W  T  F  S     S  M  T  W  T  F  S     S  M  T  W  T  F  S
                    1           1  2  3  4  5           1  2  3  4  5
  2  3  4  5  6  7  8     6  7  8  9 10 11 12     6  7  8  9 10 11 12
  9 10 11 12 13 14 15    13 14 15 16 17 18 19    13 14 15 16 17 18 19
 16 17 18 19 20 21 22    20 21 22 23 24 25 26    20 21 22 23 24 25 26
 23 24 25 26 27 28 29    27 28                   27 28 29 30 31
 30 31

         April                    May                    June

  S  M  T  W  T  F  S     S  M  T  W  T  F  S     S  M  T  W  T  F  S
                 1  2     1  2  3  4  5  6  7              1  2  3  4
  3  4  5  6  7  8  9     8  9 10 11 12 13 14     5  6  7  8  9 10 11
 10 11 12 13 14 15 16    15 16 17 18 19 20 21    12 13 14 15 16 17 18
 17 18 19 20 21 22 23    22 23 24 25 26 27 28    19 20 21 22 23 24 25
 24 25 26 27 28 29 30    29 30 31                26 27 28 29 30


         July                   August                 September

  S  M  T  W  T  F  S     S  M  T  W  T  F  S     S  M  T  W  T  F  S
                 1  2        1  2  3  4  5  6                 1  2  3
  3  4  5  6  7  8  9     7  8  9 10 11 12 13     4  5  6  7  8  9 10
 10 11 12 13 14 15 16    14 15 16 17 18 19 20    11 12 13 14 15 16 17
 17 18 19 20 21 22 23    21 22 23 24 25 26 27    18 19 20 21 22 23 24
 24 25 26 27 28 29 30    28 29 30 31             25 26 27 28 29 30
 31

        October                November                December

  S  M  T  W  T  F  S     S  M  T  W  T  F  S     S  M  T  W  T  F  S
                    1           1  2  3  4  5                 1  2  3
  2  3  4  5  6  7  8     6  7  8  9 10 11 12     4  5  6  7  8  9 10
  9 10 11 12 13 14 15    13 14 15 16 17 18 19    11 12 13 14 15 16 17
 16 17 18 19 20 21 22    20 21 22 23 24 25 26    18 19 20 21 22 23 24
 23 24 25 26 27 28 29    27 28 29 30             25 26 27 28 29 30 31
 30 31

Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments