| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Display Modes |
|
#1
|
|||
|
|||
|
Logic to Convert Days From 1800 to a Date (Month, Day, Year)
Hi,
This is really a logic problem more so than a stright up C++ problem. For class I have written a program that takes dates from a text file and then finds the number of days from January 1st 1800 that days is. The program also has to be able to take the number (that number being the number of days since 1800 that date is) and convert it back into a date (in other words finding the month, day, year and day of the week). What makes this quite a bit trickier is taking into account leap years and the effect they have. I can't seem to figure out how to find the date from the number of days. If you want to look at it below is the function that I wrote that finds the number of *from January 1st a date is: Code:
int DaysFrom1800::numDaysFrom1800 (int day, int month, int year) {
// Declare leapCount variable to keep track of number of leap years and days variable
// * *to store number of days
int leapCount =0;
int days = 0;
// For loop to find the number of leap years
for (int i=0; i < year; i++) {
* * * *if (leapCheck(i))
* * * * * *leapCount ++;
* *}
// Check to see if current year is a leap year
bool thisYear = leapCheck(year);
//Find the Number of Days From Complete Years
days = ((year-1800-leapCount)*365) + (leapCount*366);
// Find the Number of Days From the Months
switch (month) {
case 1:
* *days = days + day;
* *break;
case 2:
* *if (day < 28)
* * * *days = days + 31 + day;
* * * *if (thisYear)
* * * * * *days = days + 31 + 29;
* * * *break;
case 3:
* *if (thisYear)
* * * *days = days +31+29+ day;
* * * *else
* * * *days = days + 31 + 29 + day;
* * * *break;
case 4:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + day;
* * * *else
* * * *days = days + 31 + 28 + 31 + day;
* * * *break;
case 5:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + day;
* *else
* * * *days = days +31 + 28 + 31 + 30 + day;
* *break;
case 6:
* *if (thisYear)
* * * *days = days +31 + 29 + 31 + 30 + 31 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 29 + 31 + day;
* *break;
case 7:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + day;
* *break;
case 8:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + day;
* *break;
case 9:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + day;
* *break;
case 10:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
* *break;
case 11:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + day;
* *break;
case 12:
* *if (thisYear)
* * * *days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
* *else
* * * *days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
* *break;
}
return days;
}
If somone could help me in figuring out the logic of how to convert the day number back to a date (and find the day of the week, we do know that January 1st 1800 is a Wednesday) that would be awesome. thanks, -Scott |
|
#2
|
||||
|
||||
|
where are you getting month? I dont see a declaration of it..
also, could you show me an example of your input? Is the snippet of code you gave us from a function or is it in the main portion of your code? |
|
#3
|
|||
|
|||
|
Quote:
Month is being passed to this function as an argument. This snippet is a function. If you're interested in it the code the the entire program is: Code:
/* Name: Scott Kamen
Student Number: 9054
Assignment number and description: Lab 08 Assignment (Read dates from a text file and compute
how many days that date is from January 1st, 1800)
Lab Instructor: Huma Kamal
Lab Day and Time: Wed at 6:00 */
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
// Prototypes
bool leapCheck (int year);
// DaysFrom1800 Class Definition
class DaysFrom1800 {
public:
DaysFrom1800();
int numDaysFrom1800 (int day, int month, int year);
int fillDaysArray (int numberOfDates, int day[], int month[], int year[], string textArray[], DaysFrom1800 numbers []);
void printDaysSince1800 (DaysFrom1800 numbers[]);
private:
int daysSince;
};
int main () {
// Declare Day, Month and Year Array to store Date Values
int day[200];
int month [200];
int year [200];
// Declare Variable for Number of Dates Gathered from Text File
int numberOfDates = 0;
// Declare Array of DaysFrom1800 objects to store those objects
DaysFrom1800 numbers[200];
// Declare Dummy DaysFrom1800 object to make call to the fillDaysArray function
DaysFrom1800 dummy;
// Declare Array of Strings to store Text From Text File
string textArray [200];
// Call fillDaysArray from dummy object and store returned value in numberOfDates
numberOfDates = dummy.fillDaysArray (numberOfDates, day, month, year, textArray, numbers);
// Test Output
for (int i=0; i <numberOfDates; i++) {
cout << month[i] << "/" << day[i] << "/" << year[i] << endl;
}
// Test Output for Object Array
for (i=0; i < numberOfDates; i++) {
numbers[i].printDaysSince1800(numbers);
cout << endl;
}
// Test Output for String Array
for (i = 0; i <numberOfDates; i++) {
cout << textArray[i];
cout << endl;
}
return 0;
}
// Defualt Constructer for DaysFrom1800 Class
DaysFrom1800::DaysFrom1800() : daysSince (0) {
// Nothing to be done here...
}
int DaysFrom1800::numDaysFrom1800 (int day, int month, int year) {
// Declare leapCount variable to keep track of number of leap years and days variable
// to store number of days
int leapCount =0;
int days = 0;
// For loop to find the number of leap years
for (int i=0; i < year; i++) {
if (leapCheck(i))
leapCount ++;
}
// Check to see if current year is a leap year
bool thisYear = leapCheck(year);
days = ((year-1800-leapCount)*365) + (leapCount*366);
switch (month) {
case 1:
days = days + day;
break;
case 2:
if (day < 28)
days = days + 31 + day;
if (thisYear)
days = days + 31 + 29;
break;
case 3:
if (thisYear)
days = days +31+29+ day;
else
days = days + 31 + 29 + day;
break;
case 4:
if (thisYear)
days = days + 31 + 29 + 31 + day;
else
days = days + 31 + 28 + 31 + day;
break;
case 5:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + day;
else
days = days +31 + 28 + 31 + 30 + day;
break;
case 6:
if (thisYear)
days = days +31 + 29 + 31 + 30 + 31 + day;
else
days = days + 31 + 28 + 31 + 29 + 31 + day;
break;
case 7:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + day;
break;
case 8:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + day;
break;
case 9:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + day;
break;
case 10:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
break;
case 11:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + day;
break;
case 12:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + 30 + 31 + day;
break;
}
return days;
}
void DaysFrom1800::printDaysSince1800 (DaysFrom1800 numbers[]) {
cout << daysSince;
}
int DaysFrom1800::fillDaysArray (int numberOfDates, int day[], int month[], int year[], string textArray[], DaysFrom1800 numbers []) {
// Declare Stream and Open Text File
ifstream inStream;
inStream.open("in.txt");
// Test Input File
if (inStream.fail()) {
cerr << "Can't open file!\n";
exit(1);
}
// Declare and Initialize Index Variable
int i=0;
// Temp Character Array
char temp [100];
while (!inStream.eof()) {
// Get Dates from Text File Storing Info in day, month and year variables
inStream >> month[i] >> day[i] >> year[i];
inStream.get(temp, 100, '\n');
textArray[i]=temp;
// Increase Index by One
i++;
}
// Assign Index Value to numberOfDates variable to be returned in this function
numberOfDates = i;
// For Loop to Calculate Number of Days for Each Day and Store in Object Array
for (i=0; i<numberOfDates; i++) {
numbers[i].daysSince = numDaysFrom1800 (day[i], month[i], year[i]);
}
// Return Intever Variable numberOfDays
return numberOfDates;
}
bool leapCheck (int year) {
if ((year%400==0)||(year%4==0))
return true;
else
return false;
}
|
|
#4
|
|||
|
|||
|
Hey skamen, I love these types of problems, so I decided to spend some time on this. First off, I've found some errors in your "numDaysFrom1800" function:
1) Your loop near the beginning of the function: for (int i=0; i < year; i++) {... needs to start at 1800, NOT 0, otherwise you're counting all leap years from year 0 to the current year. 2) In your case statement, case 3 should use 28 in the else part, not 29: CORRECTED: Code:
case 3: if (thisYear) days = days + 31 + 29+ day; else days = days + 31 + 28 + day; break; also in the case statement, the months after july all have the wrong number of days. July has 31 days which is right, but so does august, then sept has 30 and so on... CORRECTED: Code:
case 9:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + day;
break;
case 10:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
break;
case 11:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
break;
case 12:
if (thisYear)
days = days + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
else
days = days + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
break;
NOTE: Your code as written is going to give you a "daysSince" of 1 for Jan. 1, 1800. I'm not sure if you need it to be zero or not. I've written all my code to be consistent with yours in this respect. Your leapCheck function also needed a little something. To check if given year is a leap year you check to see if it is divisible by 4, which you've done. The part that needs fixing is when that given year is a century (ie ends in 00, eg 1800, 1900...). A century divisible by 4 is not always a leap year, only if it also divisible by 400. I see you've tried to account for this with: Code:
if ((year%400==0)||(year%4==0)) However, centuries like 1800 and 1900, which are not leap years, slip through. The year%400 part fails, which is correct, but your code then goes on to check the same year in the year%4 part, which does succeed, and goes on to count it as a leap year. Below I've corrected this to account for the checking of centuries: Code:
bool leapCheck (int year) {
if ((year % 100) == 0) {
//is century
if ((year % 400) == 0)
return true;
}
else
if ((year % 4) == 0)
return true;
return false;
}
Ok, errors fixed. Now, on with your questions. QUESTION 1 (Days of week): This one was quite easy. All you need is the number of days since Jan 1, 1800, which we have calculated, and a starting point for the days of the week. You know that Jan 1, 1800 was a wednesday. The day of the week can be figured out by this one line function: Code:
int DayOfWeek(int days) {
return (days-1) % 7;
}
I should explain. I'm using the numbering system: Wednesday = 0, Thursday = 1, Friday = 2, Saturday = 3, Sunday = 4, Monday = 5, Tuesday = 6 I subtract one from days to allow the use of this numbering system (eg if days = 1, this is the first day January 1, 1800, which is a wednesday, which is zero after the subtraction.). The reason I do this is so that mod 7 will give us one of a possible seven values (0,1,2,3,4,5,or 6) beginning with wednesday. If you don't subtract one, then Tuesday is zero. I just thought subtracting one made more sense since for our purpose, the beginning of time is Wednesday Jan 1, 1800. You could then use a switch if you like to display the day of week as a string. Sorry, that probably confused you more than helped. QUESTION 2 (convert days since back to date): This one's a little bit more work, and I can't just give the code outright, however I will explain how I did it. 1) variables: int curYear = 1800; int daysleft = days; //days is the number of days given What you need to do is break up daysleft into how many whole years, and how many days in the current year, which is then used to figure out the month and day. Goes something like this: while daysleft is greater than or equal to maximum days in a year (ie 366), determine if curYear is a leap year (you've got a function for this). Subtract number of days in curYear from days left. After this looping, curYear will hold the year you're looking for, and daysleft will tell you how many days into this year you are. 2) Determine month and day. I'll give you part. What you need to do, is to write the function "daysInMonth", that determines, you guessed it, how many days are in the month given by the variable "mon". Code:
int mon = 1;
int dim = 0;
bool isLeapYear = leapCheck(curYear);
while (daysleft > (dim = daysInMonth(mon, isLeapYear))) {
daysleft -= dim;
mon++;
}
At the end of this daysleft holds the day of the month, mon holds the number of the month (Jan = 1...). Again you can use a switch statement to turn these integers into strings. That's about it, this has turned into one monster of a post. Hope this all helped, if you haven't got it already. kernel mustard |
![]() |
| Viewing: Dev Articles Community Forums > Programming > C/C++ Help > Logic to Convert Days From 1800 to a Date (Month, Day, Year) |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|