source: XIOS/trunk/src/calendar_util.cpp @ 549

Last change on this file since 549 was 549, checked in by rlacroix, 6 years ago

Revised calendar functionalities:

  • the calendar is now configured from a specific calendar child node of the context in the XML configuration file. Example: <calendar type="Gregorian" start_date="2012-03-01 15:00:00" time_origin="2012-02-29 15:00:00" timestep="1h" />
  • the calendar type should now be configured when defining the start time and/or the time origin.
  • the start time and the time origin are now optional, 0000-01-01 00:00:00 will be used by default. It is also possible to define them partially. For example, 2015 and 2014-12 are valid dates corresponding respectively to 2015-01-01 00:00:00 and 2014-12-01 00:00:00.
  • an optional duration offset can be added to the start date and time origin. For example, it's possible to define the date 2015-01-12 12:00:00 as 2015-01-11 + 36h or 2015-01-11 12:00:00 + 1d. The duration format is the same as the time step. Being that the date is optional, it is possible to only use a duration (for example + 42s is the same as 0000-01-01 00:00:00 + 42s). An error will be raised if a duration based on the time step is used before the time step was configured. For example, the following would cause an error: <calendar type="Gregorian" start_date="+ 1ts" /> but <calendar type="Gregorian" start_date="+ 1ts" timestep="0.5h" /> would not.
  • new Fortran interface to define the calendar:
    • xios_define_calendar(type[, timestep, start_date, time_origin]) will create a calendar when none had previously been defined. Only the type argument is mandatory, the rest is optional. Calendar operations on dates and durations are possible as soon as the calendar is created (either using this procedure or directly from the XML configuration file).
    • the following getter and setter procedures are available: xios_set_timestep, xios_set_start_date, xios_set_time_origin, xios_get_calendar_type, xios_get_timestep, xios_get_start_date, xios_get_time_origin.
  • new Fortran interface to interact with the calendar: xios_update_calendar, xios_get_current_date, xios_get_year_length_in_seconds, xios_get_day_length_in_seconds.
  • new Fortran interface for date conversion: xios_date_get_second_of_year, xios_date_get_day_of_year, xios_date_get_fraction_of_year, xios_date_get_second_of_day, xios_date_get_fraction_of_day.
  • two new placeholders are available to format the file name when splitting the output (split_freq_format attribute):
    • %S the number of seconds since the time origin
    • %D the integral number of days since the time origin
  • 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: 7.7 KB
Line 
1#include "calendar_util.hpp"
2
3namespace xios
4{
5      /// ////////////////////// Définitions ////////////////////// ///
6
7      CDuration operator*(const double& scal, const CDuration& ddr)
8      { return (ddr * scal); }
9
10      CDuration operator-(const CDuration& ddr , const CDuration& dr)
11      {
12         CDuration dur(ddr);
13         dur.year -= dr.year;  dur.month  -= dr.month; dur.day    -= dr.day;
14         dur.hour -= dr.hour;  dur.minute -= dr.minute; dur.second -= dr.second; dur.timestep -= dr.timestep;
15         return (dur);
16      }
17
18      CDuration operator+(const CDuration& ddr , const CDuration& dr)
19      {
20         CDuration dur(ddr);
21         dur.year += dr.year;  dur.month  += dr.month; dur.day    += dr.day;
22         dur.hour += dr.hour;  dur.minute += dr.minute; dur.second += dr.second; dur.timestep += dr.timestep;
23         return (dur);
24      }
25
26      CDuration operator*(const CDuration& ddr , const double& scal)
27      {
28         CDuration dur(ddr);
29         dur.year *= scal;  dur.month  *= scal; dur.day    *= scal;
30         dur.hour *= scal;  dur.minute *= scal; dur.second *= scal; dur.timestep *= scal;
31         return (dur);
32      }
33
34      CDuration operator-(const CDuration& ddr)
35      {
36         CDuration dur(ddr);
37         dur.year   = -dur.year;
38         dur.month  = -dur.month;
39         dur.day    = -dur.day;
40         dur.hour   = -dur.hour;
41         dur.minute = -dur.minute;
42         dur.second = -dur.second;
43         dur.timestep = -dur.timestep;
44         return (dur);
45      }
46
47      //-----------------------------------------------------------------
48
49      CDate operator+(const CDate& dt, const CDuration& dr)
50      {
51         CDuration drr(dr);
52         int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
53         const CCalendar& c = dt.getRelCalendar();
54
55         drr.timestep = 0;
56         if (dr.timestep)
57         {
58            if (c.getTimeStep() == NoneDu)
59               ERROR("operator+(const CDate& dt, const CDuration& dr)",
60                     << "Impossible to use the timestep before it is set.");
61            drr = drr + dr.timestep * c.getTimeStep();
62         }
63
64         drr.resolve(c);
65
66         // Ajustement des minutes par rapport aux secondes.
67         second += dt.getSecond() + drr.second;
68         if (second < 0) { minute--; second += c.getMinuteLength(); }
69         if (second >= c.getMinuteLength()) { minute++; second -= c.getMinuteLength(); }
70
71         // Ajustement des heures en fonction des minutes.
72         minute += dt.getMinute() + drr.minute;
73         if (minute < 0) { hour--; minute += c.getHourLength(); }
74         if (minute >= c.getHourLength()) { hour++; minute -= c.getHourLength(); }
75
76         // Ajustement des jours en fonction des heures.
77         hour += dt.getHour() + drr.hour;
78         if (hour < 0) { drr.day--; hour += c.getDayLength(); }
79         if (hour >= c.getDayLength()) { drr.day++; hour -= c.getDayLength(); }
80
81         // Ajustement des mois en fonction des jours.
82         CDate dtt(dt);
83         drr.day += dtt.getDay() - 1;
84         dtt.setDay(1);
85
86         if (drr.day >= 0)
87         {
88           for(; c.getMonthLength(dtt) <= drr.day; dtt.addMonth(1))
89           { drr.day -= c.getMonthLength(dtt); drr.month += 1; }
90
91           day = drr.day + 1;
92         }
93         else
94         {
95           dtt.addMonth(-1);
96           drr.month -= 1;
97           for(; c.getMonthLength(dtt) < -drr.day; dtt.addMonth(-1))
98           { drr.day += c.getMonthLength(dtt); drr.month -= 1; }
99           day = c.getMonthLength(dtt) + drr.day + 1;
100         }
101
102/*
103         if (day <  0) { drr.month --; day += c.getMonthLength(dtt); }
104         if (day > c.getMonthLength(dtt)) { drr.month ++; day -= c.getMonthLength(dtt); } // << ProblÚme ici
105         if (day == 0){ day = c.getMonthLength(dtt); drr.month --; }
106*/
107         drr.resolve(c);
108
109         // Ajustement des années en fonction des mois.
110         month += dt.getMonth() + drr.month;
111         if (month < 0) { drr.year--; month += c.getYearLength(); }
112         if (month > c.getYearLength()) { drr.year++; month -= c.getYearLength(); }
113         if (month == 0){ month = c.getYearLength(); drr.year--; }
114
115         year += dt.getYear() + drr.year;
116
117         return (CDate(c, year, month, day, hour, minute, second));
118      }
119
120      CDate operator-(const CDate& dt, const CDuration& dr) { return (dt + (-dr)); }
121
122      //-----------------------------------------------------------------
123
124      CDuration operator-(const CDate& dt0, const CDate& dt1)
125      {
126         // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier.
127         CDuration dur =
128         { dt0.getYear() - dt1.getYear(), dt0.getMonth()  - dt1.getMonth() , dt0.getDay()    - dt1.getDay(),
129           dt0.getHour() - dt1.getHour(), dt0.getMinute() - dt1.getMinute(), dt0.getSecond() - dt1.getSecond() };
130         return (dur.resolve(dt0.getRelCalendar()));
131      }
132
133      //-----------------------------------------------------------------
134
135      /// Les opérateurs de comparaison. (Non testés pour le moment)
136
137      bool operator==(const CDuration& ddr, const CDuration& dr)
138      {
139         return ((ddr.year == dr.year)&& (ddr.month  == dr.month) && (dr.day    == ddr.day)&&
140                 (ddr.hour == dr.hour)&& (ddr.minute == dr.minute)&& (dr.second == ddr.second)&&
141                 (ddr.timestep == dr.timestep));
142      }
143
144      bool operator!=(const CDuration& ddr, const CDuration& dr)
145      {
146         return !(ddr == dr);
147      }
148
149      bool operator==(const CDate& dt0, const CDate& dt1)
150      {
151         // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier.
152         return ((dt0.getYear() == dt1.getYear())&& (dt0.getMonth()  == dt1.getMonth()) && (dt1.getDay()    == dt0.getDay())&&
153                 (dt0.getHour() == dt1.getHour())&& (dt0.getMinute() == dt1.getMinute())&& (dt1.getSecond() == dt0.getSecond()));
154      }
155
156      bool operator< (const CDate& dt0, const CDate& dt1)
157      {
158         // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier.
159         if   (dt0.getYear()  < dt1.getYear())
160         {
161            return true;
162         }
163         else if (dt0.getYear() == dt1.getYear())
164         {
165            if   (dt0.getMonth()  < dt1.getMonth())
166            {
167               return true;
168            }
169            else if (dt0.getMonth() == dt1.getMonth())
170            {
171               if   (dt0.getDay()  < dt1.getDay())
172               {
173                   return true;
174               }
175               else if (dt0.getDay() == dt1.getDay())
176               {
177                  if    (dt0.getHour()  < dt1.getHour())
178                  {
179                     return true;
180                  }
181                  else if (dt0.getHour() == dt1.getHour())
182                  {
183                     if   (dt0.getMinute()  < dt1.getMinute())
184                     {
185                        return true;
186                     }
187                     else if (dt0.getMinute() == dt1.getMinute())
188                     {
189                        if (dt0.getSecond() < dt1.getSecond())
190                           return true;
191                     }
192                  }
193               }
194            }
195         }
196         return false;
197      }
198
199      //-----------------------------------------------------------------
200
201      bool operator!=(const CDate& dt0, const CDate& dt1){ return !(dt1 == dt0); }
202      bool operator> (const CDate& dt0, const CDate& dt1){ return (dt1 < dt0); }
203      bool operator>=(const CDate& dt0, const CDate& dt1){ return ((dt0 > dt1) || (dt1 == dt0)); }
204      bool operator<=(const CDate& dt0, const CDate& dt1){ return ((dt0 < dt1) || (dt1 == dt0)); }
205
206      ///----------------------------------------------------------------
207
208} // namespace xios
209
210
211
212
213
214
Note: See TracBrowser for help on using the repository browser.