#include <iostream> #include <cstring> #include <sstream> // new header including - using stringstream (Date::toString()) #include <cassert> // using assert function using namespace std; class Date { // Put your private data fields here. private: // friend member friend ostream& operator<<(ostream& output, Date* p) { output << p->toString(); // This mean output(Date* p's address) changes string p->toString(). return output; }; // operator'<<' overloading .. // if Date* d1 = new Date(12/31/2009); , cout << d1;'s output is d1's address.. // To solve this problem, I choose operator << overloading. // I don't add This line (friend ostream& op...) to class Date public. // It is private , not public. So, it is legal! (from Notes on grading) // operator << overloading - reference : http://www.fredosaurus.com/notes-cpp/oop-friends/overload-io.html int m_month; int m_day; int m_year; // Constructs a date with the given month, day and year. If the date is // not valid, the entire program will halt with an error message. // @param month is a month, numbered in the range 1...12. // @param day is between 1 and the number of days in the given month. // @param year is the year in question, with no digits omitted. public: Date(int month, int day, int year) { // error message - for Invalid Date assert(isValidDate(month, day, year)); // print error message & line number & program halts m_month = month; m_day = day; m_year = year; } // Constructs a Date object corresponding to the given string. // @param s should be a string of the form "month/day/year" where month must // be one or two digits, day must be one or two digits, and year must be // between 1 and 4 digits. If s does not match these requirements or is not // a valid date, the program halts with an error message. Date(string s) { // Convert string to int using C++ - reference : http://www.techbytes.ca/techbyte99.html (lang:english) const char* ds = s.c_str(); // convert string to const char* int k=0,t=0; unsigned i=0; int month,day,year; string t_s; const char* t_c; // string for(i=0;i<s.length();i++) { if(ds[i] == '/') k++; } if(k>2) { cout << "\nError: Invalid String.\n"; } else { k=0; // string::length - reference : http://www.cplusplus.com/reference/string/string/length/ for(i=0;i<s.length();i++) // s.length() means string s's length. { if(ds[i] == '/') { k++; t_s = s.substr(t, i-1); // substr from string s // string::substr - reference : http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html if(t==0&&i==1) t_s=s[0]; t_c = t_s.c_str(); // string member - c_str() .. convert string to const char* if(k==1) { // first-order - t_c is 'const char*' & it means month month = atoi(t_c);t=i+1; // function atoi(const char*) - convert const char* to integer } if(k==2) { // second-order - t_c is 'const char*' & it means day day = atoi(t_c);t=i+1; } } if(i==s.length()-1) { // t_c means year t_s = s.substr(t, i-1); t_c = t_s.c_str(); year = atoi(t_c); //break; } } // error message - for Invalid Date assert(isValidDate(month, day, year)); // print error message & line number & program halts m_month = month; m_day = day; m_year = year; } } // Checks whether the given year is a leap year. // @return true if and only if the input year is a leap year. static bool isLeapYear(int year) { // leapyear reference : http://blog.naver.com/makesome/140002664401 (lang:korean) if(year%4==0) { if(year>=1582) { if(year%100==0) { if(year%400 ==0) { return true; } else { return false; } } else { return true; } } else { return true; } } else { return false; } // replace this line with your solution } // Returns the number of days in a given month. // @param month is a month, numbered in the range 1...12. // @param year is the year in question, with no digits omitted. // @return the number of days in the given month. static int daysInMonth(int month, int year) { if(month==1 ||month==3 ||month==5 ||month==7 ||month==8 ||month==10 ||month==12) { return 31; } else if(month==2) { if(isLeapYear(year)) { return 29; } else { return 28; } } else { return 30; } } // Checks whether the given date is valid. // @return true if and only if month/day/year constitute a valid date. // Years prior to A.D. 1 are NOT valid. static bool isValidDate(int month, int day, int year) { if(year < 1 || year>9999) return false; // Years prior to A.D. 1 are NOT valid. if(month < 1 || month >12) return false; if(day<1 || day>daysInMonth(month,year)) return false; return true; } // Returns a string representation of this date in the form month/day/year. // The month, day, and year are printed in full as integers; for example, // 12/7/2006 or 3/21/407. // @return a string representation of this date. string toString() { // old C style (failed) - using non-standard function: itoa, _itoa, _itoa_s (only for microsoft visual studio) /* char buffer[4]; _itoa_s(m_month, buffer, 10); string month = buffer; _itoa_s(m_day, buffer, 10); string day = buffer; _itoa_s(m_year, buffer, 10); string year = buffer; */ // New C++ Style - using stringstream // // standard string class - reference : http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html (lang:english) // // C++ string class - reference : http://www.synch3d.com/wiki/moin/moin.cgi/C_2b_2b_20string_20_c5_ac_b7_a1_bd_ba (lang:korean) // // How do I convert a value (a number, for example) to a std::string? // - reference : http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.1 // // C++ — Convert int to string // - reference : http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/ string is; stringstream s_month,s_day,s_year; s_month << m_month; is += s_month.str(); is += '/'; s_day << m_day; is += s_day.str(); is += '/'; s_year << m_year; is += s_year.str(); return is; } // Determines whether this Date is before the Date d. // @return true if and only if this Date is before d. bool isBefore(Date* d) { if(m_year < d->m_year) { return true; } else if(m_year > d->m_year) { return false; } else { if(m_month < d->m_month) { return true; } else if(m_month > d->m_month) { return false; } else { if(m_day < d->m_day) { return true; } else { return false; } } } } // Determines whether this Date is after the Date d. // @return true if and only if this Date is after d. bool isAfter(Date* d) { if(m_year > d->m_year) { return true; } else if(m_year < d->m_year) { return false; } else { if(m_month > d->m_month) { return true; } else if(m_month < d->m_month) { return false; } else { if(m_day > d->m_day) { return true; } else { return false; } } } } // Returns the number of this Date in the year. // @return a number n in the range 1...366, inclusive, such that this Date // is the nth day of its year. (366 is only used for December 31 in a leap // year.) int dayInYear() { int tmp, sum=0, t_month; for (t_month=1;t_month<m_month;t_month++) { tmp = daysInMonth(t_month,m_year); sum += tmp; } sum += m_day; return sum; } // Determines the difference in days between d and this Date. For example, // if this Date is 12/15/1997 and d is 12/14/1997, the difference is 1. // If this Date occurs before d, the result is negative. // @return the difference in days between d and this date. int difference(Date* d) { int i, sum=0, c_year; if(isAfter(d)) { c_year = m_year - d->m_year; if(c_year==0) { return (dayInYear()-d->dayInYear()); } else { for(i=d->m_year;i<m_year;i++) { if(isLeapYear(i)) sum+=366; else sum+=365; } sum += dayInYear() - d->dayInYear(); return sum; } } else if(isBefore(d)) { c_year = d->m_year - m_year; if(c_year==0) { return (dayInYear()-d->dayInYear()); } else { for(i=m_year;i<d->m_year;i++) { if(isLeapYear(i)) sum+=366; else sum+=365; } sum += d->dayInYear() - dayInYear(); return (-sum); } } else { return 0; } } }; int main() { cout << "\nTesting constructors." << endl; Date* d1 = new Date(1, 1, 1); /* // Test Temp value string temp_string;unsigned int i; // Testing Date.toString() temp_string = d1->toString(); cout << "\nTesting Date class by three integer- \nDate should be 1/1/1: "; for(i=0;i<temp_string.length();i++) cout << temp_string[i]; cout << "\n\n"; // end */ cout << "Date should be 1/1/1: " << d1 << endl; d1 = new Date("2/4/2"); cout << "Date should be 2/4/2: " << d1 << endl; d1 = new Date("2/29/2000"); cout << "Date should be 2/29/2000: " << d1 << endl; d1 = new Date("2/29/1904"); cout << "Date should be 2/29/1904: " << d1 << endl; /* // Testing Date.toString() temp_string = d1->toString(); cout << "\nTesting Date class by string- \nDate should be 2/29/1904: "; for(i=0;i<temp_string.length();i++) cout << temp_string[i]; cout << "\n\n"; // end */ d1 = new Date(12, 31, 1975); cout << "Date should be 12/31/1975: " << d1 << endl; Date* d2 = new Date("1/1/1976"); cout << "Date should be 1/1/1976: " << d2 << endl; Date* d3 = new Date("1/2/1976"); cout << "Date should be 1/2/1976: " << d3 << endl; Date* d4 = new Date("2/27/1977"); Date* d5 = new Date("8/31/2110"); // I recommend you write code to test the isLeapYear function! cout << "\nTesting isLeapYear(int year)- \noutput should be 1-0-1-1: "; cout<< d1->isLeapYear(1996) << "-" << d1->isLeapYear(1900) << "-" << d1->isLeapYear(2000) << "-" << d1->isLeapYear(1000) << endl; // output : 1-0-1-1 //cout << d1->toString(); // end cout << "\nTesting before and after." << endl; cout << d2 << " after " << d1 << " should be true: " << d2->isAfter(d1) << endl; cout << d3 << " after " << d2 << " should be true: " << d3->isAfter(d2) << endl; cout << d1 << " after " << d1 << " should be false: " << d1->isAfter(d1) << endl; cout << d1 << " after " << d2 << " should be false: " << d1->isAfter(d2) << endl; cout << d2 << " after " << d3 << " should be false: " << d2->isAfter(d3) << endl; cout << d1 << " before " << d2 << " should be true: " << d1->isBefore(d2) << endl; cout << d2 << " before " << d3 << " should be true: " << d2->isBefore(d3) << endl; cout << d1 << " before " << d1 << " should be false: " << d1->isBefore(d1) << endl; cout << d2 << " before " << d1 << " should be false: " << d2->isBefore(d1) << endl; cout << d3 << " before " << d2 << " should be false: " << d3->isBefore(d2) << endl; cout << "\nTesting difference." << endl; cout << d1 << " - " << d1 << " should be 0: " << d1->difference(d1) << endl; cout << d2 << " - " << d1 << " should be 1: " << d2->difference(d1) << endl; cout << d3 << " - " << d1 << " should be 2: " << d3->difference(d1) << endl; cout << d3 << " - " << d4 << " should be -422: " << d3->difference(d4) << endl; cout << d5 << " - " << d4 << " should be 48762: " << d5->difference(d4) << endl; }
Wednesday, December 7, 2011
날짜 처리를 위한 Date 클래스 (Dates Manipulation)
Labels:
C++
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment