| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- #include "calendar.hpp"
- #include "duration.hpp"
- #include "date.hpp"
- #include "calendar_util.hpp"
- namespace xios
- {
- /// ////////////////////// Définitions ////////////////////// ///
- CCalendar::CCalendar(void)
- : CObject()
- , step(0)
- , initDate(*this)
- , timeOrigin(*this)
- , currentDate(*this)
- {}
- CCalendar::CCalendar(const StdString& id)
- : CObject(id)
- , step(0)
- , initDate(*this)
- , timeOrigin(*this)
- , currentDate(*this)
- {}
- CCalendar::CCalendar(const StdString& id,
- int yr, int mth, int d,
- int hr /*= 0*/, int min /*= 0*/, int sec /*= 0*/)
- : CObject(id)
- , step(0)
- , initDate(*this)
- , timeOrigin(*this)
- , currentDate(*this)
- {
- initializeDate(yr, mth, d, hr, min, sec);
- }
- CCalendar::CCalendar(const StdString& id, const CDate& startDate)
- : CObject(id)
- , step(0)
- , initDate(startDate)
- , timeOrigin(startDate)
- , currentDate(startDate)
- {
- // Initialize the dates only in the derivated classes
- // since we want to use the overloaded virtual functions
- }
- CCalendar::CCalendar(const StdString& id, const CDate& startDate, const CDate& timeOrigin)
- : CObject(id)
- , step(0)
- , initDate(startDate)
- , timeOrigin(timeOrigin)
- , currentDate(startDate)
- {
- // Initialize the dates only in the derivated classes
- // since we want to use the overloaded virtual functions
- }
- void CCalendar::initializeDate()
- {
- if (!initDate.setRelCalendar(*this))
- ERROR("CCalendar::initializeDate()",
- "initDate: Bad format or date not conform to the calendar");
- if (!timeOrigin.setRelCalendar(*this))
- ERROR("CCalendar::initializeDate()",
- "timeOrigin: Bad format or date not conform to the calendar");
- if (!currentDate.setRelCalendar(*this))
- ERROR("CCalendar::initializeDate()",
- "currentDate: Bad format or date not conform to the calendar");
- }
- void CCalendar::initializeDate(int yr, int mth, int d,
- int hr /*= 0*/, int min /*= 0*/, int sec /*= 0*/)
- {
- initDate = CDate(*this, yr, mth, d, hr, min, sec);
- timeOrigin = initDate;
- currentDate = initDate;
- }
- void CCalendar::initializeDate(const StdString& dateStr)
- {
- initDate = CDate::FromString(dateStr, *this);
- timeOrigin = initDate;
- currentDate = initDate;
- }
- void CCalendar::initializeDate(const StdString& dateStr, const StdString& timeOriginStr)
- {
- initDate = CDate::FromString(dateStr, *this);
- timeOrigin = CDate::FromString(timeOriginStr, *this);
- currentDate = initDate;
- }
- CCalendar::~CCalendar(void)
- { /* Ne rien faire de plus */ }
- ///---------------------------------------------------------------
- StdString CCalendar::toString(void) const
- {
- StdOStringStream oss;
- oss << "[type: " << this->getId()
- << ", start: " << this->initDate
- << ", current: " << this->currentDate << "]";
- return (oss.str());
- }
- void CCalendar::fromString(const StdString& str)
- { ERROR("CCalendar::fromString(str)",
- << "[ str = " << str << "] Not implemented yet !"); }
- //-----------------------------------------------------------------
- void CCalendar::setTimeStep(const CDuration& timestep)
- {
- if (timestep.timestep)
- ERROR("CCalendar::setTimeStep(const CDuration& timestep)",
- << "Circular definition of the timestep: the timestep cannot refer to itself.");
- this->timestep = timestep;
- }
- int CCalendar::getStep(void) const
- {
- return step;
- }
- const CDate& CCalendar::update(int step)
- {
- info(20) << "update step : " << step << " timestep " << this->timestep << std::endl;
- this->step = step;
- return (this->currentDate = this->getInitDate() + step * this->timestep);
- }
- //-----------------------------------------------------------------
- void CCalendar::setInitDate(const CDate& initDate)
- {
- if (&initDate.getRelCalendar() != this)
- ERROR("CCalendar::setInitDate(const CDate& initDate)",
- << "The init date cannot be attached to another calendar.");
- this->initDate = initDate;
- }
- void CCalendar::setTimeOrigin(const CDate& timeOrigin)
- {
- if (&timeOrigin.getRelCalendar() != this)
- ERROR("CCalendar::setInitDate(const CDate& timeOrigin)",
- << "The time origin cannot be attached to another calendar.");
- this->timeOrigin = timeOrigin;
- }
- //-----------------------------------------------------------------
- const CDuration& CCalendar::getTimeStep(void) const { return this->timestep; }
- const CDate& CCalendar::getInitDate(void) const { return this->initDate; }
- const CDate& CCalendar::getTimeOrigin(void) const { return this->timeOrigin; }
- const CDate& CCalendar::getCurrentDate(void) const { return this->currentDate; }
- //-----------------------------------------------------------------
- int CCalendar::getMonthLength(const CDate& date) const
- { // Retourne la durée du mois en jour.
- static const int NoLeapMonthLength[] =
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- return NoLeapMonthLength[date.getMonth() - 1];
- }
- StdString CCalendar::getType(void) const { return StdString(this->getId()); }
- int CCalendar::getYearTotalLength(const CDate& date) const { return (365 * 86400); }
- int CCalendar::getYearLength (void) const { return 12; }
- int CCalendar::getDayLength (void) const { return 24; }
- int CCalendar::getHourLength (void) const { return 60; }
- int CCalendar::getMinuteLength(void) const { return 60; }
- int CCalendar::getDayLengthInSeconds(void) const { return getDayLength() * getHourLength() * getMinuteLength(); }
- bool CCalendar::hasLeapYear() const { return false; }
- StdString CCalendar::getMonthName(int monthId) const
- {
- static const StdString MonthNames[] =
- { "january", "february", "march", "april" , "may", "june",
- "july", "august", "september", "october", "november", "december" };
- return MonthNames[monthId - 1];
- }
- const StdString CCalendar::getMonthShortName(int monthId) const
- { StdString value = this->getMonthName(monthId); value.resize(3); return value; }
- CDuration& CCalendar::resolve(CDuration& dur, bool noNegativeTime /*= false*/) const
- {
- const int hourLengthInSeconds = getHourLength() * getMinuteLength();
- // Simplify the days, hours, minutes and seconds.
- // First convert them to seconds
- Time t = Time(modf(dur.day, &dur.day) * getDayLengthInSeconds()
- + (dur.hour * getHourLength() + dur.minute) * getMinuteLength() + dur.second);
- // Then convert back to days
- dur.day += int(t / getDayLengthInSeconds());
- t %= getDayLengthInSeconds();
- // Do we allow hour, minute, second to be negative?
- if (noNegativeTime)
- {
- // If we don't, we remove some days until the time is positive
- while (t < 0)
- {
- t += getDayLengthInSeconds();
- dur.day -= 1.0;
- }
- }
- // hours
- dur.hour = int(t / hourLengthInSeconds);
- t %= hourLengthInSeconds;
- // minutes
- dur.minute = int(t / getMinuteLength());
- // secondes
- dur.second = int(t % getMinuteLength());
- // Nothing to do for the months yet since this depends on an actual date
- // Simplify the years
- dur.month += modf(dur.year, &dur.year) * getYearLength();
- dur.year += int(dur.month) / getYearLength(); dur.month = int(dur.month) % getYearLength();
- return dur;
- }
- /*! Parse a date using a generic parser. */
- void CCalendar::parseDateDefault(StdIStream& in, CDate& date)
- {
- char sep = '-'; // Le caractère c est utilisé pour "recueillir" les séparateurs "/" et ":".
- char c;
- // Default initialize the date
- int year = 00, month = 01, day = 01;
- int hour = 00, minute = 00, second = 00;
- in >> year >> c;
- if (c == sep)
- {
- in >> month >> c;
- if (c == sep)
- {
- in >> day;
- c = in.get();
- sep = ' ';
- if (c == sep)
- {
- in >> hour >> c;
- sep = ':';
- if (c == sep)
- {
- in >> minute >> c;
- if (c == sep)
- {
- in >> second;
- in >> c;
- }
- }
- }
- }
- }
- date.setDate(year, month, day, hour, minute, second);
- // Delay the verification until we get a calendar we can compare the date to
- if (date.hasRelCalendar() && !date.checkDate())
- ERROR("void parseDateDefault(StdIStream& in, CDate& date)",
- << "Bad date format or not conform to calendar");
- if (c == '+') // We will be adding a duration to the date
- {
- CDuration dur;
- in >> dur;
- date = date + dur;
- }
- else if (!in.eof())
- ERROR("void parseDateDefault(StdIStream& in, CDate& date)",
- << "Invalid date format: unexpected trailing character(s)");
- }
- /*! Parse a date using the calendar's parser. */
- void CCalendar::parseDate(StdIStream& in, CDate& date) const
- {
- parseDateDefault(in, date);
- }
- /*! Test if a date is valid with regard to the current calendar. */
- bool CCalendar::checkDate(CDate& date) const
- {
- bool isValid = true;
- // Vérification de la valeur du mois.
- if (date.getMonth() < 1)
- { isValid = false; date.setMonth(1); }
- else if (date.getMonth() > getYearLength())
- { isValid = false; date.setMonth(getYearLength()); }
- // Vérification de la valeur du jour.
- if (date.getDay() < 1)
- { isValid = false; date.setDay(1); }
- else if (date.getDay() > getMonthLength(*this))
- { isValid = false; date.setDay(getMonthLength(*this)); }
- // Vérification de la valeur de l'heure.
- if (date.getHour() < 0)
- { isValid = false; date.setHour(0); }
- else if (date.getHour() >= getDayLength())
- { isValid = false; date.setHour(getDayLength() - 1); }
- // Vérification de la valeur des minutes.
- if (date.getMinute() < 0)
- { isValid = false; date.setMinute(0); }
- else if (date.getMinute() >= getHourLength())
- { isValid = false; date.setMinute(getHourLength() - 1); }
- // Vérification de la valeur des secondes.
- if (date.getSecond() < 0)
- { isValid = false; date.setSecond(0); }
- else if (date.getSecond() >= getMinuteLength())
- { isValid = false; date.setSecond(getMinuteLength() - 1); }
- return isValid;
- }
- } // namespace xios
|