Changeset 550


Ignore:
Timestamp:
02/10/15 14:23:02 (9 years ago)
Author:
rlacroix
Message:

Add a new user defined calendar type.

A new calendar type "user_defined" is now available. This allows the users to create a custom calendar that we can configured to be suitable for planets other than the Earth.

An user defined calendar is always defined by two mandatory attributes:

  • day_length: the duration of a day, in seconds
  • and either:
    • month_length: an array containing the duration of each month, in days (the number of elements in the array is the number of months in a year)
    • or year_length: the duration of a year, in seconds (in that case, the calendar does not have months).

If the calendar has months (i.e. month_length attribute is set) and only in that case, it is possible to define leap years in order to compensate for the duration of an astronomical year not being a multiple of the day length. The leap years are defined by two mandatory attributes:

  • leap_year_month: the month to which the extra day will be added in case of leap year, expressed as an integer number in the range [1, numberOfMonths]
  • and leap_year_drift: the fraction of a day representing the yearly drift between the calendar year and the astronomical year, expressed as a real number in the range [0, 1).

Optionally, one can define the leap_year_drift_offset attribute to set the original drift at the beginning of the time origin's year, again expressed as a real number in the range [0, 1). If leap_year_drift_offset + leap_year_drift is greater or equal to 1, then the first year will be a leap year.

For example, the following configuration creates a Gregorian-like calendar:

<calendar type="user_defined" start_date="2012-03-01 15:00:00" time_origin="2012-02-28 15:00:00 + 1d" day_length="86400" month_lengths="(1, 12) [31 28 31 30 31 30 31 31 30 31 30 31]" leap_year_month="2" leap_year_drift="0.25" leap_year_drift_offset="0.75" />

Note that dates attributes must be written differently in the configuration file when using an user defined calendar without months:

  • if the year length is greater than the day length, the input format is year-day hh:min:sec instead of year-month-day hh:min:sec
  • if the day length is greater or equal to the year length, the input format is year hh:min:sec.

In all cases, it is still possible to use the date + duration notation to build a date (with both the date and duration parts being optional).

The Fortran interface has been updated accordingly so that xios_define_calendar can accept the new attributes necessary to define custom calendars.

Location:
XIOS/trunk/src
Files:
2 added
21 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/calendar.cpp

    r549 r550  
    165165      int CCalendar::getDayLengthInSeconds(void) const { return getDayLength() * getHourLength() * getMinuteLength(); } 
    166166 
     167      bool CCalendar::hasLeapYear() const { return false; } 
     168 
    167169      StdString CCalendar::getMonthName(int monthId) const 
    168170      { 
     
    176178      { StdString value = this->getMonthName(monthId); value.resize(3); return value; } 
    177179 
    178       ///---------------------------------------------------------------- 
    179  
     180      CDuration& CCalendar::resolve(CDuration& dur, bool noNegativeTime /*= false*/) const 
     181      { 
     182        const int hourLengthInSeconds = getHourLength() * getMinuteLength(); 
     183 
     184        // Simplify the days, hours, minutes and seconds. 
     185        // First convert them to seconds 
     186        Time t = Time(modf(dur.day, &dur.day) * getDayLengthInSeconds() 
     187                        + (dur.hour * getHourLength() + dur.minute) * getMinuteLength() + dur.second); 
     188        // Then convert back to days 
     189        dur.day += int(t / getDayLengthInSeconds()); 
     190        t %= getDayLengthInSeconds(); 
     191 
     192        // Do we allow hour, minute, second to be negative? 
     193        if (noNegativeTime) 
     194        { 
     195          // If we don't, we remove some days until the time is positive 
     196          while (t < 0) 
     197          { 
     198            t += getDayLengthInSeconds(); 
     199            dur.day -= 1.0; 
     200          } 
     201        } 
     202 
     203        // hours 
     204        dur.hour = int(t / hourLengthInSeconds); 
     205        t %= hourLengthInSeconds; 
     206        // minutes 
     207        dur.minute = int(t / getMinuteLength()); 
     208        // secondes 
     209        dur.second = int(t % getMinuteLength()); 
     210 
     211        // Nothing to do for the months yet since this depends on an actual date 
     212 
     213        // Simplify the years 
     214        dur.month  += modf(dur.year, &dur.year) * getYearLength(); 
     215        dur.year   += int(dur.month) / getYearLength(); dur.month = int(dur.month) % getYearLength(); 
     216 
     217        return dur; 
     218      } 
     219 
     220      /*! Parse a date using a generic parser. */ 
     221      void CCalendar::parseDateDefault(StdIStream& in, CDate& date) 
     222      { 
     223        char sep = '-'; // Le caractÚre c est utilisé pour "recueillir" les séparateurs "/" et ":". 
     224        char c; 
     225 
     226        // Default initialize the date 
     227        int year = 00, month  = 01, day    = 01; 
     228        int hour = 00, minute = 00, second = 00; 
     229 
     230        in >> year >> c; 
     231        if (c == sep) 
     232        { 
     233          in >> month >> c; 
     234          if (c == sep) 
     235          { 
     236            in >> day; 
     237            c = in.get(); 
     238            sep = ' '; 
     239            if (c == sep) 
     240            { 
     241              in >> hour >> c; 
     242              sep = ':'; 
     243              if (c == sep) 
     244              { 
     245                in >> minute >> c; 
     246                if (c == sep) 
     247                { 
     248                  in >> second; 
     249                  in >> c; 
     250                } 
     251              } 
     252            } 
     253          } 
     254        } 
     255 
     256        date.setDate(year, month, day, hour, minute, second); 
     257 
     258        // Delay the verification until we get a calendar we can compare the date to 
     259        if (date.hasRelCalendar() && !date.checkDate()) 
     260          ERROR("void parseDateDefault(StdIStream& in, CDate& date)", 
     261                << "Bad date format or not conform to calendar"); 
     262 
     263        if (c == '+') // We will be adding a duration to the date 
     264        { 
     265          CDuration dur; 
     266          in >> dur; 
     267          date = date + dur; 
     268        } 
     269        else if (!in.eof()) 
     270          ERROR("void parseDateDefault(StdIStream& in, CDate& date)", 
     271                << "Invalid date format: unexpected trailing character(s)"); 
     272      } 
     273 
     274      /*! Parse a date using the calendar's parser. */ 
     275      void CCalendar::parseDate(StdIStream& in, CDate& date) const 
     276      { 
     277        parseDateDefault(in, date); 
     278      } 
     279 
     280      /*! Test if a date is valid with regard to the current calendar. */ 
     281      bool CCalendar::checkDate(CDate& date) const 
     282      { 
     283        bool isValid = true; 
     284 
     285        // Vérification de la valeur du mois. 
     286        if (date.getMonth() < 1) 
     287        { isValid = false; date.setMonth(1); } 
     288        else if (date.getMonth() > getYearLength()) 
     289        { isValid = false; date.setMonth(getYearLength()); } 
     290 
     291        // Vérification de la valeur du jour. 
     292        if (date.getDay() < 1) 
     293        { isValid = false; date.setDay(1); } 
     294        else if (date.getDay() > getMonthLength(*this)) 
     295        { isValid = false; date.setDay(getMonthLength(*this)); } 
     296 
     297        // Vérification de la valeur de l'heure. 
     298        if (date.getHour() < 0) 
     299        { isValid = false; date.setHour(0); } 
     300        else if (date.getHour() >= getDayLength()) 
     301        { isValid = false; date.setHour(getDayLength() - 1); } 
     302 
     303        // Vérification de la valeur des minutes. 
     304        if (date.getMinute() < 0) 
     305        { isValid = false; date.setMinute(0); } 
     306        else if (date.getMinute() >= getHourLength()) 
     307        { isValid = false; date.setMinute(getHourLength() - 1); } 
     308 
     309        // Vérification de la valeur des secondes. 
     310        if (date.getSecond() < 0) 
     311        { isValid = false; date.setSecond(0); } 
     312        else if (date.getSecond() >= getMinuteLength()) 
     313        { isValid = false; date.setSecond(getMinuteLength() - 1); } 
     314 
     315        return isValid; 
     316      } 
    180317} // namespace xios 
  • XIOS/trunk/src/calendar.hpp

    r549 r550  
    6868 
    6969            //------------------------------------------------------------ 
     70            virtual StdString getType(void) const; 
     71 
    7072            virtual int getMonthLength(const CDate& date) const; 
    71  
    72             virtual StdString getType(void) const; 
    7373 
    7474            virtual int getYearTotalLength(const CDate& date) const; // Retourne la durée d'une année en seconde. 
     
    7878            virtual int getHourLength  (void) const; // Retourne la durée d'une heure en minute. 
    7979            virtual int getMinuteLength(void) const; // Retourne la durée d'une minute en secondes. 
    80             //!< Returns the day length expressed in seconds 
     80            /*! Returns the day length expressed in seconds. */ 
    8181            virtual int getDayLengthInSeconds(void) const; 
    8282 
    83             virtual StdString getMonthName(int month_id) const; 
     83            virtual StdString getMonthName(int monthId) const; 
     84            virtual const StdString getMonthShortName(int monthId) const; 
    8485 
    85             virtual const StdString getMonthShortName(int month_id) const; 
     86            /*! Test if the calendar can have leap year. */ 
     87            virtual bool hasLeapYear() const; 
     88 
    8689            void initializeDate(int yr, int mth, int d, int hr = 0, int min = 0, int sec = 0); 
    8790            void initializeDate(const StdString& dateStr); 
    8891            void initializeDate(const StdString& dateStr, const StdString& timeOrigin); 
     92 
     93            /*! Simplify a duration based on the calendar information. */ 
     94            virtual CDuration& resolve(CDuration& dur, bool noNegativeTime = false) const; 
     95 
     96            /*! Parse a date using a generic parser. */ 
     97            static void parseDateDefault(StdIStream& in, CDate& date); 
     98            /*! Parse a date using the calendar's parser. */ 
     99            virtual void parseDate(StdIStream& in, CDate& date) const; 
     100 
     101            /*! Test if a date is valid with regard to the current calendar. */ 
     102            virtual bool checkDate(CDate& date) const; 
    89103 
    90104            //------------------------------------------------------------ 
  • XIOS/trunk/src/calendar_util.cpp

    r549 r550  
    33namespace xios 
    44{ 
    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()) 
     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      const bool calendarHasMonths = (c.getYearLength() > 0); 
     55 
     56      drr.timestep = 0; 
     57      if (dr.timestep) 
     58      { 
     59        if (c.getTimeStep() == NoneDu) 
     60          ERROR("operator+(const CDate& dt, const CDuration& dr)", 
     61                << "Impossible to use the timestep before it is set."); 
     62        drr = drr + dr.timestep * c.getTimeStep(); 
     63      } 
     64 
     65      // Handle the time part of the date 
     66      drr.second += dt.getSecond(); 
     67      drr.minute += dt.getMinute(); 
     68      drr.hour   += dt.getHour(); 
     69 
     70      if (!calendarHasMonths) // Handle the day and year immediately if there is no months 
     71      { 
     72        drr.day  += dt.getDay() - 1; 
     73        drr.year += dt.getYear(); 
     74      } 
     75 
     76      drr.resolve(c, true); // Force the time to be positive 
     77 
     78      second = drr.second; 
     79      minute = drr.minute; 
     80      hour   = drr.hour; 
     81 
     82      if (calendarHasMonths) 
     83      { 
     84        // Ajustement des mois en fonction des jours. 
     85        CDate dtt(dt); 
     86        drr.day += dtt.getDay() - 1; 
     87        dtt.setDay(1); 
     88 
     89        if (drr.day >= 0) 
     90        { 
     91          for(; c.getMonthLength(dtt) <= drr.day; dtt.addMonth(1)) 
     92          { drr.day -= c.getMonthLength(dtt); drr.month += 1; } 
     93 
     94          day = drr.day + 1; 
     95        } 
     96        else 
     97        { 
     98          dtt.addMonth(-1); 
     99          drr.month -= 1; 
     100          for(; c.getMonthLength(dtt) < -drr.day; dtt.addMonth(-1)) 
     101          { drr.day += c.getMonthLength(dtt); drr.month -= 1; } 
     102          day = c.getMonthLength(dtt) + drr.day + 1; 
     103        } 
     104 
     105        drr.resolve(c); 
     106 
     107        // Ajustement des années en fonction des mois. 
     108        month += dt.getMonth() + drr.month; 
     109        if (month < 0) { drr.year--; month += c.getYearLength(); } 
     110        if (month > c.getYearLength()) { drr.year++; month -= c.getYearLength(); } 
     111        if (month == 0){ month = c.getYearLength(); drr.year--; } 
     112 
     113        year += dt.getYear() + drr.year; 
     114      } 
     115      else // if (!calendarHasMonths) 
     116      { 
     117        day   = drr.day + 1; 
     118        month = 1; 
     119        year  = drr.year; 
     120      } 
     121 
     122      return (CDate(c, year, month, day, hour, minute, second)); 
     123    } 
     124 
     125    CDate operator-(const CDate& dt, const CDuration& dr) { return (dt + (-dr)); } 
     126 
     127    //----------------------------------------------------------------- 
     128 
     129    CDuration operator-(const CDate& dt0, const CDate& dt1) 
     130    { 
     131      // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. 
     132      CDuration dur = 
     133      { dt0.getYear() - dt1.getYear(), dt0.getMonth()  - dt1.getMonth() , dt0.getDay()   - dt1.getDay(), 
     134        dt0.getHour() - dt1.getHour(), dt0.getMinute() - dt1.getMinute(), dt0.getSecond() - dt1.getSecond() }; 
     135      return (dur.resolve(dt0.getRelCalendar())); 
     136    } 
     137 
     138    //----------------------------------------------------------------- 
     139 
     140    /// Les opérateurs de comparaison. (Non testés pour le moment) 
     141 
     142    bool operator==(const CDuration& ddr, const CDuration& dr) 
     143    { 
     144      return ((ddr.year == dr.year) && (ddr.month  == dr.month)  && (dr.day    == ddr.day) && 
     145              (ddr.hour == dr.hour) && (ddr.minute == dr.minute) && (dr.second == ddr.second) && 
     146              (ddr.timestep == dr.timestep)); 
     147    } 
     148 
     149    bool operator!=(const CDuration& ddr, const CDuration& dr) 
     150    { 
     151      return !(ddr == dr); 
     152    } 
     153 
     154    bool operator==(const CDate& dt0, const CDate& dt1) 
     155    { 
     156      // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. 
     157      return ((dt0.getYear() == dt1.getYear()) && (dt0.getMonth()  == dt1.getMonth())  && (dt1.getDay()    == dt0.getDay()) && 
     158              (dt0.getHour() == dt1.getHour()) && (dt0.getMinute() == dt1.getMinute()) && (dt1.getSecond() == dt0.getSecond())); 
     159    } 
     160 
     161    bool operator<(const CDate& dt0, const CDate& dt1) 
     162    { 
     163      // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. 
     164      if (dt0.getYear() < dt1.getYear()) 
     165      { 
     166        return true; 
     167      } 
     168      else if (dt0.getYear() == dt1.getYear()) 
     169      { 
     170        if (dt0.getMonth() < dt1.getMonth()) 
     171        { 
     172          return true; 
     173        } 
     174        else if (dt0.getMonth() == dt1.getMonth()) 
     175        { 
     176          if (dt0.getDay() < dt1.getDay()) 
     177          { 
     178             return true; 
     179          } 
     180          else if (dt0.getDay() == dt1.getDay()) 
     181          { 
     182            if (dt0.getHour() < dt1.getHour()) 
    166183            { 
    167                return true; 
     184              return true; 
    168185            } 
    169             else if (dt0.getMonth() == dt1.getMonth()) 
     186            else if (dt0.getHour() == dt1.getHour()) 
    170187            { 
    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                } 
     188              if (dt0.getMinute() < dt1.getMinute()) 
     189              { 
     190                return true; 
     191              } 
     192              else if (dt0.getMinute() == dt1.getMinute()) 
     193              { 
     194                if (dt0.getSecond() < dt1.getSecond()) 
     195                  return true; 
     196              } 
    194197            } 
    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       ///---------------------------------------------------------------- 
     198          } 
     199        } 
     200      } 
     201      return false; 
     202    } 
     203 
     204    //----------------------------------------------------------------- 
     205 
     206    bool operator!=(const CDate& dt0, const CDate& dt1) { return !(dt1 == dt0); } 
     207    bool operator> (const CDate& dt0, const CDate& dt1) { return (dt1 < dt0); } 
     208    bool operator>=(const CDate& dt0, const CDate& dt1) { return (dt0 > dt1 || dt1 == dt0); } 
     209    bool operator<=(const CDate& dt0, const CDate& dt1) { return (dt0 < dt1 || dt1 == dt0); } 
     210 
     211    ///---------------------------------------------------------------- 
    207212 
    208213} // namespace xios 
  • XIOS/trunk/src/config/calendar_wrapper_attribute.conf

    r549 r550  
    1 DECLARE_ENUM5(type, D360, AllLeap, NoLeap, Julian, Gregorian) 
     1DECLARE_ENUM6(type, D360, AllLeap, NoLeap, Julian, Gregorian, user_defined) 
    22DECLARE_ATTRIBUTE(CDuration, timestep) 
    33// The start date and time origin are declared as string attributes instead 
     
    55DECLARE_ATTRIBUTE(string, start_date) 
    66DECLARE_ATTRIBUTE(string, time_origin) 
     7DECLARE_ATTRIBUTE(int, day_length) 
     8DECLARE_ARRAY(int, 1, month_lengths) 
     9DECLARE_ATTRIBUTE(int, year_length) 
     10DECLARE_ATTRIBUTE(double, leap_year_drift) 
     11DECLARE_ATTRIBUTE(double, leap_year_drift_offset) 
     12DECLARE_ATTRIBUTE(int, leap_year_month) 
  • XIOS/trunk/src/date.cpp

    r549 r550  
    8787      } 
    8888 
    89       StdIStream& operator>>(StdIStream& in, CDate& date) // Non testée. 
    90       { 
    91         char sep = '-'; // Le caractÚre c est utilisé pour "recueillir" les séparateurs "/" et ":". 
    92         char c; 
    93  
    94         // Default initialize the date 
    95         date.year = 0; 
    96         date.month = 1; 
    97         date.day = 1; 
    98         date.hour = 0; 
    99         date.minute = 0; 
    100         date.second = 0; 
    101  
    102         in >> date.year >> c; 
    103         if (c == sep) 
    104         { 
    105           in >> date.month >> c; 
    106           if (c == sep) 
    107           { 
    108             in >> date.day; 
    109             c = in.get(); 
    110             sep = ' '; 
    111             if (c == sep) 
    112             { 
    113               in >> date.hour >> c; 
    114               sep = ':'; 
    115               if (c == sep) 
    116               { 
    117                 in>>date.minute >> c; 
    118                 if (c == sep) 
    119                 { 
    120                   in >> date.second; 
    121                   in >> c; 
    122                 } 
    123               } 
    124             } 
    125           } 
    126         } 
    127  
    128         // Delay the verification until we get a calendar we can compare the date to 
    129         if (date.relCalendar && !date.checkDate()) 
    130           ERROR("StdIStream& operator >> (StdIStream& in, CDate& date)", 
    131                 << "Bad date format or not conform to calendar"); 
    132  
    133         if (c == '+') // We will be adding a duration to the date 
    134         { 
    135           CDuration dur; 
    136           in >> dur; 
    137           date = date + dur; 
    138         } 
    139         else if (!in.eof()) 
    140           ERROR("StdIStream& operator >> (StdIStream& in, CDate& date)", 
    141                 << "Invalid date format: unexpected trailing character(s)"); 
     89      StdIStream& operator>>(StdIStream& in, CDate& date) 
     90      { 
     91        if (date.relCalendar) 
     92          date.relCalendar->parseDate(in, date); 
     93        else 
     94          CCalendar::parseDateDefault(in, date); 
    14295 
    14396        return in; 
     
    152105        Time retvalue = getSecondOfYear() - c.getTimeOrigin().getSecondOfYear(); 
    153106 
    154         if ((c.getId().compare("D360")    == 0) || 
    155             (c.getId().compare("AllLeap") == 0) || 
    156             (c.getId().compare("NoLeap")  == 0)) 
    157         return (retvalue + (getYear() - c.getTimeOrigin().getYear()) 
    158                                       * c.getYearTotalLength(*this)); 
    159  
    160         for (CDate _d(c.getTimeOrigin()); _d.getYear() < getYear(); _d.setYear(_d.getYear() + 1)) 
    161            retvalue += c.getYearTotalLength(_d); 
     107        if (c.hasLeapYear()) 
     108        { 
     109          for (CDate _d(c.getTimeOrigin()); _d.getYear() < getYear(); _d.setYear(_d.getYear() + 1)) 
     110            retvalue += c.getYearTotalLength(_d); 
     111        } 
     112        else 
     113          retvalue += (getYear() - c.getTimeOrigin().getYear()) * c.getYearTotalLength(*this); 
     114 
    162115 
    163116        return retvalue; 
     
    168121      bool CDate::checkDate(void) 
    169122      { 
    170         bool retValue = true; 
    171  
    172         // This will check that a calendar was correctly associated to the date 
    173         const CCalendar& c = getRelCalendar(); 
    174  
    175         // Vérification de la valeur du mois. 
    176         if (month  < 1) { retValue = false; month  = 1; } 
    177         if (month  > c.getYearLength()) 
    178         { retValue = false; month = c.getYearLength(); } 
    179  
    180         // Vérification de la valeur du jour. 
    181         if (day    < 1) { retValue = false; day  = 1; } 
    182         if (day    > c.getMonthLength(*this)) 
    183         { retValue = false; day = c.getMonthLength(*this); } 
    184  
    185         // Vérification de la valeur de l'heure. 
    186         if (hour   < 0) { retValue = false; hour  = 0; } 
    187         if (hour   >= c.getDayLength()) 
    188         { retValue = false; hour = c.getDayLength() - 1; } 
    189  
    190         // Vérification de la valeur des minutes. 
    191         if (minute < 0) { retValue = false; minute = 0; } 
    192         if (minute >= c.getHourLength()) 
    193         { retValue = false; minute = c.getHourLength() - 1; } 
    194  
    195         // Vérification de la valeur des secondes. 
    196         if (second < 0) { retValue = false; second = 0; } 
    197         if (second >= c.getMinuteLength()) 
    198         { retValue = false; second = c.getMinuteLength() - 1; } 
    199  
    200         return retValue; 
     123        // This will also check that a calendar was correctly associated to the date 
     124        return getRelCalendar().checkDate(*this); 
    201125      } 
    202126 
     
    238162          nbDay += c.getMonthLength(yearStart); 
    239163 
    240         return ((((nbDay + getDay() - 1) * c.getDayLength() + getHour()) * c.getHourLength() 
    241                    + getMinute()) * c.getMinuteLength() + getSecond()); 
     164        // We need to use getDayLengthInSeconds instead of getDayLength since we might 
     165        // have a non-integral number of hours per day for user defined calendars 
     166        return ((nbDay + getDay() - 1) * c.getDayLengthInSeconds() 
     167                  + (getHour() * c.getHourLength() + getMinute()) * c.getMinuteLength() + getSecond()); 
    242168      } 
    243169 
  • XIOS/trunk/src/date.hpp

    r549 r550  
    3333            CDate& operator=(const CDate& date); 
    3434            friend StdOStream& operator<<(StdOStream& out, const CDate& date); 
    35             friend StdIStream& operator>>(StdIStream& in, CDate& date); // Non testée. 
     35            friend StdIStream& operator>>(StdIStream& in, CDate& date); 
    3636 
    3737            //!< Return the number of seconds since the time origin fixed when creating the calendar 
  • XIOS/trunk/src/date/calendar_type.hpp

    r501 r550  
    77#include "julian.hpp" 
    88#include "noleap.hpp" 
     9#include "user_defined.hpp" 
    910 
    1011#endif //__XMLIO_calendar_type__ 
  • XIOS/trunk/src/date/gregorian.cpp

    r532 r550  
    3333      ///-------------------------------------------------------------- 
    3434 
    35       int CGregorianCalendar::getYearTotalLength(const CDate & date) const 
     35      int CGregorianCalendar::getYearTotalLength(const CDate& date) const 
    3636      { // Retourne la durée d'une année en seconde. 
    3737         if ((date.getYear() % 4   == 0) && 
     
    4242      } 
    4343 
    44       int CGregorianCalendar::getMonthLength(const CDate & date) const 
     44      int CGregorianCalendar::getMonthLength(const CDate& date) const 
    4545      { // Retourne la durée du mois en jour. 
    4646         if (date.getMonth() == 2) 
     
    5858      { return (StdString("gregorian")); } 
    5959 
     60      bool CGregorianCalendar::hasLeapYear() const { return true; } 
     61 
    6062      ///-------------------------------------------------------------- 
    6163} // namespace xmlioserver 
  • XIOS/trunk/src/date/gregorian.hpp

    r532 r550  
    3030            virtual StdString getType(void) const; 
    3131 
     32            virtual bool hasLeapYear() const; 
     33 
    3234            /// Destructeur /// 
    3335            virtual ~CGregorianCalendar(void); 
  • XIOS/trunk/src/date/julian.cpp

    r532 r550  
    3333      ///-------------------------------------------------------------- 
    3434 
    35       int CJulianCalendar::getYearTotalLength(const CDate & date) const 
     35      int CJulianCalendar::getYearTotalLength(const CDate& date) const 
    3636      { // Retourne la durée d'une année en seconde. 
    3737         if (date.getYear() % 4 == 0) return (366 * 86400); 
     
    3939      } 
    4040 
    41       int CJulianCalendar::getMonthLength(const CDate & date) const 
     41      int CJulianCalendar::getMonthLength(const CDate& date) const 
    4242      { // Retourne la durée du mois en jour. 
    4343         if (date.getMonth() == 2) 
     
    5252      { return (StdString("julian")); } 
    5353 
     54      bool CJulianCalendar::hasLeapYear() const { return true; } 
     55 
    5456      ///-------------------------------------------------------------- 
    5557} // namespace xmlioserver 
  • XIOS/trunk/src/date/julian.hpp

    r532 r550  
    3030            virtual StdString getType(void) const; 
    3131 
     32            virtual bool hasLeapYear() const; 
     33 
    3234            /// Destructeur /// 
    3335            virtual ~CJulianCalendar(void); 
  • XIOS/trunk/src/duration.cpp

    r539 r550  
    22#include "date.hpp" 
    33#include "calendar.hpp" 
     4#include "calendar_util.hpp" 
    45 
    56namespace xios 
    67{ 
    78      /// ////////////////////// Définitions ////////////////////// /// 
    8       const CDuration Year   = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 
    9                       Month  = {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 
    10                       Week   = {0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0}, 
    11                       Day    = {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, 
    12                       Hour   = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, 
    13                       Minute = {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, 
    14                       Second = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, 
    15                       NoneDu = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 
    16                       TimeStep = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}; 
     9      const CDuration Year     = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, 
     10                      Month    = { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, 
     11                      Week     = { 0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0 }, 
     12                      Day      = { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, 
     13                      Hour     = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 }, 
     14                      Minute   = { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, 
     15                      Second   = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 }, 
     16                      TimeStep = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, 
     17                      NoneDu   = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; 
    1718 
    1819      ///--------------------------------------------------------------- 
    1920 
    20       CDuration & CDuration::operator=(const CDuration & duration) 
     21      CDuration& CDuration::operator=(const CDuration& duration) 
    2122      { 
    22          year = duration.year;  month  = duration.month ; day    = duration.day; 
    23          hour = duration.hour;  minute = duration.minute; second = duration.second; timestep=duration.timestep ; 
    24          return (*this); 
     23        year = duration.year; month  = duration.month; day    = duration.day; 
     24        hour = duration.hour; minute = duration.minute; second = duration.second; timestep = duration.timestep; 
     25        return *this; 
    2526      } 
    2627 
    27       StdOStream & operator<<(StdOStream & out, const CDuration & duration) 
     28      StdOStream& operator<<(StdOStream& out, const CDuration& duration) 
    2829      { 
    29          StdOStringStream sout; 
    30          bool testValue = true; 
    31          if(duration.year   != 0.0) { testValue = false; sout << duration.year   << "y " ; } 
    32          if(duration.month  != 0.0) { testValue = false; sout << duration.month  << "mo "; } 
    33          if(duration.day    != 0.0) { testValue = false; sout << duration.day    << "d " ; } 
    34          if(duration.hour   != 0.0) { testValue = false; sout << duration.hour   << "h " ; } 
    35          if(duration.minute != 0.0) { testValue = false; sout << duration.minute << "mi "; } 
    36          if(duration.second != 0.0) { testValue = false; sout << duration.second << "s " ; } 
    37          if(duration.timestep != 0.0 || testValue)       { sout << duration.timestep << "ts " ; } 
     30        StdOStringStream sout; 
     31        bool forceOutput = true; 
    3832 
    39          // << suppression de l'espace en fin de chaîne. 
    40          out << (sout.str().substr(0, sout.str().size()-1)); 
    41          return (out); 
     33        if (duration.year   != 0.0) { forceOutput = false; sout << duration.year   << "y "; } 
     34        if (duration.month  != 0.0) { forceOutput = false; sout << duration.month  << "mo "; } 
     35        if (duration.day    != 0.0) { forceOutput = false; sout << duration.day    << "d "; } 
     36        if (duration.hour   != 0.0) { forceOutput = false; sout << duration.hour   << "h "; } 
     37        if (duration.minute != 0.0) { forceOutput = false; sout << duration.minute << "mi "; } 
     38        if (duration.second != 0.0) { forceOutput = false; sout << duration.second << "s "; } 
     39        if (duration.timestep != 0.0 || forceOutput)     { sout << duration.timestep << "ts "; } 
     40 
     41        // suppression de l'espace en fin de chaîne. 
     42        StdString strOut = sout.str(); 
     43        out << strOut.erase(strOut.size() - 1); 
     44        return out; 
    4245      } 
    4346 
     
    7881            } 
    7982            default: 
    80               invalidUnit = true;  
     83              invalidUnit = true; 
    8184              break; 
    8285          } 
     
    8588            ERROR("StdIStream& operator>>(StdIStream& in , CDuration& duration)", 
    8689                  << "Bad duration format: invalid unit, unexpected '" << c << "' character."); 
    87         } while (in.peek() != EOF); // check whether there is a next character to read  
     90        } while (in.peek() != EOF); // check whether there is a next character to read 
    8891 
    8992        return in; 
     
    9497      bool CDuration::isNone(void) const 
    9598      { 
    96          if ((year == 0) && (month  == 0) && (day    == 0) && 
    97              (hour == 0) && (minute == 0) && (second == 0) && (timestep == 0)) 
    98             return (true); 
    99          return (false); 
     99        return (*this == NoneDu); 
    100100      } 
    101101 
    102102      //----------------------------------------------------------------- 
    103       CDuration & CDuration::solveTimeStep(const CCalendar & c) 
     103 
     104      CDuration& CDuration::solveTimeStep(const CCalendar& c) 
    104105      { 
    105         CDuration timeStep=c.getTimeStep() ; 
    106         second +=timestep*timeStep.second ;  
    107         minute +=timestep*timeStep.minute ;  
    108         hour +=timestep*timeStep.hour ;  
    109         day +=timestep*timeStep.day ;  
    110         month +=timestep*timeStep.month ;  
    111         year +=timestep*timeStep.year ;  
    112         timestep = 0 ; 
     106        CDuration timeStep = c.getTimeStep(); 
     107        second += timestep * timeStep.second; 
     108        minute += timestep * timeStep.minute; 
     109        hour   += timestep * timeStep.hour; 
     110        day    += timestep * timeStep.day; 
     111        month  += timestep * timeStep.month; 
     112        year   += timestep * timeStep.year; 
     113        timestep = 0.0; 
     114      } 
    113115 
    114       } 
    115                 
    116          
    117       CDuration & CDuration::resolve(const CCalendar & c) 
     116      CDuration& CDuration::resolve(const CCalendar& c, bool noNegativeTime /*= false*/) 
    118117      { 
    119          // Simplification de l'écriture des minutes. 
    120          second += modf(minute, &minute) * (float)c.getMinuteLength(); 
    121          minute += int(second)/c.getMinuteLength(); second = int(second)%c.getMinuteLength(); 
    122  
    123          // Simplification de l'écriture des heures. 
    124          minute += modf(hour , &hour) * (float)c.getHourLength(); 
    125          hour   += int(minute)/c.getHourLength(); minute = int(minute)%c.getHourLength(); 
    126  
    127          // Simplification de l'écriture des jours. 
    128          hour   += modf(day, &day) * (float)c.getDayLength(); 
    129          day    += int(hour)  /c.getDayLength(); hour   = int(hour)%c.getDayLength(); 
    130  
    131          // > Aucune équivalence jour - mois fixée par avance. // 
    132  
    133          // Simplification de l'écriture des années. 
    134          month  += modf(year, &year) * (float)c.getYearLength(); 
    135          year   += int(month) /c.getYearLength(); month  = int(month)%c.getYearLength(); 
    136          return (*this); 
     118        return c.resolve(*this, noNegativeTime); 
    137119      } 
    138120 
     
    141123      StdString CDuration::toString(void) const 
    142124      { 
    143          const  CDuration & own = *this; 
    144          StdOStringStream oss; oss << own; 
    145          return (oss.str()); 
     125        StdOStringStream oss; oss << *this; 
     126        return oss.str(); 
    146127      } 
    147128 
    148       CDuration CDuration::FromString(const StdString & str) 
     129      CDuration CDuration::FromString(const StdString& str) 
    149130      { 
    150          CDuration dr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 
    151          StdIStringStream iss(str); iss >> dr; 
    152          return (dr); 
     131        CDuration dr = NoneDu; 
     132        StdIStringStream iss(str); iss >> dr; 
     133        return dr; 
    153134      } 
    154  
    155       ///--------------------------------------------------------------- 
    156  
    157  
    158135} // namespace xios 
    159136 
  • XIOS/trunk/src/duration.hpp

    r501 r550  
    1313 
    1414      ///--------------------------------------------------------------- 
    15       typedef struct _duration 
     15 
     16      struct CDuration 
    1617      { 
    17          public : 
     18         public: /* static */ 
     19            static CDuration FromString(const StdString& str); 
    1820 
     21         public: 
    1922            /// Opérateurs /// 
    20             struct _duration & operator=(const struct _duration& duration); 
     23            CDuration& operator=(const CDuration& duration); 
    2124 
    22             friend StdOStream & operator<<(StdOStream & out, const struct _duration& duration); 
    23             friend StdIStream & operator>>(StdIStream & in , struct _duration& duration); 
     25            friend StdOStream& operator<<(StdOStream& out, const CDuration& duration); 
     26            friend StdIStream& operator>>(StdIStream& in , CDuration& duration); 
    2427 
    2528            /// Test /// 
     
    2730 
    2831            /// Traitement /// 
    29             struct _duration & resolve(const CCalendar & calendar); 
    30             struct _duration & solveTimeStep(const CCalendar & c) ; 
     32            CDuration& resolve(const CCalendar& calendar, bool noNegativeTime = false); 
     33            CDuration& solveTimeStep(const CCalendar& c); 
    3134            /// Autres /// 
    3235            StdString toString(void) const; 
    3336 
    34          public: /* static */ 
    35  
    36             static struct _duration FromString(const StdString & str); 
    37  
    3837            /// Propriétés publiques /// 
    3938            double year, month, day, hour, minute, second, timestep; 
    40  
    41       } CDuration; 
     39      }; 
    4240 
    4341      ///--------------------------------------------------------------- 
    4442 
    45       const extern CDuration Year, Month , Week  , Day    , 
    46                              Hour, Minute, Second, NoneDu, TimeStep ; 
    47       ///--------------------------------------------------------------- 
    48  
     43      const extern CDuration Year, Month,  Week,   Day, 
     44                             Hour, Minute, Second, TimeStep, NoneDu; 
    4945} // namespace xios 
    5046 
  • XIOS/trunk/src/interface/c_attr/iccalendar_wrapper_attr.cpp

    r549 r550  
    1818  typedef xios::CCalendarWrapper*  calendar_wrapper_Ptr; 
    1919   
     20  void cxios_set_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int day_length) 
     21  { 
     22     CTimer::get("XIOS").resume(); 
     23    calendar_wrapper_hdl->day_length.setValue(day_length); 
     24     CTimer::get("XIOS").suspend(); 
     25  } 
     26   
     27  void cxios_get_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int* day_length) 
     28  { 
     29    *day_length = calendar_wrapper_hdl->day_length.getInheritedValue(); 
     30  } 
     31   
     32  bool cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     33  { 
     34     CTimer::get("XIOS").resume(); 
     35    return calendar_wrapper_hdl->day_length.hasInheritedValue(); 
     36     CTimer::get("XIOS").suspend(); 
     37  } 
     38   
     39   
     40   
     41  void cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl, double leap_year_drift) 
     42  { 
     43     CTimer::get("XIOS").resume(); 
     44    calendar_wrapper_hdl->leap_year_drift.setValue(leap_year_drift); 
     45     CTimer::get("XIOS").suspend(); 
     46  } 
     47   
     48  void cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl, double* leap_year_drift) 
     49  { 
     50    *leap_year_drift = calendar_wrapper_hdl->leap_year_drift.getInheritedValue(); 
     51  } 
     52   
     53  bool cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     54  { 
     55     CTimer::get("XIOS").resume(); 
     56    return calendar_wrapper_hdl->leap_year_drift.hasInheritedValue(); 
     57     CTimer::get("XIOS").suspend(); 
     58  } 
     59   
     60   
     61   
     62  void cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl, double leap_year_drift_offset) 
     63  { 
     64     CTimer::get("XIOS").resume(); 
     65    calendar_wrapper_hdl->leap_year_drift_offset.setValue(leap_year_drift_offset); 
     66     CTimer::get("XIOS").suspend(); 
     67  } 
     68   
     69  void cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl, double* leap_year_drift_offset) 
     70  { 
     71    *leap_year_drift_offset = calendar_wrapper_hdl->leap_year_drift_offset.getInheritedValue(); 
     72  } 
     73   
     74  bool cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     75  { 
     76     CTimer::get("XIOS").resume(); 
     77    return calendar_wrapper_hdl->leap_year_drift_offset.hasInheritedValue(); 
     78     CTimer::get("XIOS").suspend(); 
     79  } 
     80   
     81   
     82   
     83  void cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl, int leap_year_month) 
     84  { 
     85     CTimer::get("XIOS").resume(); 
     86    calendar_wrapper_hdl->leap_year_month.setValue(leap_year_month); 
     87     CTimer::get("XIOS").suspend(); 
     88  } 
     89   
     90  void cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl, int* leap_year_month) 
     91  { 
     92    *leap_year_month = calendar_wrapper_hdl->leap_year_month.getInheritedValue(); 
     93  } 
     94   
     95  bool cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     96  { 
     97     CTimer::get("XIOS").resume(); 
     98    return calendar_wrapper_hdl->leap_year_month.hasInheritedValue(); 
     99     CTimer::get("XIOS").suspend(); 
     100  } 
     101   
     102   
     103   
     104  void cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl, int* month_lengths, int extent1) 
     105  { 
     106    CTimer::get("XIOS").resume(); 
     107    CArray<int,1> tmp(month_lengths,shape(extent1),neverDeleteData) ; 
     108    calendar_wrapper_hdl->month_lengths.reference(tmp.copy()); 
     109     CTimer::get("XIOS").suspend(); 
     110  } 
     111   
     112  void cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl, int* month_lengths, int extent1) 
     113  { 
     114    CTimer::get("XIOS").resume(); 
     115    CArray<int,1> tmp(month_lengths,shape(extent1),neverDeleteData) ; 
     116    tmp=calendar_wrapper_hdl->month_lengths.getInheritedValue() ; 
     117     CTimer::get("XIOS").suspend(); 
     118  } 
     119   
     120  bool cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     121  { 
     122     CTimer::get("XIOS").resume(); 
     123    return calendar_wrapper_hdl->month_lengths.hasInheritedValue(); 
     124     CTimer::get("XIOS").suspend(); 
     125  } 
     126   
     127   
     128   
    20129  void cxios_set_calendar_wrapper_start_date(calendar_wrapper_Ptr calendar_wrapper_hdl, const char * start_date, int start_date_size) 
    21130  { 
     
    134243   
    135244   
     245  void cxios_set_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int year_length) 
     246  { 
     247     CTimer::get("XIOS").resume(); 
     248    calendar_wrapper_hdl->year_length.setValue(year_length); 
     249     CTimer::get("XIOS").suspend(); 
     250  } 
     251   
     252  void cxios_get_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int* year_length) 
     253  { 
     254    *year_length = calendar_wrapper_hdl->year_length.getInheritedValue(); 
     255  } 
     256   
     257  bool cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl ) 
     258  { 
     259     CTimer::get("XIOS").resume(); 
     260    return calendar_wrapper_hdl->year_length.hasInheritedValue(); 
     261     CTimer::get("XIOS").suspend(); 
     262  } 
     263   
     264   
     265   
    136266   
    137267} 
  • XIOS/trunk/src/interface/fortran/icalendar.F90

    r549 r550  
    2020   CONTAINS ! Fonctions disponibles pour les utilisateurs. 
    2121 
    22    SUBROUTINE xios(define_calendar)(type, timestep, start_date, time_origin) 
     22   SUBROUTINE xios(define_calendar)(type, timestep, start_date, time_origin, & 
     23                                    day_length, month_lengths, year_length, & 
     24                                    leap_year_month, leap_year_drift, leap_year_drift_offset) 
    2325      USE ICALENDAR_WRAPPER, ONLY : txios(calendar_wrapper), xios(get_default_calendar_wrapper_handle) 
    2426      USE icalendar_wrapper_attr, ONLY : xios(set_calendar_wrapper_attr_hdl) 
     
    3032      TYPE(txios(date)),     OPTIONAL, INTENT(IN) :: start_date 
    3133      TYPE(txios(date)),     OPTIONAL, INTENT(IN) :: time_origin 
     34      INTEGER,               OPTIONAL, INTENT(IN) :: day_length 
     35      INTEGER,               OPTIONAL, INTENT(IN) :: month_lengths(:) 
     36      INTEGER,               OPTIONAL, INTENT(IN) :: year_length 
     37      REAL (KIND=8),         OPTIONAL, INTENT(IN) :: leap_year_drift 
     38      REAL (KIND=8),         OPTIONAL, INTENT(IN) :: leap_year_drift_offset 
     39      INTEGER,               OPTIONAL, INTENT(IN) :: leap_year_month 
    3240      TYPE(txios(calendar_wrapper)) :: calendar_wrapper 
    3341 
     
    3846         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, timestep=timestep) 
    3947      END IF 
     48      IF (PRESENT(day_length)) THEN 
     49         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, day_length=day_length) 
     50      END IF 
     51      IF (PRESENT(month_lengths)) THEN 
     52         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, month_lengths=month_lengths) 
     53      END IF 
     54      IF (PRESENT(year_length)) THEN 
     55         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, year_length=year_length) 
     56      END IF 
     57      IF (PRESENT(leap_year_month)) THEN 
     58         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_month=leap_year_month) 
     59      END IF 
     60      IF (PRESENT(leap_year_drift)) THEN 
     61         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_drift=leap_year_drift) 
     62      END IF 
     63      IF (PRESENT(leap_year_drift_offset)) THEN 
     64         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_drift_offset=leap_year_drift_offset) 
     65      END IF 
    4066 
    4167      CALL xios(create_calendar)(calendar_wrapper) 
  • XIOS/trunk/src/interface/fortran_attr/calendar_wrapper_interface_attr.F90

    r549 r550  
    1010     
    1111     
     12    SUBROUTINE cxios_set_calendar_wrapper_day_length(calendar_wrapper_hdl, day_length) BIND(C) 
     13      USE ISO_C_BINDING 
     14      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     15      INTEGER (KIND=C_INT)      , VALUE :: day_length 
     16    END SUBROUTINE cxios_set_calendar_wrapper_day_length 
     17     
     18    SUBROUTINE cxios_get_calendar_wrapper_day_length(calendar_wrapper_hdl, day_length) BIND(C) 
     19      USE ISO_C_BINDING 
     20      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     21      INTEGER (KIND=C_INT)             :: day_length 
     22    END SUBROUTINE cxios_get_calendar_wrapper_day_length 
     23     
     24    FUNCTION cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_hdl ) BIND(C) 
     25      USE ISO_C_BINDING 
     26      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_day_length 
     27      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     28    END FUNCTION cxios_is_defined_calendar_wrapper_day_length 
     29     
     30     
     31    SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl, leap_year_drift) BIND(C) 
     32      USE ISO_C_BINDING 
     33      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     34      REAL (KIND=C_DOUBLE)      , VALUE :: leap_year_drift 
     35    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift 
     36     
     37    SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl, leap_year_drift) BIND(C) 
     38      USE ISO_C_BINDING 
     39      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     40      REAL (KIND=C_DOUBLE)             :: leap_year_drift 
     41    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift 
     42     
     43    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl ) BIND(C) 
     44      USE ISO_C_BINDING 
     45      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_drift 
     46      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     47    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift 
     48     
     49     
     50    SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl, leap_year_drift_offset) BIND(C) 
     51      USE ISO_C_BINDING 
     52      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     53      REAL (KIND=C_DOUBLE)      , VALUE :: leap_year_drift_offset 
     54    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift_offset 
     55     
     56    SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl, leap_year_drift_offset) BIND(C) 
     57      USE ISO_C_BINDING 
     58      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     59      REAL (KIND=C_DOUBLE)             :: leap_year_drift_offset 
     60    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift_offset 
     61     
     62    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl ) BIND(C) 
     63      USE ISO_C_BINDING 
     64      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_drift_offset 
     65      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     66    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift_offset 
     67     
     68     
     69    SUBROUTINE cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_hdl, leap_year_month) BIND(C) 
     70      USE ISO_C_BINDING 
     71      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     72      INTEGER (KIND=C_INT)      , VALUE :: leap_year_month 
     73    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_month 
     74     
     75    SUBROUTINE cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_hdl, leap_year_month) BIND(C) 
     76      USE ISO_C_BINDING 
     77      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     78      INTEGER (KIND=C_INT)             :: leap_year_month 
     79    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_month 
     80     
     81    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_hdl ) BIND(C) 
     82      USE ISO_C_BINDING 
     83      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_month 
     84      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     85    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_month 
     86     
     87     
     88    SUBROUTINE cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_hdl, month_lengths, extent1) BIND(C) 
     89      USE ISO_C_BINDING 
     90      INTEGER (kind = C_INTPTR_T), VALUE       :: calendar_wrapper_hdl 
     91      INTEGER (KIND=C_INT)     , DIMENSION(*) :: month_lengths 
     92      INTEGER (kind = C_INT), VALUE  :: extent1 
     93    END SUBROUTINE cxios_set_calendar_wrapper_month_lengths 
     94     
     95    SUBROUTINE cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_hdl, month_lengths, extent1) BIND(C) 
     96      USE ISO_C_BINDING 
     97      INTEGER (kind = C_INTPTR_T), VALUE       :: calendar_wrapper_hdl 
     98      INTEGER (KIND=C_INT)     , DIMENSION(*) :: month_lengths 
     99      INTEGER (kind = C_INT), VALUE  :: extent1 
     100    END SUBROUTINE cxios_get_calendar_wrapper_month_lengths 
     101     
     102    FUNCTION cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_hdl ) BIND(C) 
     103      USE ISO_C_BINDING 
     104      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_month_lengths 
     105      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     106    END FUNCTION cxios_is_defined_calendar_wrapper_month_lengths 
     107     
     108     
    12109    SUBROUTINE cxios_set_calendar_wrapper_start_date(calendar_wrapper_hdl, start_date, start_date_size) BIND(C) 
    13110      USE ISO_C_BINDING 
     
    94191     
    95192     
     193    SUBROUTINE cxios_set_calendar_wrapper_year_length(calendar_wrapper_hdl, year_length) BIND(C) 
     194      USE ISO_C_BINDING 
     195      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     196      INTEGER (KIND=C_INT)      , VALUE :: year_length 
     197    END SUBROUTINE cxios_set_calendar_wrapper_year_length 
     198     
     199    SUBROUTINE cxios_get_calendar_wrapper_year_length(calendar_wrapper_hdl, year_length) BIND(C) 
     200      USE ISO_C_BINDING 
     201      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     202      INTEGER (KIND=C_INT)             :: year_length 
     203    END SUBROUTINE cxios_get_calendar_wrapper_year_length 
     204     
     205    FUNCTION cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_hdl ) BIND(C) 
     206      USE ISO_C_BINDING 
     207      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_year_length 
     208      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl 
     209    END FUNCTION cxios_is_defined_calendar_wrapper_year_length 
     210     
     211     
    96212    END INTERFACE 
    97213   
  • XIOS/trunk/src/interface/fortran_attr/icalendar_wrapper_attr.F90

    r549 r550  
    1212   
    1313  SUBROUTINE xios(set_calendar_wrapper_attr)  & 
    14     ( calendar_wrapper_id, start_date, time_origin, timestep, type ) 
     14    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     15    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    1516     
    1617    IMPLICIT NONE 
    1718      TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl 
    1819      CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id 
     20      INTEGER  , OPTIONAL, INTENT(IN) :: day_length 
     21      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift 
     22      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset 
     23      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month 
     24      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths(:) 
    1925      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date 
    2026      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin 
    2127      TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep 
    2228      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type 
     29      INTEGER  , OPTIONAL, INTENT(IN) :: year_length 
    2330       
    2431      CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl) 
    2532      CALL xios(set_calendar_wrapper_attr_hdl_)   & 
    26       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     33      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     34      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    2735     
    2836  END SUBROUTINE xios(set_calendar_wrapper_attr) 
    2937   
    3038  SUBROUTINE xios(set_calendar_wrapper_attr_hdl)  & 
    31     ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
    32      
    33     IMPLICIT NONE 
    34       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     39    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     40    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
     41     
     42    IMPLICIT NONE 
     43      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     44      INTEGER  , OPTIONAL, INTENT(IN) :: day_length 
     45      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift 
     46      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset 
     47      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month 
     48      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths(:) 
    3549      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date 
    3650      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin 
    3751      TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep 
    3852      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type 
     53      INTEGER  , OPTIONAL, INTENT(IN) :: year_length 
    3954       
    4055      CALL xios(set_calendar_wrapper_attr_hdl_)  & 
    41       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     56      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     57      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    4258     
    4359  END SUBROUTINE xios(set_calendar_wrapper_attr_hdl) 
    4460   
    4561  SUBROUTINE xios(set_calendar_wrapper_attr_hdl_)   & 
    46     ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ ) 
    47      
    48     IMPLICIT NONE 
    49       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     62    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  & 
     63    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ ) 
     64     
     65    IMPLICIT NONE 
     66      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     67      INTEGER  , OPTIONAL, INTENT(IN) :: day_length_ 
     68      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_ 
     69      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset_ 
     70      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month_ 
     71      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths_(:) 
    5072      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date_ 
    5173      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin_ 
    5274      TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep_ 
    5375      CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ 
     76      INTEGER  , OPTIONAL, INTENT(IN) :: year_length_ 
     77       
     78      IF (PRESENT(day_length_)) THEN 
     79        CALL cxios_set_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr, day_length_) 
     80      ENDIF 
     81       
     82      IF (PRESENT(leap_year_drift_)) THEN 
     83        CALL cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr, leap_year_drift_) 
     84      ENDIF 
     85       
     86      IF (PRESENT(leap_year_drift_offset_)) THEN 
     87        CALL cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr, leap_year_drift_offset_) 
     88      ENDIF 
     89       
     90      IF (PRESENT(leap_year_month_)) THEN 
     91        CALL cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr, leap_year_month_) 
     92      ENDIF 
     93       
     94      IF (PRESENT(month_lengths_)) THEN 
     95        CALL cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr, month_lengths_,size(month_lengths_,1)) 
     96      ENDIF 
    5497       
    5598      IF (PRESENT(start_date_)) THEN 
     
    69112      ENDIF 
    70113       
     114      IF (PRESENT(year_length_)) THEN 
     115        CALL cxios_set_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr, year_length_) 
     116      ENDIF 
     117       
    71118       
    72119     
     
    74121   
    75122  SUBROUTINE xios(get_calendar_wrapper_attr)  & 
    76     ( calendar_wrapper_id, start_date, time_origin, timestep, type ) 
     123    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     124    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    77125     
    78126    IMPLICIT NONE 
    79127      TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl 
    80128      CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id 
     129      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length 
     130      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift 
     131      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset 
     132      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month 
     133      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths(:) 
    81134      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date 
    82135      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin 
    83136      TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep 
    84137      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type 
     138      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length 
    85139       
    86140      CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl) 
    87141      CALL xios(get_calendar_wrapper_attr_hdl_)   & 
    88       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     142      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     143      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    89144     
    90145  END SUBROUTINE xios(get_calendar_wrapper_attr) 
    91146   
    92147  SUBROUTINE xios(get_calendar_wrapper_attr_hdl)  & 
    93     ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
    94      
    95     IMPLICIT NONE 
    96       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     148    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     149    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
     150     
     151    IMPLICIT NONE 
     152      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     153      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length 
     154      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift 
     155      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset 
     156      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month 
     157      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths(:) 
    97158      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date 
    98159      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin 
    99160      TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep 
    100161      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type 
     162      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length 
    101163       
    102164      CALL xios(get_calendar_wrapper_attr_hdl_)  & 
    103       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     165      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     166      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    104167     
    105168  END SUBROUTINE xios(get_calendar_wrapper_attr_hdl) 
    106169   
    107170  SUBROUTINE xios(get_calendar_wrapper_attr_hdl_)   & 
    108     ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ ) 
    109      
    110     IMPLICIT NONE 
    111       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     171    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  & 
     172    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ ) 
     173     
     174    IMPLICIT NONE 
     175      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     176      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length_ 
     177      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_ 
     178      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset_ 
     179      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month_ 
     180      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths_(:) 
    112181      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date_ 
    113182      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin_ 
    114183      TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep_ 
    115184      CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ 
     185      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length_ 
     186       
     187      IF (PRESENT(day_length_)) THEN 
     188        CALL cxios_get_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr, day_length_) 
     189      ENDIF 
     190       
     191      IF (PRESENT(leap_year_drift_)) THEN 
     192        CALL cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr, leap_year_drift_) 
     193      ENDIF 
     194       
     195      IF (PRESENT(leap_year_drift_offset_)) THEN 
     196        CALL cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr, leap_year_drift_offset_) 
     197      ENDIF 
     198       
     199      IF (PRESENT(leap_year_month_)) THEN 
     200        CALL cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr, leap_year_month_) 
     201      ENDIF 
     202       
     203      IF (PRESENT(month_lengths_)) THEN 
     204        CALL cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr, month_lengths_,size(month_lengths_,1)) 
     205      ENDIF 
    116206       
    117207      IF (PRESENT(start_date_)) THEN 
     
    131221      ENDIF 
    132222       
     223      IF (PRESENT(year_length_)) THEN 
     224        CALL cxios_get_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr, year_length_) 
     225      ENDIF 
     226       
    133227       
    134228     
     
    136230   
    137231  SUBROUTINE xios(is_defined_calendar_wrapper_attr)  & 
    138     ( calendar_wrapper_id, start_date, time_origin, timestep, type ) 
     232    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     233    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    139234     
    140235    IMPLICIT NONE 
    141236      TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl 
    142237      CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id 
     238      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length 
     239      LOGICAL(KIND=C_BOOL) :: day_length_tmp 
     240      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift 
     241      LOGICAL(KIND=C_BOOL) :: leap_year_drift_tmp 
     242      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset 
     243      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset_tmp 
     244      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month 
     245      LOGICAL(KIND=C_BOOL) :: leap_year_month_tmp 
     246      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths 
     247      LOGICAL(KIND=C_BOOL) :: month_lengths_tmp 
    143248      LOGICAL, OPTIONAL, INTENT(OUT) :: start_date 
    144249      LOGICAL(KIND=C_BOOL) :: start_date_tmp 
     
    149254      LOGICAL, OPTIONAL, INTENT(OUT) :: type 
    150255      LOGICAL(KIND=C_BOOL) :: type_tmp 
     256      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length 
     257      LOGICAL(KIND=C_BOOL) :: year_length_tmp 
    151258       
    152259      CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl) 
    153260      CALL xios(is_defined_calendar_wrapper_attr_hdl_)   & 
    154       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     261      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     262      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    155263     
    156264  END SUBROUTINE xios(is_defined_calendar_wrapper_attr) 
    157265   
    158266  SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl)  & 
    159     ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
    160      
    161     IMPLICIT NONE 
    162       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     267    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     268    , month_lengths, start_date, time_origin, timestep, type, year_length ) 
     269     
     270    IMPLICIT NONE 
     271      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     272      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length 
     273      LOGICAL(KIND=C_BOOL) :: day_length_tmp 
     274      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift 
     275      LOGICAL(KIND=C_BOOL) :: leap_year_drift_tmp 
     276      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset 
     277      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset_tmp 
     278      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month 
     279      LOGICAL(KIND=C_BOOL) :: leap_year_month_tmp 
     280      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths 
     281      LOGICAL(KIND=C_BOOL) :: month_lengths_tmp 
    163282      LOGICAL, OPTIONAL, INTENT(OUT) :: start_date 
    164283      LOGICAL(KIND=C_BOOL) :: start_date_tmp 
     
    169288      LOGICAL, OPTIONAL, INTENT(OUT) :: type 
    170289      LOGICAL(KIND=C_BOOL) :: type_tmp 
     290      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length 
     291      LOGICAL(KIND=C_BOOL) :: year_length_tmp 
    171292       
    172293      CALL xios(is_defined_calendar_wrapper_attr_hdl_)  & 
    173       ( calendar_wrapper_hdl, start_date, time_origin, timestep, type ) 
     294      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  & 
     295      , month_lengths, start_date, time_origin, timestep, type, year_length ) 
    174296     
    175297  END SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl) 
    176298   
    177299  SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl_)   & 
    178     ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ ) 
    179      
    180     IMPLICIT NONE 
    181       TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     300    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  & 
     301    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ ) 
     302     
     303    IMPLICIT NONE 
     304      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl 
     305      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length_ 
     306      LOGICAL(KIND=C_BOOL) :: day_length__tmp 
     307      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_ 
     308      LOGICAL(KIND=C_BOOL) :: leap_year_drift__tmp 
     309      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset_ 
     310      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset__tmp 
     311      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month_ 
     312      LOGICAL(KIND=C_BOOL) :: leap_year_month__tmp 
     313      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths_ 
     314      LOGICAL(KIND=C_BOOL) :: month_lengths__tmp 
    182315      LOGICAL, OPTIONAL, INTENT(OUT) :: start_date_ 
    183316      LOGICAL(KIND=C_BOOL) :: start_date__tmp 
     
    188321      LOGICAL, OPTIONAL, INTENT(OUT) :: type_ 
    189322      LOGICAL(KIND=C_BOOL) :: type__tmp 
     323      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length_ 
     324      LOGICAL(KIND=C_BOOL) :: year_length__tmp 
     325       
     326      IF (PRESENT(day_length_)) THEN 
     327        day_length__tmp=cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr) 
     328        day_length_=day_length__tmp 
     329      ENDIF 
     330       
     331      IF (PRESENT(leap_year_drift_)) THEN 
     332        leap_year_drift__tmp=cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr) 
     333        leap_year_drift_=leap_year_drift__tmp 
     334      ENDIF 
     335       
     336      IF (PRESENT(leap_year_drift_offset_)) THEN 
     337        leap_year_drift_offset__tmp=cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr) 
     338        leap_year_drift_offset_=leap_year_drift_offset__tmp 
     339      ENDIF 
     340       
     341      IF (PRESENT(leap_year_month_)) THEN 
     342        leap_year_month__tmp=cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr) 
     343        leap_year_month_=leap_year_month__tmp 
     344      ENDIF 
     345       
     346      IF (PRESENT(month_lengths_)) THEN 
     347        month_lengths__tmp=cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr) 
     348        month_lengths_=month_lengths__tmp 
     349      ENDIF 
    190350       
    191351      IF (PRESENT(start_date_)) THEN 
     
    209369      ENDIF 
    210370       
     371      IF (PRESENT(year_length_)) THEN 
     372        year_length__tmp=cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr) 
     373        year_length_=year_length__tmp 
     374      ENDIF 
     375       
    211376       
    212377     
  • XIOS/trunk/src/node/calendar_wrapper.cpp

    r549 r550  
    9595#include "calendar_type.conf" 
    9696#undef DECLARE_CALENDAR 
     97      // Special case for the user defined calendar 
     98      if (type.getValue() == type_attr::user_defined) 
     99      { 
     100        if (day_length.isEmpty()) 
     101          ERROR("CCalendarWrapper::createCalendar(void)", 
     102                << "The day length must be configured when using an user defined calendar."); 
     103        if (month_lengths.isEmpty() == year_length.isEmpty()) 
     104          ERROR("CCalendarWrapper::createCalendar(void)", 
     105                << "Either the month lengths or the year length must be configured when using an user defined calendar."); 
     106        if (leap_year_drift.isEmpty() != leap_year_month.isEmpty()) 
     107          ERROR("CCalendarWrapper::createCalendar(void)", 
     108                << "Both leap_year_drift and leap_year_month attributes must be set if you wish to configure leap years."); 
     109        if (leap_year_drift.isEmpty() && !leap_year_drift_offset.isEmpty()) 
     110          ERROR("CCalendarWrapper::createCalendar(void)", 
     111                << "Both leap_year_drift and leap_year_month attributes are mandatory if you wish to use leap_year_drift_offset attribute."); 
     112 
     113        boost::shared_ptr<CUserDefinedCalendar> userDefinedCalendar; 
     114        if (year_length.isEmpty()) 
     115          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), month_lengths.getValue())); 
     116        else 
     117          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), year_length.getValue())); 
     118 
     119        if (!leap_year_month.isEmpty()) 
     120          userDefinedCalendar->configureLeapYear(leap_year_month.getValue(), 
     121                                                 leap_year_drift.getValue(), 
     122                                                 leap_year_drift_offset.isEmpty() ? 0.0 : leap_year_drift_offset.getValue()); 
     123 
     124        calendar = userDefinedCalendar; 
     125      } 
     126      else 
     127      { 
     128#define CHECK_EMPTY(attr)                                                                       \ 
     129        if (!attr.isEmpty())                                                                    \ 
     130          ERROR("CCalendarWrapper::createCalendar(void)",                                       \ 
     131                << "The attribute \"" #attr "\" can only be used with user defined calendar."); 
     132        CHECK_EMPTY(day_length) 
     133        CHECK_EMPTY(month_lengths) 
     134        CHECK_EMPTY(year_length) 
     135        CHECK_EMPTY(leap_year_month) 
     136        CHECK_EMPTY(leap_year_drift) 
     137        CHECK_EMPTY(leap_year_drift_offset) 
     138#undef CHECK_EMPTY 
     139      } 
    97140 
    98141      if (!calendar) 
    99         ERROR("CCalendarWrapper::parse(xml::CXMLNode& node)", 
     142        ERROR("CCalendarWrapper::createCalendar(void)", 
    100143              << "[ type = " << type.getStringValue() << " ] " 
    101144              << "The calendar is not properly handled!"); 
     
    121164    else if (!start_date.isEmpty() || !time_origin.isEmpty()) 
    122165    { 
    123       ERROR("CCalendarWrapper::parse(xml::CXMLNode& node)", 
     166      ERROR("CCalendarWrapper::createCalendar(void)", 
    124167            << "The calendar type must be set before defining the start date or the time origin!"); 
    125168    } 
  • XIOS/trunk/src/node/calendar_wrapper.hpp

    r549 r550  
    66#include "attribute_enum.hpp" 
    77#include "attribute_enum_impl.hpp" 
     8#include "attribute_array.hpp" 
    89#include "declare_attribute.hpp" 
    910#include "object_template.hpp" 
  • XIOS/trunk/src/node/context.cpp

    r549 r550  
    700700      else if (calendar->getTimeStep() == NoneDu) 
    701701        ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
     702      // Calendar first update to set the current date equals to the start date 
     703      calendar->update(0); 
    702704 
    703705      // Find all inheritance in xml structure 
  • XIOS/trunk/src/test/test_client.f90

    r549 r550  
    1313  TYPE(xios_duration) :: dtime 
    1414  TYPE(xios_date) :: date 
    15   CHARACTER(len=10) :: calendar_type 
     15  CHARACTER(len=15) :: calendar_type 
    1616  TYPE(xios_context) :: ctx_hdl 
    1717  INTEGER,PARAMETER :: ni_glo=100 
Note: See TracChangeset for help on using the changeset viewer.