date.cpp

Go to the documentation of this file.
00001 
00014 #include <iostream>
00015 #include <sstream>
00016 #include <iomanip>
00017 #include <dlrUtilities/stringManipulation.h>
00018 #include <dlrUtilities/date.h>
00019 
00020 namespace dlr {
00021 
00022   namespace utilities {
00023 
00025     void
00026     Date::
00027     setISODate(const std::string& isoString)
00028     {
00029       // Be a little forgiving of format.  Replace both "-" and "/"
00030       // with whitespace (not just "-")
00031       std::string string0 = replaceString(isoString, "/", " ");
00032       std::string string1 = replaceString(isoString, "-", " ");
00033 
00034       // Now parse string.
00035       std::istringstream inputStream(string1);
00036       inputStream >> m_year >> m_month >> m_day;
00037       if(!inputStream) {
00038         std::ostringstream message;
00039         message << "Couldn't parse ISO date string: " << isoString << std::endl;
00040         DLR_THROW(ValueException, "Date::setISODate()", message.str().c_str());
00041       }
00042 
00043       // Make sure month and day are sane.
00044       this->sanitize();
00045     }
00046 
00047     // Returns the number of days in a given month.
00048     size_t Date::
00049     dayCount(size_t month, size_t year) {
00050       switch(month) {
00051       case 1:
00052       case 3:
00053       case 5:
00054       case 7:
00055       case 8:
00056       case 10:
00057       case 12:
00058         return 31;
00059         break;
00060       case 4:
00061       case 6:
00062       case 9:
00063       case 11:
00064         return 30;
00065         break;
00066       case 2:
00067         if(this->isLeapYear(year)) {
00068           return 29;
00069         }
00070         return 28;
00071         break;
00072       default:
00073         std::ostringstream message;
00074         message << "Invalid month: " << month << std::endl;
00075         DLR_THROW(ValueException, "Date::dayCount()", message.str().c_str());
00076         break;
00077       }
00078       DLR_THROW(LogicException, "Date::dayCount()", "Faulty switch logic\n");
00079       return 0;
00080     }
00081 
00082     // Chech for leapyear.
00083     bool Date::
00084     isLeapYear(size_t year)
00085     {
00086       if(year % 4 == 0) {
00087         return true;
00088       }
00089       return false;
00090     }
00091 
00092     // Make sure day and date numbers are calender-possible.
00093     void Date::
00094     sanitize()
00095     {
00096       while(1) {
00097         // Fix month first, since this might bump us into a leapyear
00098         while(m_month > 12) {
00099           m_month -= 12;
00100           m_year += 1;
00101         }
00102         // Done?
00103         if(m_day <= dayCount(m_month, m_year)) {
00104           break;
00105         }
00106         m_day -= dayCount(m_month, m_year);
00107         m_month++;
00108       }
00109     }
00110 
00111     bool
00112     operator<(const Date& date0, const Date& date1)
00113     {
00114       if(date0.year() > date1.year()) {
00115         return false;
00116       }
00117       if(date0.year() == date1.year()) {
00118         if(date0.month() > date1.month()) {
00119           return false;
00120         }
00121         if(date0.month() == date1.month()) {
00122           if(date0.day() >= date1.day()) {
00123             return false;
00124           }
00125         }
00126       }
00127       return true;
00128     }
00129 
00130     bool
00131     operator>(const Date& date0, const Date& date1)
00132     {
00133       return (!((date0 == date1) || (date0 < date1)));
00134     }
00135 
00136     bool
00137     operator<=(const Date& date0, const Date& date1)
00138     {
00139       return ((date0 == date1) || (date0 < date1));
00140     }
00141 
00142     bool
00143     operator>=(const Date& date0, const Date& date1)
00144     {
00145       return !(date0 < date1);
00146     }
00147 
00148     bool
00149     operator==(const Date& date0, const Date& date1)
00150     {
00151       return ((date0.year() == date1.year())
00152               && (date0.month() == date1.month())
00153               && (date0.day() == date1.day()));
00154     }
00155 
00156     bool
00157     operator!=(const Date& date0, const Date& date1)
00158     {
00159       return !(date0 == date1);
00160     }
00161 
00162     std::ostream&
00163     operator<<(std::ostream& stream, const Date& date)
00164     {
00165       stream << std::setfill('0') << std::setw(4) << date.year() << "-"
00166              << std::setw(2) << date.month() << "-"
00167              << std::setw(2) << date.day() << std::setfill(' ');
00168       return stream;
00169     }
00170 
00171     std::istream&
00172     operator>>(std::istream& stream, Date& date)
00173     {
00174       std::string isoString;
00175       stream >> isoString;
00176 
00177       // Can't read from stream if it's in a bad state.
00178       if(!stream) {
00179         return stream;
00180       }
00181 
00182       try {
00183         Date newDate(isoString);        // Make sure things parse OK before
00184         date = newDate;         // assigning to argument date.
00185       } catch(const ValueException&) {
00186         stream.clear(std::ios_base::failbit);
00187         return stream;
00188       }
00189 
00190       return stream;
00191     }
00192 
00193     
00194   } // namespace utilities
00195     
00196 } // namespace dlr

Generated on Mon Jul 9 20:34:02 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2