date.cpp

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

Generated on Wed Nov 25 11:07:09 2009 for dlrUtilities Utility Library by  doxygen 1.5.8