Relevant

Monday, 27 October 2014

Solutions No. 002: EEG 206: Program that calculates which day of the year a given date falls on

That program where you enter a date and it tells you that it's the nth day of the year

Code Notes: 
  • The program's name is "DateConv".
  • The date is entered as a string.
  • You have to enter the date in the proper format (DD/MM/YYYY). e.g. 27/10/2014.
  • Please check up on data casting (You explicitly change a variable from one type to another).
  • You can copy & paste the code, but in case of incasity & insanity , I'm also posting a link to the .cpp file.
  • The code I am posting works, but of course, due to compatiblity issues and plain old human error, things might go wrong. If and when they do go wrong, post a comment below the relevant post or just contact me.
  • I try to make my programs as efficient as possible, at times at the risk of simplicity; but I am not perfect, no one is. Please I'm begging you feel free to post suggestions for improvement
Code Process:
  1. I create a character array with size of 11 characters.
  2. Why 11? I hear you ask. Simple. 2 for day, 2 for month, 4 for year, and one extra for the '\0' that ends the string.
  3. Now to obtain the values from the string, some madness happens. There is something known as the ASCII table (pronounced "askee") where every letter and number has a numerical value (e.g. capital letter 'A' is 65). Remember, even though you entered numbers as the date, they are still characters.
  4. The character '0' is number 48 on the ASCII table, '1' is 49, '2' is 50... e.t.c.
  5. Keep this in mind.

  1. Now, to get the int values of the date from the array, ASCII comes in. For the first character: date[0], which is '2', we use data casting to transform it into its ASCII value (50). We then subtract 48 from it to make it 2.
  2. Cast it to int -----> subtract 48 -------> You have the int value.
  3. Now remember, the day is 27; date[0] is 2, date [1] is 7; to get 27 from 2&7, we say: 27 = (2*10) + (7*1); that is, int day = (date[0]*10) + (date[1]*1); but remember to data cast & subtract. You'll see it in the code.
  4. Same thing for month;
  5. For year, int year = (date[6]*1000) +...+ (date[9]*1);
  6. Now, we have int values for day, month and year.
  7. The month with the least number of days is February (28 days). That means all other months have some days extra. We then create an array containing the values of these extra days.
  8. All leap years are divisible by 4. Therefore we find year%4 and if the result is zero, it is a leap year. If it is a leap year, February has 29 days (that is, one extra day). We then modify the appropriate value in the extradays array.
  9. Now, to find which day of the year it is, we calulate the number of days in the month(s) before it and then add the day of the month. E.g. if it is April 21, We find the number of days in Jan, Feb, Mar, and then add 21 (the day it is in April).
  10. If it is april, the value of "month" is 4 therefore, we multiply (month-1) by 28 and then add the extra days (extradays[0],[1],[2] up to [month-1]). This gives us the number of days in the months before april. Use loops and "+=" to accomplish this.
* This has been an extremely long post and I am very sorry I had to make it so complex. If anyone wants me to make a simpler albeit less efficient version, please request in the comments.

And now, the code:


#include <iostream>

int DateConv(char[]);

using namespace std;

int main()
{
int day, month, year;
char date[11];
cout << "Please enter the date in the format DD/MM/YYYY: ";
enterdate: cin.getline(date,11, '\n'); // It has a label so as to revert back here with a goto statement in case of an error
if (DateConv(date) == -1)
goto enterdate;
int val = DateConv(date)%10;
cout << endl << "The day specified is the " << DateConv(date);
cout << (((val > 3) || (val == 0)) ? ("th") : ((val == 3) ? ("rd") : ((val == 2) ? ("nd") : ("st"))));
cout << " day of the year " << date[6] << date[7] << date[8] << date[9] << endl;
main(); // Recursion for the main function (To loop back)
return 0;
}

int DateConv(char date[])
{
// Get integer values for the day, month and year from the character string by use of data casting and the ASCII table
int day = ((((int)(date[0])) - 48) * 10) + (((int)(date[1])) - 48);
int month = ((((int)(date[3])) - 48) * 10) + (((int)(date[4])) - 48);
int year = ((((int)(date[6])) - 48) * 1000) + ((((int)(date[7])) - 48) * 100) + ((((int)(date[8])) - 48) * 10) + (((int)(date[9])) - 48);

int extradays[12]{3, 0, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3}; // The number of days more than 28 that each month has
if (!(year % 4)) // For leap years
extradays[1] = 1; // February has 29 days so therefore, 1 extra
// Handling errors in the date input
if (day >(extradays[month - 1] + 28)) // Check if there are too many days in a month (more than 28/29/30/31)
{
cout << "Error. There are too many days in the month.\n\nPlease re-enter the date: ";
return -1;
}
if (month > 12) // Check if there are more than 12 months
{
cout << "Error. Maximum of 12 months in a year.\n\nPlease re-enter the date: ";
return -1;
}
int sumex{};
for (int i = 0; i < (month - 1); i++)
sumex += extradays[i];
int dayval = ((month - 1) * 28) + day + sumex; // The integer value for which day of the year it is
return dayval;
}
* Download the code: DateConv
* Remember, Arrays, loops; powerful together

No comments:

Post a Comment