source: XIOS3/trunk/src/date.cpp

Last change on this file was 2629, checked in by jderouillat, 2 months ago

Delete boost dependencies, the few features used are replaced by functions stored in extern/boost_extraction

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