source: XIOS/trunk/src/date.cpp @ 1211

Last change on this file since 1211 was 1105, checked in by mhnguyen, 7 years ago

Adding comparison operator between objects of XIOS.
Two objects of a same type are considered equal if they have same non-empty
attributes which have same values

+) Add operator== to class CArray
+) Add comparison operator to some basic attribute classes
+) Add operator== to date and duration (It seems that they don't serve much)

Test
+) On Curie
+) No Unit tests but test with transformation work (the next commit)

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 11.4 KB
RevLine 
[219]1#include "date.hpp"
2#include "calendar.hpp"
[334]3#include "calendar_type.hpp"
[549]4#include "calendar_util.hpp"
[316]5#include <boost/date_time/gregorian/gregorian.hpp>
6#include <boost/date_time/posix_time/posix_time.hpp>
[219]7
[549]8using namespace boost::posix_time;
9using namespace boost::gregorian;
[316]10
[335]11namespace xios
[219]12{
13      /// ////////////////////// Définitions ////////////////////// ///
[532]14      CDate::CDate(void)
[549]15        : relCalendar(NULL)
16        , year(0), month(1),  day(1)
17        , hour(0), minute(0), second(0)
[532]18      {}
19
[334]20      CDate::CDate(const CCalendar& calendar)
[532]21         : relCalendar(&calendar)
[549]22         , year(0), month(1),  day(1)
[334]23         , hour(0), minute(0), second(0)
[532]24      {}
[549]25
[219]26      CDate::CDate(const CCalendar& calendar,
27                   int yr, int mth, int d,
28                   int hr, int min, int sec)
[532]29         : relCalendar(&calendar)
[549]30         , year(yr), month(mth),  day(d)
[219]31         , hour(hr), minute(min), second(sec)
32      {
[549]33         if (!this->checkDate())
[231]34         {
[219]35            DEBUG(<< "La date initialisée a été modifiée "
36                  << "car elle était incorrecte par rapport au calendrier souhaité.");
[231]37         }
[219]38      }
39
[532]40      CDate::CDate(const CDate& date)
[549]41        : relCalendar(date.relCalendar)
42        , year(date.year), month(date.month),   day(date.day)
43        , hour(date.hour), minute(date.minute), second(date.second)
[219]44      {
[532]45        // Delay the verification until we get a calendar we can compare the date to
46        if (relCalendar && !checkDate())
47        {
48          DEBUG(<< "La date initialisée a été modifiée "
49                << "car elle était incorrecte par rapport au calendrier souhaité.");
50        }
[219]51      }
52
53      CDate::~CDate(void)
54      { /* Ne rien faire de plus */ }
55
56      ///---------------------------------------------------------------
57
[549]58      CDate& CDate::operator=(const CDate& date)
[219]59      {
[532]60         relCalendar = date.relCalendar;
[549]61         year = date.year; month  = date.month; day    = date.day;
[219]62         hour = date.hour; minute = date.minute; second = date.second;
63         return (*this);
64      }
65
[1105]66      bool CDate::operator==(const CDate& date)
67      {         
68         return (&(*relCalendar) == &(*date.relCalendar) &&
69                 year == date.year && month  == date.month  && day == date.day &&
70                 hour == date.hour && minute == date.minute && second == date.second);
71         
72      }
73
[549]74      StdOStream& operator<<(StdOStream& out, const CDate& date)
[219]75      {
[549]76        std::streamsize s;
77        char c;
[494]78
[549]79        int width=4;
80        double maxSize=10000;
81        while (date.year>=maxSize)
82        {
83          maxSize*=10;
84          width++;
85        }
86        s = out.width(width); c = out.fill('0'); out << date.year << '-';
[494]87
[549]88        s = out.width(2); c = out.fill('0'); out << date.month << '-';
89        s = out.width(2); c = out.fill('0'); out << date.day << ' ';
90        s = out.width(2); c = out.fill('0'); out << date.hour << ':';
91        s = out.width(2); c = out.fill('0'); out << date.minute << ':';
92        s = out.width(2); c = out.fill('0'); out << date.second;
[494]93
[549]94        return out;
[219]95      }
96
[550]97      StdIStream& operator>>(StdIStream& in, CDate& date)
[219]98      {
[550]99        if (date.relCalendar)
100          date.relCalendar->parseDate(in, date);
101        else
102          CCalendar::parseDateDefault(in, date);
[549]103
104        return in;
[219]105      }
106
[334]107      CDate::operator Time(void) const // Non vérifiée, pas optimisée ...
[219]108      {
[549]109        // This will check that a calendar was correctly associated to the date
110        const CCalendar& c = getRelCalendar();
[532]111
[549]112        // Todo : Tester si la date courante est supérieure à la date initiale.
[647]113        Time t = getSecondOfYear() - c.getTimeOrigin().getSecondOfYear();
[219]114
[550]115        if (c.hasLeapYear())
116        {
[647]117          for (CDate d(c.getTimeOrigin()); d.getYear() < getYear(); d.setYear(d.getYear() + 1))
118            t += c.getYearTotalLength(d);
[550]119        }
120        else
[647]121          t += Time(getYear() - c.getTimeOrigin().getYear()) * c.getYearTotalLength(*this);
[219]122
[647]123        return t;
[219]124      }
125
126      //----------------------------------------------------------------
127
128      bool CDate::checkDate(void)
129      {
[550]130        // This will also check that a calendar was correctly associated to the date
131        return getRelCalendar().checkDate(*this);
[219]132      }
133
134      //----------------------------------------------------------------
135
136      int CDate::getYear  (void) const { return (this->year  ); }
137      int CDate::getMonth (void) const { return (this->month ); }
138      int CDate::getDay   (void) const { return (this->day   ); }
139      int CDate::getHour  (void) const { return (this->hour  ); }
140      int CDate::getMinute(void) const { return (this->minute); }
141      int CDate::getSecond(void) const { return (this->second); }
142
143      //----------------------------------------------------------------
144
[532]145      const CCalendar& CDate::getRelCalendar(void) const
146      {
147        if (!this->relCalendar)
148          ERROR("const CCalendar& CDate::getRelCalendar(void) const",
149                "Invalid state: The date is not associated with any calendar.");
150        return (*this->relCalendar);
151      }
[219]152
[532]153      bool CDate::hasRelCalendar(void) const
154      { return (this->relCalendar != NULL); }
155
[219]156      //----------------------------------------------------------------
157
[549]158      /*!
159        Get the number of seconds since the beginning of the year.
160        \return the number of seconds since the beginning of the year.
161      */
162      int CDate::getSecondOfYear() const
163      {
164        CDate yearStart(*this);
165        const CCalendar& c = getRelCalendar();
166        int nbDay = 0;
167
168        for (yearStart.setMonth(1); yearStart.getMonth() < getMonth(); yearStart.setMonth(yearStart.getMonth() + 1))
169          nbDay += c.getMonthLength(yearStart);
170
[550]171        // We need to use getDayLengthInSeconds instead of getDayLength since we might
172        // have a non-integral number of hours per day for user defined calendars
173        return ((nbDay + getDay() - 1) * c.getDayLengthInSeconds()
174                  + (getHour() * c.getHourLength() + getMinute()) * c.getMinuteLength() + getSecond());
[549]175      }
176
177      /*!
178        Get the number of days (expressed as a real number) since the beginning of the year.
179        \return the number of days (expressed as a real number) since the beginning of the year.
180      */
181      double CDate::getDayOfYear() const
182      {
183        return double(getSecondOfYear()) / getRelCalendar().getDayLengthInSeconds();
184      }
185
186      /*!
187        Get the fraction of the current year as a real number between 0 and 1.
188        \return the fraction of the current year.
189      */
190      double CDate::getFractionOfYear() const
191      {
192        return double(getSecondOfYear()) / getRelCalendar().getYearTotalLength(*this);
193      }
194
195      /*!
196        Get the number of seconds since the beginning of the day.
197        \return the number of seconds since the beginning of the day.
198      */
199      int CDate::getSecondOfDay() const
200      {
201        const CCalendar& c = getRelCalendar();
202        return ((getHour() * c.getHourLength() + getMinute()) * c.getMinuteLength() + getSecond());
203      }
204
205      /*!
206        Get the fraction of the current day as a real number between 0 and 1.
207        \return the fraction of the current day.
208      */
209      double CDate::getFractionOfDay() const
210      {
211        return double(getSecondOfDay()) / getRelCalendar().getDayLengthInSeconds();
212      }
213
214      //----------------------------------------------------------------
215
[532]216      void CDate::setYear  (int newyear)   { this->year   = newyear; }
217      void CDate::setMonth (int newmonth)  { this->month  = newmonth; }
218      void CDate::setDay   (int newday)    { this->day    = newday; }
219      void CDate::setHour  (int newhour)   { this->hour   = newhour; }
220      void CDate::setMinute(int newminute) { this->minute = newminute; }
221      void CDate::setSecond(int newsecond) { this->second = newsecond; }
[219]222
[532]223      void CDate::setDate(int yr, int mth, int d, int hr, int min, int sec)
224      {
225        this->year   = yr;
226        this->month  = mth;
227        this->day    = d;
228        this->hour   = hr;
229        this->minute = min;
230        this->second = sec;
231      }
232
[219]233      //----------------------------------------------------------------
234
[549]235      void CDate::addMonth(int value)
[219]236      {// Value doit être égale à 1 ou -1.
[549]237        this->month += value;
238        if (this->month == 13) { year++; this->month = 1; }
239        if (this->month == 0)  { year--; this->month = 12; }
[219]240      }
241
242      //----------------------------------------------------------------
243
[532]244      bool CDate::setRelCalendar(const CCalendar& relCalendar)
245      {
246        this->relCalendar = &relCalendar;
247        return this->checkDate();
248      }
249
250      //----------------------------------------------------------------
251
[549]252      CDate CDate::FromString(const StdString& str, const CCalendar& calendar)
[219]253      {
[549]254        CDate dt(calendar);
255        StdIStringStream iss(str);
256        iss >> dt;
257        return dt;
[219]258      }
[549]259
[219]260      //----------------------------------------------------------------
[549]261
[321]262      StdString CDate::getStryyyymmdd(void) const
[549]263      {
264        std::streamsize s;
265        char c;
[321]266
[549]267        ostringstream oss;
[321]268
[549]269        s = oss.width(4); c = oss.fill('0'); oss << year;
270        s = oss.width(2); c = oss.fill('0'); oss << month;
271        s = oss.width(2); c = oss.fill('0'); oss << day;
[321]272
[549]273        return oss.str();
[321]274      }
[431]275
276      string CDate::getStr(const string& str) const
277      {
[549]278        ostringstream oss;
[431]279        int level;
[549]280
281        level=0;
[431]282        for(string::const_iterator it=str.begin();it!=str.end();++it)
283        {
284          if (level==0)
285          {
[549]286            if (*it=='%') level++;
287            else oss<<*it;
[431]288          }
289          else if (level==1)
290          {
291            switch (*it)
292            {
293              case 'y' :
[549]294                oss.width(4); oss.fill('0'); oss << year;
295                level=0;
296                break;
[431]297              case 'm' : // month or minute
[549]298                level++;
299                break;
[431]300              case 'd' :
[549]301                oss.width(2); oss.fill('0'); oss << day;
[431]302                level=0;
[549]303                break;
[431]304              case 'h' :
[549]305                oss.width(2); oss.fill('0'); oss << hour;
[431]306                level=0;
[549]307                break;
[431]308              case 's' :
[549]309                oss.width(2); oss.fill('0'); oss << second;
310                level=0;
[431]311                break;
[549]312              case 'S' : // seconds since time origin
313                oss.width(0); oss << Time(*this);
314                level=0;
315                break;
316              case 'D' : // days since time origin
317                oss.width(0); oss << Time(*this) / getRelCalendar().getDayLengthInSeconds();
318                level=0;
319                break;
[431]320              default :
[549]321                oss<<'%'<<*it;
322                level=0;
[431]323            }
324          }
325          else if (level==2)
326          {
327            switch (*it)
328            {
329              case 'o' : // month
[549]330                oss.width(2); oss.fill('0'); oss << month;
331                level=0;
332                break;
[431]333              case 'i' : //minute
[549]334                oss.width(2); oss.fill('0'); oss << minute;
335                level=0;
336                break;
[431]337              default :
[549]338                oss<<"%m"<<*it;
339                level=0;
[431]340            }
341          }
342        }
343        return oss.str();
344      }
[549]345
[431]346      StdString CDate::toString(void) const
[549]347      {
348        StdOStringStream oss;
349        oss << *this;
350        return oss.str();
[219]351      }
352
353      ///---------------------------------------------------------------
354
[335]355} // namespace xios
Note: See TracBrowser for help on using the repository browser.