UMBC CS 201,Spring 05
UMBC CMSC 201 Spring '05 CSEE | 201 | 201 S'05 | lectures | news | resources |discussion| help

CMSC 201
Programming Project One
Manipulating Dates

v2.0

Out: Wednesday 23 February 2005
Due: Before Midnight, Tuesday 8 March 2005

Engineering Change Notices

An engineering change notice (ECN) describes changes to the design of an engineeringed object made after the original design is released.

  • ECN1 - The PrintInterval function now takes two dates.

The Objective

The objective of this assignment is to get you started writing programs in C in the UNIX environment. Its main emphasis is design, so we will be designing the project together in class. This project will also give you practice writing functions, loops, switch statements and using separate compilation.

The Background

You are just beginning to learn to program in C and you want to challenge yourself by writing a large enough program to test your design skills and to give you practice with separate compilation. You decide to write a program that you can release as public domain software (give away to others). It should be something that is a little bit useful and maybe even a little bit fun ... something to do with dates and calendars.

It would be useful to have a kind of perpetual calendar -- one that you can use to do things like the following:

  • find out the day of week for any particular date in the past or the future (so you can find out what kind of person you are based on the day of the week on which you were born);
  • Print a calendar for any given month or year, past or future;
  • Compute the number of days between any two dates (e.g., how long till the singularity?)

We are all familiar with the basic concepts involved -- days, months, years -- but some of the details are messy and can be blamed on the orbits of the Sun and the Moon and how our ancient ancestors tried to make sense of it all. The months differ in their lengths and so do the years (leap years having 366 and regular years 365 days). A date's "day of the week" name depends on a seven day cycle rooted in ancient religions. But, it turns out that the details are not too complex and it's pretty easy to support the simple functions above, with some limitations.

Calendars have gone through many reforms. The one used in the "West" and for most of the world, at least for business, was last reformed in 1752 So, if we restrict ourselves to dates after Sunday, December 31, 1752, we will only have one set of rules to work with. If you are interested in the techniques for representing dates going back to Monday, January 1, 4713 BC, check out the Julian day concept.

The Task

Design (to be done in class) and code a project that after printing a greeting to the user, presents the user with a menu and allows her to choose any of six different options, including quit. After performing the option, the user should be presented with the menu again, so that she can continue to make choices.

The Design

Since you are distributing this software to others, you must use separate compilation and provide the interface for the user. This is in the form of a well commented header (.h) file. You must have three files. The file that contains main( ) MUST be called proj1.c; the file containing the function definitions MUST be called dates.c and the header file MUST be called dates.h.

You are required to use a switch statement to handle the menu requests. There are also other places where the switch statement is the appropriate choice too.

You must adhere to the design given in class. The function prototypes given in the design document must be used and may NOT be altered in anyway

Here is the design document you must follow. It defines the functions you should implement and gives their prototypes. It also shows the constants your program should use. In future projects, we will ask you to develop you own design and submit that as the first part of your project. After that you will implement the design, debug the result and submit that. But, for this first assignment, you must use the design we provide. That means you have to implement the functions as we have specified and use the defined constants we have given you.

Notes and suggestions

Here are some notes on some of the functions that will be in your program.

The Anchor date. Your program will only work for dates after December 31, 1752, which we will call the anchor date. This date is specified using the constants ANCHOR_DAY, ANCHOR_MONTH and ANCHOR_YEAR. In addition, we know that this date was a Sunday, so define the constant ANCHOR_DAY_OF_WEEK as 0. A key property of any date is the number of days since the anchor. Knowing this, we can easily compute the day of week of a date or the interval between any two dates.

DaysSinceAnchor(day,month,year) returns the number of days since the anchor. This can be computed as the number of days in each year between the anchor year and year (exclusive) plus the"day number" of the given date, as computed by DayNumber(day, month, year).

DayNumber(day,month,year) returns the number of the given day in the year. e.g., 1/1/2005 is 1 and 12/31/2005 is 365. It's pretty easy to compute.

DaysInYear(year) returns the number of days in the given year and is even easier to compute if you know whether or not the year is a leap year.

IsLeapYear(year) returns true (1) if the year is a leap year and false (0) otherwise. You must handle leap years properly and according to the usual rule: "A year is a leap year if it is evenly divisible by 4 but not also evenly divisible by 100, however a year is also a leap year if it is evenly divisible by 400." Thus 2000 is was a leap year as is 2004. 2005 is not a leap year, nor will 2100 be one.

DaysInMonth(month,year) returns the number of days in the given month and year. A piece of cake.

DaysBetween(d1,m1,y1,d2,m2,y2) returns the number of days between the two dates as a positive number. You can do this easily with two calls to DaysSinceAnchor and some math. You will find the abs function in the stdlib library useful -- see man abs.

DayOfWeek(day,month,year) returns an integer representing the date's day of week (e.g., 0 for Sunday, 6 for Saturday). Since we know the day of the week of the anchor, we can easily compute this by finding the days since the anchor and taking this modulo seven and adding the anchor's day of week.

PrintMonth(month, year) takes a month and year and prints a minimal calendar for that month. For example, PrintMonth(2,2005) should print something like this:


     February 2005
 SU MO TU WE TH FR SA
        1  2  3  4  5
  6  7  8  9 10 11 12
 13 14 15 16 17 18 19
 20 21 22 23 24 25 26
 27 28
Here are some suggestions: The first two lines should be easy to figure out. The calendar block has seven "logical" columns, each of which is three spaces wide. Print each day's number using "%3d" so it's printed using three "spaces". Before you begin printing the dates, you will have to figure out how many of the "logical" columns to "skip". That is, if we know we want to start printing on a Tuesday (day=2 corresponding to the third logical column), we'll have to print two set of three spaces to skip over the first two logical columns. Now we're ready to start printing the numbers for the days in the month. How many are there? Use the DaysInMonth function to find out. To print them all, just loop from 1 to the number of days and print them using %3d. Each time you print a number, increment a separate counter to keep track of which logical column you have printed. When you've printed the day in the seventh logical column, then print a newline. That's it.

PrintYear(year) is easy once you have PrintMonth. Can you spell f-o-r?

PrintInterval(d1,m1,y1,d2,m2,y2) computes the number of days between the two dates and prints its absolute value.

Managing complexity

Computer programs, even relatively simple ones like Project One, are complicated artifacts and managing the complexity of designing, implementing and debugging them is probably the biggest reason why programming is hard. Our field has developed many techniques and tools to help you manage the complexity. One of the simplest techniques, and one you can use now, is the use of stubs. A stub is a "dummy definition" for a function that allows you to write, test and debug the rest of the program before you get to the task of developing the stubbed function. For example, for Project One, you might put off the subtask of writing DaysSinceAnchor by using the following stub definition:


/* STUB! RETURNS 3 */
int DaysSinceAnchor (int day, int month, int year) {
   return 3;
   }
A slightly better stub might be one that returns a random integer between one and 10,000, which will better 'exercise' your code in other functions that need to know the day of week (e.g., PrintDate, PrintMonth). To use this version, you would have to add #include <stdlib.h> to your dates.c file, of course.

/* STUB STILL, BUT BETTER: RETURNS RANDOM NUMBER BETWEEN 1 AND 10K */
int DaysSinceAnchor (int day, int month, int year) {
   return (rand() % 10000) + 1;
   }

Coding standards

You must follow the CMSC201 coding standards, see the 201 projects page for details and a description of how we will evaluate and grade your work.

Sample Run

We've provided you with a sample run demonstrating how our model solution works. Although your output need not be identical to the above, all information (including the greeting) must be present. This is definitely NOT a complete test of the program. Your testing should be much more extensive. You may run the sample executable found at
/afs/umbc.edu/users/s/b/sbogar1/pub/
It's called p1a.out

We'll give your program a good workout to see if it is appropriately robust and works for all reasonable inputs.

Submitting the Program

  • You are to use separate compilation for this project, so you will be submitting three files, proj1.c, dates.c and dates.h
  • Your C source code file that contains main( ) MUST be called proj1.c.
  • The file which contains the function definitions MUST be called dates.c and the header file MUST be called dates.h
  • To submit your project, type the following at the Unix prompt. Note that the project name starts with uppercase 'P'.
    submit cs201 Proj1 proj1.c dates.c dates.h
  • To verify that your project was submitted, you can execute the following command at the Unix prompt. It will show all files that you submitted in a format similar to the Unix 'ls' command.
    submitls cs201 Proj1
  • The files must be submitted before Midnight at the end of Tuesday 8 March 2005.


CSEE | 201 | 201 S'05 | lectures | news | resources | help |

Wednesday, 02-Mar-2005 11:12:17 EST