Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
#include <iostream>
#include <stdio.h>
#include <iomanip>
using namespace std;
class Date
{
private:
int year;
int monthNum;
int dayNum;
public:
Date(int newYear = 1900, int newMonth = 1, int newDay = 1);
void SetDate(int ChangeYear, int ChangeMonth, int ChangeDay);
void DisplayNumerically();
void DisplayTextually();
};
int main()
{
How do i make it so when setDate is called and the parameters
are incorrect it returns the date it was trying to change
Date f(1980, 6, 8);
f.DisplayNumerically(); /// prints "06/08/1980"
f.DisplayTextually(); /// prints "June 8, 1980"
f.SetDate(1980, 6, 31); /// prints "Error: SetDate() called with invalid date information"
f.DisplayNumerically(); /// prints "06/08/1980"
f.DisplayTextually(); /// prints "June 8, 1980"*
This section right above.
return 0;
}
Date::Date(int newYear, int newMonth, int newDay)
{
year = newYear;
monthNum = newMonth;
dayNum = newDay;
if(newDay > 30)
{
cout <<"Error: Date created with invalid date information."<<endl;
year = 1900;
monthNum = 1;
dayNum = 1;
}
}
void Date::SetDate(int ChangeYear, int ChangeMonth, int ChangeDay)
{
year = ChangeYear;
monthNum = ChangeMonth;
dayNum = ChangeDay;
if(ChangeMonth > 12||ChangeDay > 30)
{
cout <<"Error: SetDate() called with invalid date information."<<endl;
year=1;
monthNum=1;
dayNum=1;
}
}
void Date::DisplayNumerically()
{
printf("%02d",monthNum);
printf("/%02d",dayNum);
printf("/%04d\n",year);
}
void Date::DisplayTextually()
{
string m;
if( monthNum == 1)
m = "January";
else if( monthNum == 2)
m = "February";
else if( monthNum == 3)
m = "March";
else if( monthNum == 4)
m = "April";
else if( monthNum == 5)
m = "May";
else if( monthNum == 6)
m = "June";
else if( monthNum == 7)
m = "July";
else if( monthNum == 8)
m = "August";
else if( monthNum == 9)
m = "September";
else if( monthNum == 10)
m = "October";
else if( monthNum == 11)
m = "November";
else if( monthNum == 12)
m = "December";
else
cout <<"Invalid month input: "<< monthNum << endl;
cout << m <<" "<<fixed<<setprecision(2)<<dayNum<<","<<year<<endl;
}
Just don't modify the date when the input is faulty:
void Date::SetDate(int ChangeYear, int ChangeMonth, int ChangeDay)
{
if(ChangeMonth > 12||ChangeDay > 30)
{
cout <<"Error: SetDate() called with invalid date information."<<endl;
}
else
{
year = ChangeYear;
monthNum = ChangeMonth;
dayNum = ChangeDay;
}
}
(I'm assuming that your validity check is only for illustration purposes.)
Related
when the first date is bigger than the second, it doesent calculate.
for example: first date 22/10/2022
second date: 15/10/2022
#include <iostream>
#include <cstdlib>
using namespace std;
class Date {
public:
Date(int d, int m, int y);
void set_date(int d, int m, int y);
void print_date();
void inc_one_day();
bool equals(Date d);
int get_day() { return day; }
int get_month() { return month; }
int get_year() { return year; }
private :
int day;
int month;
int year;
};
bool is_leap_year(int year)
{
int r = year % 33;
return r == 1 || r == 5 || r == 9 || r == 13 || r == 17 || r == 22 || r == 26 || r == 30;
}
int days_of_month(int m, int y){
if (m < 7)
return 31;
else if (m < 12)
return 30;
else if (m == 12)
return is_leap_year(y) ? 30 : 29;
else
abort();
}
void Date::inc_one_day(){
day++;
if (day > days_of_month(month, year)) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
}
bool Date::equals(Date d) {
return day == d.day && month == d.month && year == d.year;
}
int days_between(Date d1, Date d2){
int count = 1;
while (!d1.equals(d2)){
d1.inc_one_day();
count++;
}
return count;
}
Date::Date(int d, int m, int y){
cout << "constructor called \n";
set_date(d, m, y);
}
void Date::set_date(int d, int m, int y){
if (y < 0 || m < 1 || m>12 || d < 1 || d > days_of_month(m, y))
abort();
day = d;
month = m;
year = y;
}
void Date::print_date(){
cout << day << '/' << month << '/' << year<<endl;
}
int main(){
Date bd(22, 12, 1395);
Date be(15, 12, 1395);
cout << '\n';
int i;
i= days_between(bd, be);
cout << i << endl;
}
here's my code.
I've seen many codes that calculate the days between two dates, but they didn't use class Date.
how can i solve this problem? could you guys help me please.I'm sorry i'm new in c++ so, my problem might be so basic.
It is clear why your algorithm does not work - you are incrementing the later date so it will never equal the earlier date. The solution is simply to compare the dates and swap the operands if necessary so that you are always incrementing the earlier date toward the later date.
int days_between(Date d1, Date d2)
{
int count = 0 ;
// Initially assume d2 >= d1
Date* earlier = &d1 ;
Date* later = &d2 ;
// Test if d1 > d2...
int year_diff = d2.get_year() - d1.get_year() ;
int mon_diff = d2.get_month() - d1.get_month() ;
int day_diff = d2.get_day() - d1.get_day() ;
if( year_diff < 0 ||
(year_diff == 0 && (mon_diff < 0 || (mon_diff == 0 &&
day_diff < 0 ))))
{
// d1 > d2, so swap
earlier = &d2 ;
later = &d1 ;
}
while (!earlier->equals(*later))
{
earlier->inc_one_day();
count++;
}
return count;
}
Note that it is not clear why you start with a count of 1. If the dates start equal, surely that should return a zero? That is how I have written it in any case.
If it is required to indicate whether the dates were reversed or not, you might want to return a signed value. In that case:
return earlier == &d2 ? -count : count ;
Which for the dates in your example will return -7.
Your solution is a good candidate for operator overloading so you could simply and more intuitively write:
if( d1 > d2 )
{
earlier = &d2 ;
later = &d1 ;
}
while( *earlier != *later))
{
earlier++ ;
count++ ;
}
return earlier == &d2 ? -count : count ;
and even ultimately:
i = be - bd;
What would be easier is to write a function that calculates the total number of days that have occurred since the year 0000. After that you can simply subtract them from each other and return the total number of days between them.
Having trouble determining the cause of this. Everything builds properly just does not print any type of output. I'm sure it is something minuscule so please be understanding and not chew me out for asking such a simple question. Trying my best to learn on my own. The program is supposed to ask you to enter a date dd/mm/yy. Below I have attached the main.cpp and date.h. Thank you for any assistance.
main.cpp
#ifndef DATE_H_
#define DATE_H_
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Date
{
private:
int day, month, year;
char format;
bool isLeapYear() const;
int days_in_month() const;
public:
Date(int month=1, int day=1, int year=2000);
void Input();
void Show();
bool Set(int m, int d, int y);
int GetMonth() const;
int GetDay() const;
int GetYear() const;
bool SetFormat(char f);
void Increment(int numDays=1);
int Compare(const Date& d);
void printJulianDate();
};
#endif
//end of date.h
// date.c
#include "date.h"
// constructor
Date::Date(int month, int day, int year)
{
// set the parameters to default values
this->month = 1;
this->day = 1;
this->year = 2000;
this->format = 'D';
// call the method to set the passed month, day and year
if(!Set(month,day,year))
{
cout<<"Invalid date"<<endl; // display error message if invalid date
}
}
// helper function to return if the year is leap or not
bool Date:: isLeapYear() const
{
return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
}
// helper function to return the number of days in the month
int Date::days_in_month() const
{
if(month == 2)
{
if(isLeapYear())
return 29;
else
return 28;
}else if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month ==10 || month==12)
return 31;
else
return 30;
}
// function to input date from the user
void Date:: Input()
{
int m,d,y;
char sep;
// input of date
cout<<"Enter date:";
cin>>m>>sep>>d>>sep>>y;
// loop that continues till the user enters a valid date
while(!Set(m,d,y))
{
cout<<"Invalid date. Try again: ";
cin>>m>>sep>>d>>sep>>y;
}
}
// function to display the date in the format specified
void Date:: Show()
{
if(format == 'D')
{
cout<<month<<"/"<<day<<"/"<<year;
}else if(format == 'T')
{
cout<<setw(2)<<setfill('0')<<month<<"/"<<setw(2)<<setfill('0')<<day<<"/"<<setw(2)<<setfill('0')<<(year%100);
}else if(format == 'L')
{
switch(month)
{
case 1:
cout<<"Jan";
break;
case 2:
cout<<"Feb";
break;
case 3:
cout<<"Mar";
break;
case 4:
cout<<"Apr";
break;
case 5:
cout<<"May";
break;
case 6:
cout<<"June";
break;
case 7:
cout<<"July";
break;
case 8:
cout<<"Aug";
break;
case 9:
cout<<"Sep";
break;
case 10:
cout<<"Oct";
break;
case 11:
cout<<"Nov";
break;
case 12:
cout<<"Dec";
break;
}
cout<<" "<<day<<", "<<year;
}
}
// method to validate the passed arguments and set the date if the arguments represent a valid date
bool Date:: Set(int m, int d, int y)
{
if(y > 1582)
{
if(m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
{
if(d < 1 || d > 31)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if(m == 4 || m == 6 || m == 9 || m == 11)
{
if(d < 1 || d > 30)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if(m == 2)
{
if((y%400 == 0 ) || ((y%4 == 0) && (y%100) != 0))
{
if(d < 1 || d > 29)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else
{
if(d < 1 || d > 28)
return false;
else{
day = d;
month = m;
year = y;
return true;
}
}
}else
return false;
}else if(y == 1582)
{
if(m >= 10)
{
if(m == 10 || m == 12)
{
if(d < 1 || d > 31)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if( m == 11)
{
if(d < 1 || d > 30)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else
return false;
}
}
return false;
}
// function to return the month
int Date::GetMonth() const
{
return month;
}
// function to return the day
int Date::GetDay() const
{
return day;
}
// function to return the year
int Date::GetYear() const
{
return year;
}
// function to set the format of the date
bool Date::SetFormat(char f)
{
if(f == 'D' || f == 'T' || f == 'L')
{
format = f;
return true;
}
return false;
}
// function to increment the number of days passed to the date and update the date accordingly
void Date:: Increment(int numDays)
{
day += numDays; // add number of days passed
// loop that continues till the date is valid
while(day > days_in_month())
{
day -= days_in_month();
month++;
if(month > 12) // if month > 12, i.e it represents the first month of next year
{
// increment year and set month to 1
year++;
month = 1;
}
}
}
// function to compare the passed date with this date and return
// -1, if the calling object comes first chronologically
// 0, if the calling object comes first chronologically
// 1, if the objects are the same date
int Date::Compare(const Date& d)
{
if(year < d.year)
return -1;
else if(year > d.year)
return 1;
else
{
if(month < d.month)
return -1;
else if(month > d.month)
return 1;
else
{
if(day < d.day)
return -1;
else if(day > d.day)
return 1;
else
return 0;
}
}
}
// function to print the julian date
void Date:: printJulianDate()
{
int days=0;
// loop to get the day number
for(int i=1;i<month;i++)
{
switch(i)
{
case 1:
days += 31;
break;
case 2:
if(isLeapYear())
days += 29;
else
days += 28;
break;
case 3:
days += 31;
break;
case 4:
days += 30;
break;
case 5:
days += 31;
break;
case 6:
days += 30;
break;
case 7:
days += 31;
break;
case 8:
days += 31;
break;
case 9:
days += 30;
break;
case 10:
days += 31;
break;
case 11:
days += 30;
break;
case 12:
days += 31;
break;
}
}
days += day;
cout<<days<<"-"<<setw(4)<<setfill('0')<<year;
}
Date.h
#ifndef UNTITLED16_DATE_H
#define UNTITLED16_DATE_H
#endif //UNTITLED16_DATE_H
date.cpp
int main(){return 0;}
Since your main function is int main(){return 0;} all your code is doing is: starting up, calling main(), and then returning back to the caller. Of course there is no output involved here...
There are many other details with your code where I am not sure if it will work as you intend. But the minimum change you have to do to see anything is something like this:
#include "Date.h"
#include <iostream>
int main() {
Date theDate;
theDate.Input();
theDate.Show();
// and maybe also
Date theDate2;
theDate2.Input();
if (theDate2.Compare(theDate)) {
std::cout << "true" << std::endl;
}
return 0;
}
This project I'm working on is forcing me to use Visual C++-6.0 and it seems like everytime I compile this code it causes errors in not only this segment of code but elsewhere that is unrelated to this portion.
Right now I am trying to calculate an expiration date that is 15 months from the date that would be given.
I've tried researching if this is a common issue after windows updates. I know 6.0 has been unsupported and phased out but its a "requirement" for this program. I swore it was working 2 months ago and since that point about 30 patches have been deployed to my Windows 10 device.
Currently in this snippit of code the date that is passed into the code is carried through unaltered. For example: Nov-01-2019 should become Feb-01-2021
void CalculateDates(int numIndex)
{
int tDay = 0, tMonth = 0, tYear = 0, exp_Months = 15;
char sTemp1[4], sTemp2[4], sTemp3[4], sTemp4[4], sDay[4], sYear[4], *p;
p = Database[numIndexCount].sIdentifier;
strncpy(Database[numIndexCount].sPreparedBy, Database[numIndexCount].sIdentifier, 3);
Database[numIndexCount].sPreparedBy[3] = 0;
strncpy(sTemp1, p + 3, 2);
sTemp1[2] = 0;
strncpy(sTemp2, p + 5, 2);
sTemp2[2] = 0;
strncpy(sTemp3, p + 7, 2);
sTemp3[2] = 0;
strcpy(sTemp4, "20");
SetDateMonth(sTemp1);
sprintf(Database[numIndex].sPreparedDate, "%s-%s-%s%s", sTemp2, sMonth1, sTemp4, sTemp3);
tDay = atoi(sTemp2);
tMonth = atoi(sTemp1);
tYear = atoi(sTemp3);
if (tMonth <= 9) {
if (tMonth == 9) {
tMonth = 12;
tYear++;
// cout << "Is the month printing right? ";
// cout<<tMonth;
// cout << "\n";
}
else {
tMonth = (tMonth + exp_Months) % 12;
tYear++;
//cout << "Is the month printing right? ";
//cout<<tMonth;
//cout << "\n";
}
}
if (tMonth == 4 || tMonth == 6 || tMonth == 9 || tMonth == 11) {
// cout << "This is reached";
// cout << "\n";
// cout << "The day value is: ";
// cout << tDay;
// cout << "\n";
if (tDay == 31)
{
tDay = 30;
}
}
if (tDay >= 29 && tMonth == 2 && tYear % 4 == 0) {
if (tYear % 100 != 0) {
tDay = 29;
}
else if (tYear % 100 == 0 && tYear % 400 == 0) {
tDay = 29;
}
}
else if (tYear % 4 != 0 && tMonth == 2) {
tDay = 28;
}
sprintf(sTemp1, "%i", tMonth);
if (tDay < 10) sprintf(sDay, "0%i", tDay);
else sprintf(sDay, "%i", tDay);
if (tYear < 10) sprintf(sYear, "0%i", tYear);
else sprintf(sYear, "%i", tYear);
SetDateMonth(sTemp1);
sprintf(Database[numIndex].sUseByDate, "%s-%s-%s%s", sDay, sMonth1, sTemp4, sYear);
sprintf(sUseByDate, "%s-%s-%s%s", sDay, sMonth1, sTemp4, sYear);
}
End results for the above for today were Nov-01-19 but should have been Feb-01-19
I'm currently working on a project for my intro to C++ programming class. The project asks a user to enter a date using mm/dd/yyyy format. Based on the information given, the program then has to determine if the date is valid or invalid, then displays a response to that. I'm facing the problem currently where everything is coming out reading "Good date!" I'm not sure where the problem is. Any help is appreciated. If you could help point me in the right direction, that would be awesome.
#include <iostream>
#include <conio.h>
using namespace std;
void getDate(int *month, int *day, int *year);
int checkDate(int month, int day, int year);
void displayMessage(int status);
int main()
{
int month, day, year;
int s = 0;
getDate(&month, &day, &year);
do
{
checkDate(month, day, year);
displayMessage(s);
getDate(&month, &day, &year);
}
while (_getch() != EOF);
}
void getDate(int *month, int *day, int *year)
{
char fill;
fill = '/';
cout << "Enter a date in mm/dd/yyyy form: ";
cin >> *month;
if (cin.get() != '/')
{
cout << "expected /" << endl;
}
cin >> *day;
if (cin.get() != '/')
{
cout << "expected /" << endl;
}
cin >> *year;
cout << *month << fill << *day << fill << *year << endl;
};
int checkDate(int month, int day, int year)
{
if ((month = 1) || (month = 3) || (month = 5) || (month = 7) ||
(month = 8) || (month = 10) || (month = 12))
{
day <= 31;
}
else if ((month = 4) || (month = 6) || (month = 9) || (month = 11))
{
day <= 30;
}
else if ((month = 2) && (year % 4 == 0))
{
day <= 29;
}
else if ((month = 2) && (year % 4 != 0))
{
day <= 28;
};
int status = 0;
if ((year < 999) || (year > 10000))
{
status == 1;
}
if ((month < 1) || (month > 12))
{
status == 2;
}
else if ((day < 1) || (day > 31))
{
status == 3;
}
else if ((day < 1) || (day > 30))
{
status == 4;
}
else if ((day < 1) || (day > 29))
{
status == 5;
}
else if ((day < 1) || (day > 28))
{
status == 6;
}
return status;
};
void displayMessage(int status)
{
if (status == 0)
{
cout << "Good date!" << endl;
}
if (status == 1)
{
cout << "Bad year" << endl;
}
if (status == 2)
{
cout << "Bad month" << endl;
}
if (status == 3)
{
cout << "Bad day. Not 1-31" << endl;
}
if (status == 4)
{
cout << "Bad day, not 1-30" << endl;
}
if (status == 5)
{
cout << "Bad day, not 1-29" << endl;
}
if (status == 6)
{
cout << "Bad day, not 1-28" << endl;
}
_getch();
}
1) There are a couple of issues here, but the most obvious one is in main():
int s=0;
...
checkDate(month, day, year); // you don't store the status
displayMessage(s); // so s will always be 0 ! So good date !
You have to correct this:
s=checkDate(month, day, year); // store the result of the check
displayMessage(s); // and take it to display the message
2) Then in checkDate(), you mixup = and ==. = changes the value of the variable to its left. == just makes a comparison but store nothing. When correcting/adjusting, without any optimisation, your code should look like:
int checkDate(int month, int day, int year)
{
int status=0;
if ((month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12) && ( day>31 || day<1) )
{
status = 3;
}
else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day>30 || day<1) )
{
status = 4;
}
else if ((month == 2) && (year % 4 == 0) && (day>29 || day<1))
{
status = 5;
}
else if ((month == 2) && (year % 4 != 0) && (day>28 || day<1) )
{
status = 6;
}
else if ((year < 999) || (year > 10000))
{
status = 1;
}
if ((month < 1) || (month > 12))
{
status = 2;
}
return status;
};
3) After this, you should improve the input function, because:
it doesn't cope with invalid separators. If '/' are missing, an error message is displayed, but you continue the input as if everything was fine.
it doesn't cope with invalid (i.e.non numeric) input. If user enters XI/1/2016 for example, your input will fail.
So keep in mind that (cin>>xxx) is an expression that you could use in an if and is true if everything was read correctly. Also be aware that cin.clear() clears error flags that blocks input after a failure.
You also could make use of the function mktime().
It tries to convert a given tm struct into a correct date. If the comparison of the individual members of the struct subsequently shows equality for all members, the given tm struct contained a valid date.
bool CBorrow::validateDate(tm * timestruct)
{
struct tm copy;
copy.tm_sec = timestruct->tm_sec;
copy.tm_min = timestruct->tm_min;
copy.tm_hour = timestruct->tm_hour;
copy.tm_mday = timestruct->tm_mday;
copy.tm_mon = timestruct->tm_mon;
copy.tm_year = timestruct->tm_year;
copy.tm_wday = timestruct->tm_wday;
copy.tm_yday = timestruct->tm_yday;
copy.tm_isdst = timestruct->tm_isdst;
time_t res = mktime(©);
if (res < 0)
{
return false;
}
if (copy.tm_mday != timestruct->tm_mday
|| copy.tm_mon != timestruct->tm_mon
|| copy.tm_year != timestruct->tm_year)
{
return false;
}
return true;
}
Updated answer for C++20:
#include <chrono>
#include <iostream>
void
displayMessage(std::chrono::year_month_day ymd)
{
using namespace std;
using namespace std::chrono;
if (!ymd.year().ok())
{
cout << "Bad year\n";
return;
}
if (!ymd.month().ok())
{
cout << "Bad month\n";
return;
}
if (!ymd.ok())
{
cout << "Bad day, not 1-" << (ymd.year()/ymd.month()/last).day() << '\n';
return;
}
cout << "Good date!\n";
}
int
main()
{
using namespace std::literals;
displayMessage(29d/2/1900);
}
Output:
Bad day, not 1-28
(1900 was not a leap year)
Can this also be achieved by a regular expression?
I know there are many drawbacks in this approach, but still may be considered:
#include <regex>
#include <string>
using std::regex;
using std::regex_match;
using std::string;
// for ddmmyy
regex ddmmyy("^([0-2][0-9]|(3)[0-1])(((0)[0-9])|((1)[0-2]))\\d{2}$");
/*
for dd/mm/yy https://regex101.com/r/IqPLBJ/1
for dd/mm/yyyy - could start from \\d{4}$ instead of \\d{2}$ bearing 0000-case in mind
*/
regex slashed_ddmmyy("^([0-2][0-9]|(3)[0-1])\/(((0)[0-9])|((1)[0-2]))\/\\d{2}$");
string f1 = "111223";
bool res = regex_match(f1,ddmmyy); // true
f1 = "112223";
res = regex_match(f1,ddmmyy); // false
res = regex_match(f1, slashed_ddmmyy); // false, no slashes
A more compact and stripped checkDate (replace uppercase return by value)
int checkDate(int day, int month, int year) {
if(day < 1 || day > 31) {
return BADVALUE;
} else if(month < 1 || month > 12) {
return BADVALUE;
} else if (year < MINYEAR || year > MAXYEAR) {
return YEAROUTRANGE;
}
if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
return BADMONTHDAY;
} else if ((month == 2) && (year % 4 == 0) && day > 29) {
return BADMONTHYEAR;
} else if ((month == 2) && (year % 4 != 0) && day > 28) {
return BADMONTHYEAR;
}
return GOOD;
}
Im writing a code that, if you input your birthday date and any other date, it returns the total number of years, months and day that you are alive.
Obs.:including (leap) bissextile years.
Obs.2:for invalid dates, the output must be "data invalida" (invalid date in portuguese).
Inputs/Outputs:
Obs.: The date format is in the brazillian standard, the format is Day / Month / Year.
8 //the first input is the number of inputs that you will test.
Input 1: 29/02/2000
Input 2: 01/03/2001
Output: 1 0 1
Input 1: 29/02/2000
Input 2: 28/02/2001
Output: 1 0 0
Input 1: 29/12/2012
Input 2: 13/01/2013
Output: 0 0 15
Input 1: 27/05/2012
Input 2: 27/05/2013
Output: 1 0 0
Input 1: 01/01/2012
Input 2: 05/01/2013
Output: 1 0 4
Input 1: 13/05/1966
Input 2: 05/02/2015
Output: 48 8 23
Input 1: 29/02/2003
Input 2: 4/05/2012
Output: data invalida
Input 1: 14/13/1995
Input 2: 7/8/1996
Output: data invalida
The Code:
#include <iostream>
#include <cstdio>
using namespace std;
int verificar(int ano)
{
if (((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0))
return 1;
else
return 0;
}
int checkdia(int dia, int mes, int ano){
if (dia>0)
if (((mes==1)||(mes==3)||(mes==5)||(mes==7)||(mes==8)||(mes==10)||(mes==12)) && (dia<=31))
return 1;
else{
if (((mes==4)||(mes==6)||(mes==9)||(mes==11)) && (dia<=30))
return 1;
else{
if ((mes==2) && (dia<=28))
return 1;
else{
if ((((verificar(ano))==true)&&(dia<=29))&&(mes==2))
return 1;
else
return 0;
}
}
}
else
return 0;
}
int checkmes(int mes)
{
if ((mes>0) && (mes<=12))
return 1;
else
return 0;
}
int checkano(int ano)
{
if ((ano>0) && (ano<11000))
return 1;
else
return 0;
}
int main(){
int numerodetestes, mes1, mes2, dia1, dia2, ano1, ano2, teste11, teste12, teste13, teste21, teste22, teste23;
cin>>numerodetestes;
for(int c=0;c<=numerodetestes;c++){
scanf("%d/%d/%d", &dia1, &mes1, &ano1);
scanf("%d/%d/%d", &dia2, &mes2, &ano2);
teste11=checkano(ano1);
teste12=checkdia(dia1,mes1,ano1);
teste13=checkmes(mes1);
teste21=checkano(ano2);
teste22=checkdia(dia2,mes2,ano2);
teste23=checkmes(mes2);
if ((dia1==29)&&(mes1==02))
dia1=28;
if ((teste11+teste12+teste13+teste21+teste22+teste23)==6){
total=((365*(ano2-ano1))+sexto);
//... incomplete part ...//
}
else
cout<<"data invalida"<<endl;
}
return 0;
}
Glossary:
dia: day
mes: month
ano: year
numerodetestes: number of tests
verificar: function for bissextile
check(...): function to check "X"
teste"XX": int variable that will receive a 0 or 1 of a check function.
THE PROBLEM IS: I cant figure out how to calculate it in an organized way.
You should use bool instead of int for your return values :
bool verificar(int ano)
{
return ((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0));
}
Also your check functions could be greatly simplified :
bool checkmes(int mes) {
return ( (mes > 0) && (mes <= 12) );
}
bool checkano(int ano) {
return ( (ano > 0) && (ano < 11000) );
}
bool checkdia(int dia, int mes, int ano) {
if(dia < 1 || dia > 31) return false;
if(mes%2 == 0 && dia >30) return false;
if(mes == 2 && dia >28) return verificar(ano);
return true;
}
Then you could write something like :
bool checkdata(int dia, int mes, int ano) {
return ( checkano(ano) && checkmes(mes) && checkdia(dia, mes, ano) );
}
Which would allow you to write :
if( !checkdata(dia1,mes1,ano1) || !checkdata(dia2,mes2,ano2) ) {
cout<< "data invalida" <<endl;
}
Now for the main problem, you could easily get an estimation of the number of day between two dates, but you can't easily get the real number, because dates are nothing but logical. You would have to take into account all calendar modifications across history.
For an easy estimation, I would first add/subtract the dates offset to the first of January, and then add the year difference :
bool isLeap(int year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
int monthLengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int monthLength(int month, int year) {
int n = monthLengths[month-1];
if(month == 2 && isLeap(year)) n += 1;
return n;
}
int yearLength(int year) {
return isLeap(year) ? 366 : 365;
}
int nDay = 0; /* day counter */
/* subtract data1 offset to 01/01 */
nDay -= dia1;
for(int i = mes1; i > 1; --i) {
nDay -= monthLength(i - 1, ano1);
}
/* add data2 offset to 01/01 */
nDay += dia2;
for(int i = mes2; i > 1; --i) {
nDay += monthLength(i - 1, ano2);
}
/* add year offset */
for(int i = ano2; i > ano1; --i) {
nDay += yearLength(i);
}
cout << "Difference = " << nDay << " days" << endl;