Index: /XIOS/trunk/src/calendar.cpp
===================================================================
--- /XIOS/trunk/src/calendar.cpp	(revision 549)
+++ /XIOS/trunk/src/calendar.cpp	(revision 550)
@@ -165,4 +165,6 @@
       int CCalendar::getDayLengthInSeconds(void) const { return getDayLength() * getHourLength() * getMinuteLength(); }
 
+      bool CCalendar::hasLeapYear() const { return false; }
+
       StdString CCalendar::getMonthName(int monthId) const
       {
@@ -176,5 +178,140 @@
       { StdString value = this->getMonthName(monthId); value.resize(3); return value; }
 
-      ///----------------------------------------------------------------
-
+      CDuration& CCalendar::resolve(CDuration& dur, bool noNegativeTime /*= false*/) const
+      {
+        const int hourLengthInSeconds = getHourLength() * getMinuteLength();
+
+        // Simplify the days, hours, minutes and seconds.
+        // First convert them to seconds
+        Time t = Time(modf(dur.day, &dur.day) * getDayLengthInSeconds()
+                        + (dur.hour * getHourLength() + dur.minute) * getMinuteLength() + dur.second);
+        // Then convert back to days
+        dur.day += int(t / getDayLengthInSeconds());
+        t %= getDayLengthInSeconds();
+
+        // Do we allow hour, minute, second to be negative?
+        if (noNegativeTime)
+        {
+          // If we don't, we remove some days until the time is positive
+          while (t < 0)
+          {
+            t += getDayLengthInSeconds();
+            dur.day -= 1.0;
+          }
+        }
+
+        // hours
+        dur.hour = int(t / hourLengthInSeconds);
+        t %= hourLengthInSeconds;
+        // minutes
+        dur.minute = int(t / getMinuteLength());
+        // secondes
+        dur.second = int(t % getMinuteLength());
+
+        // Nothing to do for the months yet since this depends on an actual date
+
+        // Simplify the years
+        dur.month  += modf(dur.year, &dur.year) * getYearLength();
+        dur.year   += int(dur.month) / getYearLength(); dur.month = int(dur.month) % getYearLength();
+
+        return dur;
+      }
+
+      /*! Parse a date using a generic parser. */
+      void CCalendar::parseDateDefault(StdIStream& in, CDate& date)
+      {
+        char sep = '-'; // Le caractÃšre c est utilisÃ© pour "recueillir" les sÃ©parateurs "/" et ":".
+        char c;
+
+        // Default initialize the date
+        int year = 00, month  = 01, day    = 01;
+        int hour = 00, minute = 00, second = 00;
+
+        in >> year >> c;
+        if (c == sep)
+        {
+          in >> month >> c;
+          if (c == sep)
+          {
+            in >> day;
+            c = in.get();
+            sep = ' ';
+            if (c == sep)
+            {
+              in >> hour >> c;
+              sep = ':';
+              if (c == sep)
+              {
+                in >> minute >> c;
+                if (c == sep)
+                {
+                  in >> second;
+                  in >> c;
+                }
+              }
+            }
+          }
+        }
+
+        date.setDate(year, month, day, hour, minute, second);
+
+        // Delay the verification until we get a calendar we can compare the date to
+        if (date.hasRelCalendar() && !date.checkDate())
+          ERROR("void parseDateDefault(StdIStream& in, CDate& date)",
+                << "Bad date format or not conform to calendar");
+
+        if (c == '+') // We will be adding a duration to the date
+        {
+          CDuration dur;
+          in >> dur;
+          date = date + dur;
+        }
+        else if (!in.eof())
+          ERROR("void parseDateDefault(StdIStream& in, CDate& date)",
+                << "Invalid date format: unexpected trailing character(s)");
+      }
+
+      /*! Parse a date using the calendar's parser. */
+      void CCalendar::parseDate(StdIStream& in, CDate& date) const
+      {
+        parseDateDefault(in, date);
+      }
+
+      /*! Test if a date is valid with regard to the current calendar. */
+      bool CCalendar::checkDate(CDate& date) const
+      {
+        bool isValid = true;
+
+        // VÃ©rification de la valeur du mois.
+        if (date.getMonth() < 1)
+        { isValid = false; date.setMonth(1); }
+        else if (date.getMonth() > getYearLength())
+        { isValid = false; date.setMonth(getYearLength()); }
+
+        // VÃ©rification de la valeur du jour.
+        if (date.getDay() < 1)
+        { isValid = false; date.setDay(1); }
+        else if (date.getDay() > getMonthLength(*this))
+        { isValid = false; date.setDay(getMonthLength(*this)); }
+
+        // VÃ©rification de la valeur de l'heure.
+        if (date.getHour() < 0)
+        { isValid = false; date.setHour(0); }
+        else if (date.getHour() >= getDayLength())
+        { isValid = false; date.setHour(getDayLength() - 1); }
+
+        // VÃ©rification de la valeur des minutes.
+        if (date.getMinute() < 0)
+        { isValid = false; date.setMinute(0); }
+        else if (date.getMinute() >= getHourLength())
+        { isValid = false; date.setMinute(getHourLength() - 1); }
+
+        // VÃ©rification de la valeur des secondes.
+        if (date.getSecond() < 0)
+        { isValid = false; date.setSecond(0); }
+        else if (date.getSecond() >= getMinuteLength())
+        { isValid = false; date.setSecond(getMinuteLength() - 1); }
+
+        return isValid;
+      }
 } // namespace xios
Index: /XIOS/trunk/src/calendar.hpp
===================================================================
--- /XIOS/trunk/src/calendar.hpp	(revision 549)
+++ /XIOS/trunk/src/calendar.hpp	(revision 550)
@@ -68,7 +68,7 @@
 
             //------------------------------------------------------------
+            virtual StdString getType(void) const;
+
             virtual int getMonthLength(const CDate& date) const;
-
-            virtual StdString getType(void) const;
 
             virtual int getYearTotalLength(const CDate& date) const; // Retourne la durÃ©e d'une annÃ©e en seconde.
@@ -78,13 +78,27 @@
             virtual int getHourLength  (void) const; // Retourne la durÃ©e d'une heure en minute.
             virtual int getMinuteLength(void) const; // Retourne la durÃ©e d'une minute en secondes.
-            //!< Returns the day length expressed in seconds
+            /*! Returns the day length expressed in seconds. */
             virtual int getDayLengthInSeconds(void) const;
 
-            virtual StdString getMonthName(int month_id) const;
+            virtual StdString getMonthName(int monthId) const;
+            virtual const StdString getMonthShortName(int monthId) const;
 
-            virtual const StdString getMonthShortName(int month_id) const;
+            /*! Test if the calendar can have leap year. */
+            virtual bool hasLeapYear() const;
+
             void initializeDate(int yr, int mth, int d, int hr = 0, int min = 0, int sec = 0);
             void initializeDate(const StdString& dateStr);
             void initializeDate(const StdString& dateStr, const StdString& timeOrigin);
+
+            /*! Simplify a duration based on the calendar information. */
+            virtual CDuration& resolve(CDuration& dur, bool noNegativeTime = false) const;
+
+            /*! Parse a date using a generic parser. */
+            static void parseDateDefault(StdIStream& in, CDate& date);
+            /*! Parse a date using the calendar's parser. */
+            virtual void parseDate(StdIStream& in, CDate& date) const;
+
+            /*! Test if a date is valid with regard to the current calendar. */
+            virtual bool checkDate(CDate& date) const;
 
             //------------------------------------------------------------
Index: /XIOS/trunk/src/calendar_util.cpp
===================================================================
--- /XIOS/trunk/src/calendar_util.cpp	(revision 549)
+++ /XIOS/trunk/src/calendar_util.cpp	(revision 550)
@@ -3,206 +3,211 @@
 namespace xios
 {
-      /// ////////////////////// DÃ©finitions ////////////////////// ///
-
-      CDuration operator*(const double& scal, const CDuration& ddr)
-      { return (ddr * scal); }
-
-      CDuration operator-(const CDuration& ddr , const CDuration& dr)
-      {
-         CDuration dur(ddr);
-         dur.year -= dr.year;  dur.month  -= dr.month; dur.day    -= dr.day;
-         dur.hour -= dr.hour;  dur.minute -= dr.minute; dur.second -= dr.second; dur.timestep -= dr.timestep;
-         return (dur);
-      }
-
-      CDuration operator+(const CDuration& ddr , const CDuration& dr)
-      {
-         CDuration dur(ddr);
-         dur.year += dr.year;  dur.month  += dr.month; dur.day    += dr.day;
-         dur.hour += dr.hour;  dur.minute += dr.minute; dur.second += dr.second; dur.timestep += dr.timestep;
-         return (dur);
-      }
-
-      CDuration operator*(const CDuration& ddr , const double& scal)
-      {
-         CDuration dur(ddr);
-         dur.year *= scal;  dur.month  *= scal; dur.day    *= scal;
-         dur.hour *= scal;  dur.minute *= scal; dur.second *= scal; dur.timestep *= scal;
-         return (dur);
-      }
-
-      CDuration operator-(const CDuration& ddr)
-      {
-         CDuration dur(ddr);
-         dur.year   = -dur.year;
-         dur.month  = -dur.month;
-         dur.day    = -dur.day;
-         dur.hour   = -dur.hour;
-         dur.minute = -dur.minute;
-         dur.second = -dur.second;
-         dur.timestep = -dur.timestep;
-         return (dur);
-      }
-
-      //-----------------------------------------------------------------
-
-      CDate operator+(const CDate& dt, const CDuration& dr)
-      {
-         CDuration drr(dr);
-         int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
-         const CCalendar& c = dt.getRelCalendar();
-
-         drr.timestep = 0;
-         if (dr.timestep)
-         {
-            if (c.getTimeStep() == NoneDu)
-               ERROR("operator+(const CDate& dt, const CDuration& dr)",
-                     << "Impossible to use the timestep before it is set.");
-            drr = drr + dr.timestep * c.getTimeStep();
-         }
-
-         drr.resolve(c);
-
-         // Ajustement des minutes par rapport aux secondes.
-         second += dt.getSecond() + drr.second;
-         if (second < 0) { minute--; second += c.getMinuteLength(); }
-         if (second >= c.getMinuteLength()) { minute++; second -= c.getMinuteLength(); }
-
-         // Ajustement des heures en fonction des minutes.
-         minute += dt.getMinute() + drr.minute;
-         if (minute < 0) { hour--; minute += c.getHourLength(); }
-         if (minute >= c.getHourLength()) { hour++; minute -= c.getHourLength(); }
-
-         // Ajustement des jours en fonction des heures.
-         hour += dt.getHour() + drr.hour;
-         if (hour < 0) { drr.day--; hour += c.getDayLength(); }
-         if (hour >= c.getDayLength()) { drr.day++; hour -= c.getDayLength(); }
-
-         // Ajustement des mois en fonction des jours.
-         CDate dtt(dt);
-         drr.day += dtt.getDay() - 1;
-         dtt.setDay(1);
-
-         if (drr.day >= 0)
-         {
-           for(; c.getMonthLength(dtt) <= drr.day; dtt.addMonth(1))
-           { drr.day -= c.getMonthLength(dtt); drr.month += 1; }
-
-           day = drr.day + 1;
-         }
-         else
-         {
-           dtt.addMonth(-1);
-           drr.month -= 1;
-           for(; c.getMonthLength(dtt) < -drr.day; dtt.addMonth(-1))
-           { drr.day += c.getMonthLength(dtt); drr.month -= 1; }
-           day = c.getMonthLength(dtt) + drr.day + 1;
-         }
-
-/*
-         if (day <  0) { drr.month --; day += c.getMonthLength(dtt); }
-         if (day > c.getMonthLength(dtt)) { drr.month ++; day -= c.getMonthLength(dtt); } // << ProblÃšme ici
-         if (day == 0){ day = c.getMonthLength(dtt); drr.month --; }
-*/
-         drr.resolve(c);
-
-         // Ajustement des annÃ©es en fonction des mois.
-         month += dt.getMonth() + drr.month;
-         if (month < 0) { drr.year--; month += c.getYearLength(); }
-         if (month > c.getYearLength()) { drr.year++; month -= c.getYearLength(); }
-         if (month == 0){ month = c.getYearLength(); drr.year--; }
-
-         year += dt.getYear() + drr.year;
-
-         return (CDate(c, year, month, day, hour, minute, second));
-      }
-
-      CDate operator-(const CDate& dt, const CDuration& dr) { return (dt + (-dr)); }
-
-      //-----------------------------------------------------------------
-
-      CDuration operator-(const CDate& dt0, const CDate& dt1)
-      {
-         // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
-         CDuration dur =
-         { dt0.getYear() - dt1.getYear(), dt0.getMonth()  - dt1.getMonth() , dt0.getDay()    - dt1.getDay(),
-           dt0.getHour() - dt1.getHour(), dt0.getMinute() - dt1.getMinute(), dt0.getSecond() - dt1.getSecond() };
-         return (dur.resolve(dt0.getRelCalendar()));
-      }
-
-      //-----------------------------------------------------------------
-
-      /// Les opÃ©rateurs de comparaison. (Non testÃ©s pour le moment)
-
-      bool operator==(const CDuration& ddr, const CDuration& dr)
-      {
-         return ((ddr.year == dr.year)&& (ddr.month  == dr.month) && (dr.day    == ddr.day)&&
-                 (ddr.hour == dr.hour)&& (ddr.minute == dr.minute)&& (dr.second == ddr.second)&&
-                 (ddr.timestep == dr.timestep));
-      }
-
-      bool operator!=(const CDuration& ddr, const CDuration& dr)
-      {
-         return !(ddr == dr);
-      }
-
-      bool operator==(const CDate& dt0, const CDate& dt1)
-      {
-         // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
-         return ((dt0.getYear() == dt1.getYear())&& (dt0.getMonth()  == dt1.getMonth()) && (dt1.getDay()    == dt0.getDay())&&
-                 (dt0.getHour() == dt1.getHour())&& (dt0.getMinute() == dt1.getMinute())&& (dt1.getSecond() == dt0.getSecond()));
-      }
-
-      bool operator< (const CDate& dt0, const CDate& dt1)
-      {
-         // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
-         if   (dt0.getYear()  < dt1.getYear())
-         {
-            return true;
-         }
-         else if (dt0.getYear() == dt1.getYear())
-         {
-            if   (dt0.getMonth()  < dt1.getMonth())
+    /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+    CDuration operator*(const double& scal, const CDuration& ddr)
+    { return (ddr * scal); }
+
+    CDuration operator-(const CDuration& ddr, const CDuration& dr)
+    {
+      CDuration dur(ddr);
+      dur.year -= dr.year; dur.month  -= dr.month;  dur.day    -= dr.day;
+      dur.hour -= dr.hour; dur.minute -= dr.minute; dur.second -= dr.second; dur.timestep -= dr.timestep;
+      return dur;
+    }
+
+    CDuration operator+(const CDuration& ddr, const CDuration& dr)
+    {
+      CDuration dur(ddr);
+      dur.year += dr.year; dur.month  += dr.month;  dur.day    += dr.day;
+      dur.hour += dr.hour; dur.minute += dr.minute; dur.second += dr.second; dur.timestep += dr.timestep;
+      return dur;
+    }
+
+    CDuration operator*(const CDuration& ddr, const double& scal)
+    {
+      CDuration dur(ddr);
+      dur.year *= scal; dur.month  *= scal; dur.day    *= scal;
+      dur.hour *= scal; dur.minute *= scal; dur.second *= scal; dur.timestep *= scal;
+      return dur;
+    }
+
+    CDuration operator-(const CDuration& ddr)
+    {
+      CDuration dur(ddr);
+      dur.year     = -dur.year;
+      dur.month    = -dur.month;
+      dur.day      = -dur.day;
+      dur.hour     = -dur.hour;
+      dur.minute   = -dur.minute;
+      dur.second   = -dur.second;
+      dur.timestep = -dur.timestep;
+      return dur;
+    }
+
+    //-----------------------------------------------------------------
+
+    CDate operator+(const CDate& dt, const CDuration& dr)
+    {
+      CDuration drr(dr);
+      int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
+      const CCalendar& c = dt.getRelCalendar();
+      const bool calendarHasMonths = (c.getYearLength() > 0);
+
+      drr.timestep = 0;
+      if (dr.timestep)
+      {
+        if (c.getTimeStep() == NoneDu)
+          ERROR("operator+(const CDate& dt, const CDuration& dr)",
+                << "Impossible to use the timestep before it is set.");
+        drr = drr + dr.timestep * c.getTimeStep();
+      }
+
+      // Handle the time part of the date
+      drr.second += dt.getSecond();
+      drr.minute += dt.getMinute();
+      drr.hour   += dt.getHour();
+
+      if (!calendarHasMonths) // Handle the day and year immediately if there is no months
+      {
+        drr.day  += dt.getDay() - 1;
+        drr.year += dt.getYear();
+      }
+
+      drr.resolve(c, true); // Force the time to be positive
+
+      second = drr.second;
+      minute = drr.minute;
+      hour   = drr.hour;
+
+      if (calendarHasMonths)
+      {
+        // Ajustement des mois en fonction des jours.
+        CDate dtt(dt);
+        drr.day += dtt.getDay() - 1;
+        dtt.setDay(1);
+
+        if (drr.day >= 0)
+        {
+          for(; c.getMonthLength(dtt) <= drr.day; dtt.addMonth(1))
+          { drr.day -= c.getMonthLength(dtt); drr.month += 1; }
+
+          day = drr.day + 1;
+        }
+        else
+        {
+          dtt.addMonth(-1);
+          drr.month -= 1;
+          for(; c.getMonthLength(dtt) < -drr.day; dtt.addMonth(-1))
+          { drr.day += c.getMonthLength(dtt); drr.month -= 1; }
+          day = c.getMonthLength(dtt) + drr.day + 1;
+        }
+
+        drr.resolve(c);
+
+        // Ajustement des annÃ©es en fonction des mois.
+        month += dt.getMonth() + drr.month;
+        if (month < 0) { drr.year--; month += c.getYearLength(); }
+        if (month > c.getYearLength()) { drr.year++; month -= c.getYearLength(); }
+        if (month == 0){ month = c.getYearLength(); drr.year--; }
+
+        year += dt.getYear() + drr.year;
+      }
+      else // if (!calendarHasMonths)
+      {
+        day   = drr.day + 1;
+        month = 1;
+        year  = drr.year;
+      }
+
+      return (CDate(c, year, month, day, hour, minute, second));
+    }
+
+    CDate operator-(const CDate& dt, const CDuration& dr) { return (dt + (-dr)); }
+
+    //-----------------------------------------------------------------
+
+    CDuration operator-(const CDate& dt0, const CDate& dt1)
+    {
+      // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
+      CDuration dur =
+      { dt0.getYear() - dt1.getYear(), dt0.getMonth()  - dt1.getMonth() , dt0.getDay()   - dt1.getDay(),
+        dt0.getHour() - dt1.getHour(), dt0.getMinute() - dt1.getMinute(), dt0.getSecond() - dt1.getSecond() };
+      return (dur.resolve(dt0.getRelCalendar()));
+    }
+
+    //-----------------------------------------------------------------
+
+    /// Les opÃ©rateurs de comparaison. (Non testÃ©s pour le moment)
+
+    bool operator==(const CDuration& ddr, const CDuration& dr)
+    {
+      return ((ddr.year == dr.year) && (ddr.month  == dr.month)  && (dr.day    == ddr.day) &&
+              (ddr.hour == dr.hour) && (ddr.minute == dr.minute) && (dr.second == ddr.second) &&
+              (ddr.timestep == dr.timestep));
+    }
+
+    bool operator!=(const CDuration& ddr, const CDuration& dr)
+    {
+      return !(ddr == dr);
+    }
+
+    bool operator==(const CDate& dt0, const CDate& dt1)
+    {
+      // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
+      return ((dt0.getYear() == dt1.getYear()) && (dt0.getMonth()  == dt1.getMonth())  && (dt1.getDay()    == dt0.getDay()) &&
+              (dt0.getHour() == dt1.getHour()) && (dt0.getMinute() == dt1.getMinute()) && (dt1.getSecond() == dt0.getSecond()));
+    }
+
+    bool operator<(const CDate& dt0, const CDate& dt1)
+    {
+      // TODO :: VÃ©rifier que les deux dates (dt0 et dt1) ont une rÃ©fÃ©rence vers le mÃªme calendrier.
+      if (dt0.getYear() < dt1.getYear())
+      {
+        return true;
+      }
+      else if (dt0.getYear() == dt1.getYear())
+      {
+        if (dt0.getMonth() < dt1.getMonth())
+        {
+          return true;
+        }
+        else if (dt0.getMonth() == dt1.getMonth())
+        {
+          if (dt0.getDay() < dt1.getDay())
+          {
+             return true;
+          }
+          else if (dt0.getDay() == dt1.getDay())
+          {
+            if (dt0.getHour() < dt1.getHour())
             {
-               return true;
+              return true;
             }
-            else if (dt0.getMonth() == dt1.getMonth())
+            else if (dt0.getHour() == dt1.getHour())
             {
-               if   (dt0.getDay()  < dt1.getDay())
-               {
-                   return true;
-               }
-               else if (dt0.getDay() == dt1.getDay())
-               {
-                  if    (dt0.getHour()  < dt1.getHour())
-                  {
-                     return true;
-                  }
-                  else if (dt0.getHour() == dt1.getHour())
-                  {
-                     if   (dt0.getMinute()  < dt1.getMinute())
-                     {
-                        return true;
-                     }
-                     else if (dt0.getMinute() == dt1.getMinute())
-                     {
-                        if (dt0.getSecond() < dt1.getSecond())
-                           return true;
-                     }
-                  }
-               }
+              if (dt0.getMinute() < dt1.getMinute())
+              {
+                return true;
+              }
+              else if (dt0.getMinute() == dt1.getMinute())
+              {
+                if (dt0.getSecond() < dt1.getSecond())
+                  return true;
+              }
             }
-         }
-         return false;
-      }
-
-      //-----------------------------------------------------------------
-
-      bool operator!=(const CDate& dt0, const CDate& dt1){ return !(dt1 == dt0); }
-      bool operator> (const CDate& dt0, const CDate& dt1){ return (dt1 < dt0); }
-      bool operator>=(const CDate& dt0, const CDate& dt1){ return ((dt0 > dt1) || (dt1 == dt0)); }
-      bool operator<=(const CDate& dt0, const CDate& dt1){ return ((dt0 < dt1) || (dt1 == dt0)); }
-
-      ///----------------------------------------------------------------
+          }
+        }
+      }
+      return false;
+    }
+
+    //-----------------------------------------------------------------
+
+    bool operator!=(const CDate& dt0, const CDate& dt1) { return !(dt1 == dt0); }
+    bool operator> (const CDate& dt0, const CDate& dt1) { return (dt1 < dt0); }
+    bool operator>=(const CDate& dt0, const CDate& dt1) { return (dt0 > dt1 || dt1 == dt0); }
+    bool operator<=(const CDate& dt0, const CDate& dt1) { return (dt0 < dt1 || dt1 == dt0); }
+
+    ///----------------------------------------------------------------
 
 } // namespace xios
Index: /XIOS/trunk/src/config/calendar_wrapper_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/calendar_wrapper_attribute.conf	(revision 549)
+++ /XIOS/trunk/src/config/calendar_wrapper_attribute.conf	(revision 550)
@@ -1,3 +1,3 @@
-DECLARE_ENUM5(type, D360, AllLeap, NoLeap, Julian, Gregorian)
+DECLARE_ENUM6(type, D360, AllLeap, NoLeap, Julian, Gregorian, user_defined)
 DECLARE_ATTRIBUTE(CDuration, timestep)
 // The start date and time origin are declared as string attributes instead
@@ -5,2 +5,8 @@
 DECLARE_ATTRIBUTE(string, start_date)
 DECLARE_ATTRIBUTE(string, time_origin)
+DECLARE_ATTRIBUTE(int, day_length)
+DECLARE_ARRAY(int, 1, month_lengths)
+DECLARE_ATTRIBUTE(int, year_length)
+DECLARE_ATTRIBUTE(double, leap_year_drift)
+DECLARE_ATTRIBUTE(double, leap_year_drift_offset)
+DECLARE_ATTRIBUTE(int, leap_year_month)
Index: /XIOS/trunk/src/date.cpp
===================================================================
--- /XIOS/trunk/src/date.cpp	(revision 549)
+++ /XIOS/trunk/src/date.cpp	(revision 550)
@@ -87,57 +87,10 @@
       }
 
-      StdIStream& operator>>(StdIStream& in, CDate& date) // Non testÃ©e.
-      {
-        char sep = '-'; // Le caractÃšre c est utilisÃ© pour "recueillir" les sÃ©parateurs "/" et ":".
-        char c;
-
-        // Default initialize the date
-        date.year = 0;
-        date.month = 1;
-        date.day = 1;
-        date.hour = 0;
-        date.minute = 0;
-        date.second = 0;
-
-        in >> date.year >> c;
-        if (c == sep)
-        {
-          in >> date.month >> c;
-          if (c == sep)
-          {
-            in >> date.day;
-            c = in.get();
-            sep = ' ';
-            if (c == sep)
-            {
-              in >> date.hour >> c;
-              sep = ':';
-              if (c == sep)
-              {
-                in>>date.minute >> c;
-                if (c == sep)
-                {
-                  in >> date.second;
-                  in >> c;
-                }
-              }
-            }
-          }
-        }
-
-        // Delay the verification until we get a calendar we can compare the date to
-        if (date.relCalendar && !date.checkDate())
-          ERROR("StdIStream& operator >> (StdIStream& in, CDate& date)",
-                << "Bad date format or not conform to calendar");
-
-        if (c == '+') // We will be adding a duration to the date
-        {
-          CDuration dur;
-          in >> dur;
-          date = date + dur;
-        }
-        else if (!in.eof())
-          ERROR("StdIStream& operator >> (StdIStream& in, CDate& date)",
-                << "Invalid date format: unexpected trailing character(s)");
+      StdIStream& operator>>(StdIStream& in, CDate& date)
+      {
+        if (date.relCalendar)
+          date.relCalendar->parseDate(in, date);
+        else
+          CCalendar::parseDateDefault(in, date);
 
         return in;
@@ -152,12 +105,12 @@
         Time retvalue = getSecondOfYear() - c.getTimeOrigin().getSecondOfYear();
 
-        if ((c.getId().compare("D360")    == 0) ||
-            (c.getId().compare("AllLeap") == 0) ||
-            (c.getId().compare("NoLeap")  == 0))
-        return (retvalue + (getYear() - c.getTimeOrigin().getYear())
-                                      * c.getYearTotalLength(*this));
-
-        for (CDate _d(c.getTimeOrigin()); _d.getYear() < getYear(); _d.setYear(_d.getYear() + 1))
-           retvalue += c.getYearTotalLength(_d);
+        if (c.hasLeapYear())
+        {
+          for (CDate _d(c.getTimeOrigin()); _d.getYear() < getYear(); _d.setYear(_d.getYear() + 1))
+            retvalue += c.getYearTotalLength(_d);
+        }
+        else
+          retvalue += (getYear() - c.getTimeOrigin().getYear()) * c.getYearTotalLength(*this);
+
 
         return retvalue;
@@ -168,35 +121,6 @@
       bool CDate::checkDate(void)
       {
-        bool retValue = true;
-
-        // This will check that a calendar was correctly associated to the date
-        const CCalendar& c = getRelCalendar();
-
-        // VÃ©rification de la valeur du mois.
-        if (month  < 1) { retValue = false; month  = 1; }
-        if (month  > c.getYearLength())
-        { retValue = false; month = c.getYearLength(); }
-
-        // VÃ©rification de la valeur du jour.
-        if (day    < 1) { retValue = false; day  = 1; }
-        if (day    > c.getMonthLength(*this))
-        { retValue = false; day = c.getMonthLength(*this); }
-
-        // VÃ©rification de la valeur de l'heure.
-        if (hour   < 0) { retValue = false; hour  = 0; }
-        if (hour   >= c.getDayLength())
-        { retValue = false; hour = c.getDayLength() - 1; }
-
-        // VÃ©rification de la valeur des minutes.
-        if (minute < 0) { retValue = false; minute = 0; }
-        if (minute >= c.getHourLength())
-        { retValue = false; minute = c.getHourLength() - 1; }
-
-        // VÃ©rification de la valeur des secondes.
-        if (second < 0) { retValue = false; second = 0; }
-        if (second >= c.getMinuteLength())
-        { retValue = false; second = c.getMinuteLength() - 1; }
-
-        return retValue;
+        // This will also check that a calendar was correctly associated to the date
+        return getRelCalendar().checkDate(*this);
       }
 
@@ -238,6 +162,8 @@
           nbDay += c.getMonthLength(yearStart);
 
-        return ((((nbDay + getDay() - 1) * c.getDayLength() + getHour()) * c.getHourLength()
-                   + getMinute()) * c.getMinuteLength() + getSecond());
+        // We need to use getDayLengthInSeconds instead of getDayLength since we might
+        // have a non-integral number of hours per day for user defined calendars
+        return ((nbDay + getDay() - 1) * c.getDayLengthInSeconds()
+                  + (getHour() * c.getHourLength() + getMinute()) * c.getMinuteLength() + getSecond());
       }
 
Index: /XIOS/trunk/src/date.hpp
===================================================================
--- /XIOS/trunk/src/date.hpp	(revision 549)
+++ /XIOS/trunk/src/date.hpp	(revision 550)
@@ -33,5 +33,5 @@
             CDate& operator=(const CDate& date);
             friend StdOStream& operator<<(StdOStream& out, const CDate& date);
-            friend StdIStream& operator>>(StdIStream& in, CDate& date); // Non testÃ©e.
+            friend StdIStream& operator>>(StdIStream& in, CDate& date);
 
             //!< Return the number of seconds since the time origin fixed when creating the calendar
Index: /XIOS/trunk/src/date/calendar_type.hpp
===================================================================
--- /XIOS/trunk/src/date/calendar_type.hpp	(revision 549)
+++ /XIOS/trunk/src/date/calendar_type.hpp	(revision 550)
@@ -7,4 +7,5 @@
 #include "julian.hpp"
 #include "noleap.hpp"
+#include "user_defined.hpp"
 
 #endif //__XMLIO_calendar_type__
Index: /XIOS/trunk/src/date/gregorian.cpp
===================================================================
--- /XIOS/trunk/src/date/gregorian.cpp	(revision 549)
+++ /XIOS/trunk/src/date/gregorian.cpp	(revision 550)
@@ -33,5 +33,5 @@
       ///--------------------------------------------------------------
 
-      int CGregorianCalendar::getYearTotalLength(const CDate & date) const
+      int CGregorianCalendar::getYearTotalLength(const CDate& date) const
       { // Retourne la durÃ©e d'une annÃ©e en seconde.
          if ((date.getYear() % 4   == 0) &&
@@ -42,5 +42,5 @@
       }
 
-      int CGregorianCalendar::getMonthLength(const CDate & date) const
+      int CGregorianCalendar::getMonthLength(const CDate& date) const
       { // Retourne la durÃ©e du mois en jour.
          if (date.getMonth() == 2)
@@ -58,4 +58,6 @@
       { return (StdString("gregorian")); }
 
+      bool CGregorianCalendar::hasLeapYear() const { return true; }
+
       ///--------------------------------------------------------------
 } // namespace xmlioserver
Index: /XIOS/trunk/src/date/gregorian.hpp
===================================================================
--- /XIOS/trunk/src/date/gregorian.hpp	(revision 549)
+++ /XIOS/trunk/src/date/gregorian.hpp	(revision 550)
@@ -30,4 +30,6 @@
             virtual StdString getType(void) const;
 
+            virtual bool hasLeapYear() const;
+
             /// Destructeur ///
             virtual ~CGregorianCalendar(void);
Index: /XIOS/trunk/src/date/julian.cpp
===================================================================
--- /XIOS/trunk/src/date/julian.cpp	(revision 549)
+++ /XIOS/trunk/src/date/julian.cpp	(revision 550)
@@ -33,5 +33,5 @@
       ///--------------------------------------------------------------
 
-      int CJulianCalendar::getYearTotalLength(const CDate & date) const
+      int CJulianCalendar::getYearTotalLength(const CDate& date) const
       { // Retourne la durÃ©e d'une annÃ©e en seconde.
          if (date.getYear() % 4 == 0) return (366 * 86400);
@@ -39,5 +39,5 @@
       }
 
-      int CJulianCalendar::getMonthLength(const CDate & date) const
+      int CJulianCalendar::getMonthLength(const CDate& date) const
       { // Retourne la durÃ©e du mois en jour.
          if (date.getMonth() == 2)
@@ -52,4 +52,6 @@
       { return (StdString("julian")); }
 
+      bool CJulianCalendar::hasLeapYear() const { return true; }
+
       ///--------------------------------------------------------------
 } // namespace xmlioserver
Index: /XIOS/trunk/src/date/julian.hpp
===================================================================
--- /XIOS/trunk/src/date/julian.hpp	(revision 549)
+++ /XIOS/trunk/src/date/julian.hpp	(revision 550)
@@ -30,4 +30,6 @@
             virtual StdString getType(void) const;
 
+            virtual bool hasLeapYear() const;
+
             /// Destructeur ///
             virtual ~CJulianCalendar(void);
Index: /XIOS/trunk/src/date/user_defined.cpp
===================================================================
--- /XIOS/trunk/src/date/user_defined.cpp	(revision 550)
+++ /XIOS/trunk/src/date/user_defined.cpp	(revision 550)
@@ -0,0 +1,268 @@
+#include "user_defined.hpp"
+#include "calendar_util.hpp"
+
+namespace xios
+{
+  /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+  CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, const CArray<int,1>& monthLengths)
+    : CCalendar("user_defined")
+    , dayLength(dayLength)
+    , monthLengths(monthLengths)
+    , yearLength(sum(monthLengths) * dayLength)
+    , leapYearMonth(0)
+    , leapYearDrift(0.0)
+    , leapYearDriftOffset(0.0)
+  {
+    if (dayLength <= 0)
+      ERROR("CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, const CArray<int,1>& monthLengths)",
+            << "The day length must be strictly positive.");
+    if (monthLengths.numElements() == 0)
+      ERROR("CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, const CArray<int,1>& monthLengths)",
+            << "The month lengths must be specified.");
+    if (min(monthLengths) <= 0)
+      ERROR("CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, const CArray<int,1>& monthLengths)",
+            << "All month lengths must be strictly positive.");
+    // Ensure that the month lengths array is always 0-indexed
+    this->monthLengths.reindexSelf(TinyVector<int, 1>(0));
+  }
+
+  CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, int yearLength)
+    : CCalendar("user_defined")
+    , dayLength(dayLength)
+    , yearLength(yearLength)
+    , leapYearMonth(0)
+    , leapYearDrift(0.0)
+    , leapYearDriftOffset(0.0)
+  {
+    if (dayLength <= 0)
+      ERROR("CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, int yearLength)",
+            << "The day length must be strictly positive.");
+    if (yearLength <= 0)
+      ERROR("CUserDefinedCalendar::CUserDefinedCalendar(int dayLength, int yearLength)",
+            << "The year length must be strictly positive.");
+  }
+
+  CUserDefinedCalendar::~CUserDefinedCalendar(void)
+  { /* Nothing to do here */ }
+
+  ///--------------------------------------------------------------
+
+  void CUserDefinedCalendar::configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset /*= 0.0*/)
+  {
+    if (monthLengths.numElements() == 0)
+      ERROR("void CUserDefinedCalendar::configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset /*= 0.0*/)",
+            << "Impossible to define leap years on a calendar without months.");
+    if (leapYearMonth < 1 || leapYearMonth > monthLengths.numElements())
+      ERROR("void CUserDefinedCalendar::configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset /*= 0.0*/)",
+            << "The month chosen for the additional day must be in the range [1, " << monthLengths.numElements() << "].");
+    if (leapYearDrift < 0.0 || leapYearDrift >= 1.0)
+      ERROR("void CUserDefinedCalendar::configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset /*= 0.0*/)",
+            << "The year drift must be in the range [0.0, 1.0).");
+    if (leapYearDriftOffset < 0.0 || leapYearDriftOffset >= 1.0)
+      ERROR("void CUserDefinedCalendar::configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset /*= 0.0*/)",
+            << "The year drift offset must be in the range [0.0, 1.0).");
+
+    this->leapYearMonth = leapYearMonth;
+    this->leapYearDrift = leapYearDrift;
+    this->leapYearDriftOffset = leapYearDriftOffset;
+  }
+
+  ///--------------------------------------------------------------
+
+  StdString CUserDefinedCalendar::getType(void) const { return StdString("user_defined"); }
+
+  /*! Returns the duration of the date's month in days. */
+  int CUserDefinedCalendar::getMonthLength(const CDate& date) const
+  {
+    int monthLength = 0;
+    if (monthLengths.numElements() > 0)
+    {
+      monthLength = monthLengths(date.getMonth() - 1);
+      if (date.getMonth() == leapYearMonth && isLeapYear(date.getYear()))
+        monthLength++;
+    }
+    return monthLength;
+  }
+
+  /*! Returns the duration of the date's year in seconds. */
+  int CUserDefinedCalendar::getYearTotalLength(const CDate& date) const
+  {
+    return isLeapYear(date.getYear()) ? yearLength + dayLength : yearLength;
+  }
+
+  /*! Returns the duration of a day in hours. Note that this value is
+      not necessarily exact since it can be rounded but it is always
+      the smallest integer number of hours that can hold a day. */
+  int CUserDefinedCalendar::getDayLength(void) const { return int(ceil(double(dayLength) / (getHourLength() * getMinuteLength()))); }
+
+  /*! Returns the duration of a year in months. */
+  int CUserDefinedCalendar::getYearLength(void) const { return monthLengths.numElements(); }
+
+  /*! Returns the day length expressed in seconds. */
+  int CUserDefinedCalendar::getDayLengthInSeconds(void) const { return dayLength; }
+
+  /*! Test if the calendar can have leap year. */
+  bool CUserDefinedCalendar::hasLeapYear() const{ return (leapYearDrift != 0.0); }
+
+  /*!
+    Test if the specified year is a leap year.
+    \param year the year to be tested
+    \return true if and only the specified year is a leap year
+  */
+  bool CUserDefinedCalendar::isLeapYear(int year) const
+  {
+    double intPart; // dummy variable
+    return (hasLeapYear() &&
+            (abs(1.0 - (modf(leapYearDriftOffset + (year - getTimeOrigin().getYear()) * leapYearDrift, &intPart) + leapYearDrift)) < 1e-14));
+  }
+
+  CDuration& CUserDefinedCalendar::resolve(CDuration& dur, bool noNegativeTime /*= false*/) const
+  {
+    if (monthLengths.numElements() > 0) // normal case, we can rely on the generic function
+      return CCalendar::resolve(dur, noNegativeTime);
+
+    if (dur.month)
+      ERROR("CDuration& CUserDefinedCalendar::resolve(CDuration& dur, bool noNegativeTime /*= false*/) const",
+            << "month = " << dur.month << " but the user defined calendar has no month.");
+
+    const int hourLengthInSeconds = getHourLength() * getMinuteLength();
+
+    // Convert everything in seconds
+    Time t = Time(dur.year * yearLength + dur.day * dayLength
+                    + (dur.hour * getHourLength() + dur.minute) * getMinuteLength() + dur.second);
+
+    // Then convert back to years
+    dur.year = int(t / yearLength);
+    t %= yearLength;
+
+    // days
+    dur.day = int(t / dayLength);
+    t %= dayLength;
+
+    // Do we allow hour, minute, second to be negative?
+    if (noNegativeTime)
+    {
+      // If we don't, we remove some days or years until the time is positive
+      double& val = (dayLength < yearLength) ? dur.day : dur.year;
+      int length  = (dayLength < yearLength) ? dayLength : yearLength;
+      while (t < 0)
+      {
+        t += length;
+        val -= 1.0;
+      }
+    }
+
+    // hours
+    dur.hour = int(t / hourLengthInSeconds);
+    t %= hourLengthInSeconds;
+    // minutes
+    dur.minute = int(t / getMinuteLength());
+    // secondes
+    dur.second = int(t % getMinuteLength());
+
+    return dur;
+  }
+
+  /*! Parse a date using the calendar's parser. */
+  void CUserDefinedCalendar::parseDate(StdIStream& in, CDate& date) const
+  {
+    if (monthLengths.numElements() > 0) // normal case, we can rely on the generic function
+    {
+      CCalendar::parseDate(in, date);
+      return;
+    }
+
+    char sep = '-'; // Le caractÃšre c est utilisÃ© pour "recueillir" les sÃ©parateurs "/" et ":".
+    char c;
+
+    // Default initialize the date
+    int year = 00, month  = 01, day    = 01;
+    int hour = 00, minute = 00, second = 00;
+
+    // Read the year
+    in >> year;
+    // Read the day only if the day length is smaller than the year length
+    c = in.get();
+    if (c == sep && dayLength < yearLength)
+    {
+      in >> day;
+      c = in.get();
+    }
+    // Read the time
+    sep = ' ';
+    if (c == sep)
+    {
+      in >> hour >> c;
+      sep = ':';
+      if (c == sep)
+      {
+        in >> minute >> c;
+        if (c == sep)
+        {
+          in >> second;
+          in >> c;
+        }
+      }
+    }
+
+    date.setDate(year, month, day, hour, minute, second);
+
+    // Delay the verification until we get a calendar we can compare the date to
+    if (!checkDate(date))
+      ERROR("void CUserDefinedCalendar::parseDate(StdIStream& in, CDate& date) const",
+            << "Bad date format or not conform to calendar");
+
+    if (c == '+') // We will be adding a duration to the date
+    {
+      CDuration dur;
+      in >> dur;
+      date = date + dur;
+    }
+    else if (!in.eof())
+      ERROR("void CUserDefinedCalendar::parseDate(StdIStream& in, CDate& date) const",
+            << "Invalid date format: unexpected trailing character(s)");
+  }
+
+  /*! Test if a date is valid with regard to the current calendar. */
+  bool CUserDefinedCalendar::checkDate(CDate& date) const
+  {
+    if (monthLengths.numElements() > 0) // normal case, we can rely on the generic function
+      return CCalendar::checkDate(date);
+
+    const int maxDay = (yearLength + dayLength - 1) / dayLength;
+
+    bool isValid = true;
+
+    // VÃ©rification de la valeur du mois.
+    if (date.getMonth() != 1)
+    { isValid = false; date.setMonth(1); }
+
+    // VÃ©rification de la valeur du jour.
+    if (date.getDay() < 1)
+    { isValid = false; date.setDay(1); }
+    else if (date.getDay() > maxDay)
+    { isValid = false; date.setDay(maxDay); }
+
+    // VÃ©rification de la valeur de l'heure.
+    if (date.getHour() < 0)
+    { isValid = false; date.setHour(0); }
+    else if (date.getHour() >= getDayLength())
+    { isValid = false; date.setHour(getDayLength() - 1); }
+
+    // VÃ©rification de la valeur des minutes.
+    if (date.getMinute() < 0)
+    { isValid = false; date.setMinute(0); }
+    else if (date.getMinute() >= getHourLength())
+    { isValid = false; date.setMinute(getHourLength() - 1); }
+
+    // VÃ©rification de la valeur des secondes.
+    if (date.getSecond() < 0)
+    { isValid = false; date.setSecond(0); }
+    else if (date.getSecond() >= getMinuteLength())
+    { isValid = false; date.setSecond(getMinuteLength() - 1); }
+
+    return isValid;
+  }
+} // namespace xmlioserver
+
Index: /XIOS/trunk/src/date/user_defined.hpp
===================================================================
--- /XIOS/trunk/src/date/user_defined.hpp	(revision 550)
+++ /XIOS/trunk/src/date/user_defined.hpp	(revision 550)
@@ -0,0 +1,73 @@
+#ifndef __XMLIO_CUserDefinedCalendar__
+#define __XMLIO_CUserDefinedCalendar__
+
+/// xios headers ///
+#include "xmlioserver_spl.hpp"
+#include "calendar.hpp"
+#include "array_new.hpp"
+
+namespace xios
+{
+  /// ////////////////////// DÃ©clarations ////////////////////// ///
+  /*! A custom calendar that we can configured to be suitable for planets other than the Earth. */
+  class CUserDefinedCalendar : public CCalendar
+  {
+    private:
+      /// Typedef ///
+      typedef CCalendar SuperClass;
+
+    public:
+      /// Constructor ///
+      CUserDefinedCalendar(int dayLength, const CArray<int,1>& monthLengths);
+      CUserDefinedCalendar(int dayLength, int yearLength);
+
+      /// Destructor ///
+      virtual ~CUserDefinedCalendar(void);
+
+      /// Setters ///
+      /*! Configure the leap year information. */
+      void configureLeapYear(int leapYearMonth, double leapYearDrift, double leapYearDriftOffset = 0.0);
+
+      /// Getters ///
+      virtual StdString getType(void) const;
+
+      /*! Returns the duration of the date's month in days. */
+      virtual int getMonthLength(const CDate& date) const;
+      /*! Returns the duration of the date's year in seconds. */
+      virtual int getYearTotalLength(const CDate& date) const;
+      /*! Returns the duration of a day in hours. Note that this value is
+          not necessarily exact since it can be rounded but it is always
+          the smallest integer number of hours that can hold a day. */
+      virtual int getDayLength(void) const;
+      /*! Returns the duration of a year in months. */
+      virtual int getYearLength(void) const;
+      /*! Returns the day length expressed in seconds. */
+      virtual int getDayLengthInSeconds(void) const;
+      /*! Test if the calendar can have leap year. */
+      virtual bool hasLeapYear() const;
+
+      /*! Simplify a duration based on the calendar information. */
+      virtual CDuration& resolve(CDuration& dur, bool noNegativeTime = false) const;
+
+      /*! Parse a date using the calendar's parser. */
+      virtual void parseDate(StdIStream& in, CDate& date) const;
+
+      /*! Test if a date is valid with regard to the current calendar. */
+      virtual bool checkDate(CDate& date) const;
+
+    private:
+      int dayLength; //!< length of a day in seconds
+      CArray<int,1> monthLengths; //!< length of each months in days
+      int yearLength; //!< length of a year in seconds
+
+      int leapYearMonth; //!< month to which an extra day should be added in case of a leap year
+      double leapYearDrift; //!< yearly drift (fraction of a day, must be in range [0, 1))
+      double leapYearDriftOffset; //!< initial drift (fraction of a day, must be in range [0, 1))
+
+      /*! Test if the specified year is a leap year. */
+      bool isLeapYear(int year) const;
+  }; // class CUserDefinedCalendar
+
+} // namespace xmlioserver
+
+#endif // __XMLIO_CUserDefinedCalendar__
Index: /XIOS/trunk/src/duration.cpp
===================================================================
--- /XIOS/trunk/src/duration.cpp	(revision 549)
+++ /XIOS/trunk/src/duration.cpp	(revision 550)
@@ -2,42 +2,45 @@
 #include "date.hpp"
 #include "calendar.hpp"
+#include "calendar_util.hpp"
 
 namespace xios
 {
       /// ////////////////////// DÃ©finitions ////////////////////// ///
-      const CDuration Year   = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-                      Month  = {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-                      Week   = {0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0},
-                      Day    = {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
-                      Hour   = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
-                      Minute = {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
-                      Second = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
-                      NoneDu = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-                      TimeStep = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+      const CDuration Year     = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
+                      Month    = { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
+                      Week     = { 0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0 },
+                      Day      = { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 },
+                      Hour     = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 },
+                      Minute   = { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 },
+                      Second   = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 },
+                      TimeStep = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 },
+                      NoneDu   = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
 
       ///---------------------------------------------------------------
 
-      CDuration & CDuration::operator=(const CDuration & duration)
+      CDuration& CDuration::operator=(const CDuration& duration)
       {
-         year = duration.year;  month  = duration.month ; day    = duration.day;
-         hour = duration.hour;  minute = duration.minute; second = duration.second; timestep=duration.timestep ;
-         return (*this);
+        year = duration.year; month  = duration.month;  day    = duration.day;
+        hour = duration.hour; minute = duration.minute; second = duration.second; timestep = duration.timestep;
+        return *this;
       }
 
-      StdOStream & operator<<(StdOStream & out, const CDuration & duration)
+      StdOStream& operator<<(StdOStream& out, const CDuration& duration)
       {
-         StdOStringStream sout;
-         bool testValue = true;
-         if(duration.year   != 0.0) { testValue = false; sout << duration.year   << "y " ; }
-         if(duration.month  != 0.0) { testValue = false; sout << duration.month  << "mo "; }
-         if(duration.day    != 0.0) { testValue = false; sout << duration.day    << "d " ; }
-         if(duration.hour   != 0.0) { testValue = false; sout << duration.hour   << "h " ; }
-         if(duration.minute != 0.0) { testValue = false; sout << duration.minute << "mi "; }
-         if(duration.second != 0.0) { testValue = false; sout << duration.second << "s " ; }
-         if(duration.timestep != 0.0 || testValue)       { sout << duration.timestep << "ts " ; }
+        StdOStringStream sout;
+        bool forceOutput = true;
 
-         // << suppression de l'espace en fin de chaÃ®ne.
-         out << (sout.str().substr(0, sout.str().size()-1));
-         return (out);
+        if (duration.year   != 0.0) { forceOutput = false; sout << duration.year   << "y "; }
+        if (duration.month  != 0.0) { forceOutput = false; sout << duration.month  << "mo "; }
+        if (duration.day    != 0.0) { forceOutput = false; sout << duration.day    << "d "; }
+        if (duration.hour   != 0.0) { forceOutput = false; sout << duration.hour   << "h "; }
+        if (duration.minute != 0.0) { forceOutput = false; sout << duration.minute << "mi "; }
+        if (duration.second != 0.0) { forceOutput = false; sout << duration.second << "s "; }
+        if (duration.timestep != 0.0 || forceOutput)     { sout << duration.timestep << "ts "; }
+
+        // suppression de l'espace en fin de chaÃ®ne.
+        StdString strOut = sout.str();
+        out << strOut.erase(strOut.size() - 1);
+        return out;
       }
 
@@ -78,5 +81,5 @@
             }
             default:
-              invalidUnit = true; 
+              invalidUnit = true;
               break;
           }
@@ -85,5 +88,5 @@
             ERROR("StdIStream& operator>>(StdIStream& in , CDuration& duration)",
                   << "Bad duration format: invalid unit, unexpected '" << c << "' character.");
-        } while (in.peek() != EOF); // check whether there is a next character to read 
+        } while (in.peek() != EOF); // check whether there is a next character to read
 
         return in;
@@ -94,45 +97,24 @@
       bool CDuration::isNone(void) const
       {
-         if ((year == 0) && (month  == 0) && (day    == 0) &&
-             (hour == 0) && (minute == 0) && (second == 0) && (timestep == 0))
-            return (true);
-         return (false);
+        return (*this == NoneDu);
       }
 
       //-----------------------------------------------------------------
-      CDuration & CDuration::solveTimeStep(const CCalendar & c)
+
+      CDuration& CDuration::solveTimeStep(const CCalendar& c)
       {
-        CDuration timeStep=c.getTimeStep() ;
-        second +=timestep*timeStep.second ; 
-        minute +=timestep*timeStep.minute ; 
-        hour +=timestep*timeStep.hour ; 
-        day +=timestep*timeStep.day ; 
-        month +=timestep*timeStep.month ; 
-        year +=timestep*timeStep.year ; 
-        timestep = 0 ;
+        CDuration timeStep = c.getTimeStep();
+        second += timestep * timeStep.second;
+        minute += timestep * timeStep.minute;
+        hour   += timestep * timeStep.hour;
+        day    += timestep * timeStep.day;
+        month  += timestep * timeStep.month;
+        year   += timestep * timeStep.year;
+        timestep = 0.0;
+      }
 
-      }
-               
-        
-      CDuration & CDuration::resolve(const CCalendar & c)
+      CDuration& CDuration::resolve(const CCalendar& c, bool noNegativeTime /*= false*/)
       {
-         // Simplification de l'Ã©criture des minutes.
-         second += modf(minute, &minute) * (float)c.getMinuteLength();
-         minute += int(second)/c.getMinuteLength(); second = int(second)%c.getMinuteLength();
-
-         // Simplification de l'Ã©criture des heures.
-         minute += modf(hour , &hour) * (float)c.getHourLength();
-         hour   += int(minute)/c.getHourLength(); minute = int(minute)%c.getHourLength();
-
-         // Simplification de l'Ã©criture des jours.
-         hour   += modf(day, &day) * (float)c.getDayLength();
-         day    += int(hour)  /c.getDayLength(); hour   = int(hour)%c.getDayLength();
-
-         // > Aucune Ã©quivalence jour - mois fixÃ©e par avance. //
-
-         // Simplification de l'Ã©criture des annÃ©es.
-         month  += modf(year, &year) * (float)c.getYearLength();
-         year   += int(month) /c.getYearLength(); month  = int(month)%c.getYearLength();
-         return (*this);
+        return c.resolve(*this, noNegativeTime);
       }
 
@@ -141,19 +123,14 @@
       StdString CDuration::toString(void) const
       {
-         const  CDuration & own = *this;
-         StdOStringStream oss; oss << own;
-         return (oss.str());
+        StdOStringStream oss; oss << *this;
+        return oss.str();
       }
 
-      CDuration CDuration::FromString(const StdString & str)
+      CDuration CDuration::FromString(const StdString& str)
       {
-         CDuration dr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
-         StdIStringStream iss(str); iss >> dr;
-         return (dr);
+        CDuration dr = NoneDu;
+        StdIStringStream iss(str); iss >> dr;
+        return dr;
       }
-
-      ///---------------------------------------------------------------
-
-
 } // namespace xios
 
Index: /XIOS/trunk/src/duration.hpp
===================================================================
--- /XIOS/trunk/src/duration.hpp	(revision 549)
+++ /XIOS/trunk/src/duration.hpp	(revision 550)
@@ -13,13 +13,16 @@
 
       ///---------------------------------------------------------------
-      typedef struct _duration
+
+      struct CDuration
       {
-         public :
+         public: /* static */
+            static CDuration FromString(const StdString& str);
 
+         public:
             /// OpÃ©rateurs ///
-            struct _duration & operator=(const struct _duration& duration);
+            CDuration& operator=(const CDuration& duration);
 
-            friend StdOStream & operator<<(StdOStream & out, const struct _duration& duration);
-            friend StdIStream & operator>>(StdIStream & in , struct _duration& duration);
+            friend StdOStream& operator<<(StdOStream& out, const CDuration& duration);
+            friend StdIStream& operator>>(StdIStream& in , CDuration& duration);
 
             /// Test ///
@@ -27,24 +30,17 @@
 
             /// Traitement ///
-            struct _duration & resolve(const CCalendar & calendar);
-            struct _duration & solveTimeStep(const CCalendar & c) ;
+            CDuration& resolve(const CCalendar& calendar, bool noNegativeTime = false);
+            CDuration& solveTimeStep(const CCalendar& c);
             /// Autres ///
             StdString toString(void) const;
 
-         public: /* static */
-
-            static struct _duration FromString(const StdString & str);
-
             /// PropriÃ©tÃ©s publiques ///
             double year, month, day, hour, minute, second, timestep;
-
-      } CDuration;
+      };
 
       ///---------------------------------------------------------------
 
-      const extern CDuration Year, Month , Week  , Day    ,
-                             Hour, Minute, Second, NoneDu, TimeStep ;
-      ///---------------------------------------------------------------
-
+      const extern CDuration Year, Month,  Week,   Day,
+                             Hour, Minute, Second, TimeStep, NoneDu;
 } // namespace xios
 
Index: /XIOS/trunk/src/interface/c_attr/iccalendar_wrapper_attr.cpp
===================================================================
--- /XIOS/trunk/src/interface/c_attr/iccalendar_wrapper_attr.cpp	(revision 549)
+++ /XIOS/trunk/src/interface/c_attr/iccalendar_wrapper_attr.cpp	(revision 550)
@@ -18,4 +18,113 @@
   typedef xios::CCalendarWrapper*  calendar_wrapper_Ptr;
   
+  void cxios_set_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int day_length)
+  {
+     CTimer::get("XIOS").resume();
+    calendar_wrapper_hdl->day_length.setValue(day_length);
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int* day_length)
+  {
+    *day_length = calendar_wrapper_hdl->day_length.getInheritedValue();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->day_length.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
+  void cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl, double leap_year_drift)
+  {
+     CTimer::get("XIOS").resume();
+    calendar_wrapper_hdl->leap_year_drift.setValue(leap_year_drift);
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl, double* leap_year_drift)
+  {
+    *leap_year_drift = calendar_wrapper_hdl->leap_year_drift.getInheritedValue();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->leap_year_drift.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
+  void cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl, double leap_year_drift_offset)
+  {
+     CTimer::get("XIOS").resume();
+    calendar_wrapper_hdl->leap_year_drift_offset.setValue(leap_year_drift_offset);
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl, double* leap_year_drift_offset)
+  {
+    *leap_year_drift_offset = calendar_wrapper_hdl->leap_year_drift_offset.getInheritedValue();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->leap_year_drift_offset.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
+  void cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl, int leap_year_month)
+  {
+     CTimer::get("XIOS").resume();
+    calendar_wrapper_hdl->leap_year_month.setValue(leap_year_month);
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl, int* leap_year_month)
+  {
+    *leap_year_month = calendar_wrapper_hdl->leap_year_month.getInheritedValue();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->leap_year_month.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
+  void cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl, int* month_lengths, int extent1)
+  {
+    CTimer::get("XIOS").resume();
+    CArray<int,1> tmp(month_lengths,shape(extent1),neverDeleteData) ;
+    calendar_wrapper_hdl->month_lengths.reference(tmp.copy());
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl, int* month_lengths, int extent1)
+  {
+    CTimer::get("XIOS").resume();
+    CArray<int,1> tmp(month_lengths,shape(extent1),neverDeleteData) ;
+    tmp=calendar_wrapper_hdl->month_lengths.getInheritedValue() ;
+     CTimer::get("XIOS").suspend();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->month_lengths.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
   void cxios_set_calendar_wrapper_start_date(calendar_wrapper_Ptr calendar_wrapper_hdl, const char * start_date, int start_date_size)
   {
@@ -134,4 +243,25 @@
   
   
+  void cxios_set_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int year_length)
+  {
+     CTimer::get("XIOS").resume();
+    calendar_wrapper_hdl->year_length.setValue(year_length);
+     CTimer::get("XIOS").suspend();
+  }
+  
+  void cxios_get_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl, int* year_length)
+  {
+    *year_length = calendar_wrapper_hdl->year_length.getInheritedValue();
+  }
+  
+  bool cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_Ptr calendar_wrapper_hdl )
+  {
+     CTimer::get("XIOS").resume();
+    return calendar_wrapper_hdl->year_length.hasInheritedValue();
+     CTimer::get("XIOS").suspend();
+  }
+  
+  
+  
   
 }
Index: /XIOS/trunk/src/interface/fortran/icalendar.F90
===================================================================
--- /XIOS/trunk/src/interface/fortran/icalendar.F90	(revision 549)
+++ /XIOS/trunk/src/interface/fortran/icalendar.F90	(revision 550)
@@ -20,5 +20,7 @@
    CONTAINS ! Fonctions disponibles pour les utilisateurs.
 
-   SUBROUTINE xios(define_calendar)(type, timestep, start_date, time_origin)
+   SUBROUTINE xios(define_calendar)(type, timestep, start_date, time_origin, &
+                                    day_length, month_lengths, year_length, &
+                                    leap_year_month, leap_year_drift, leap_year_drift_offset)
       USE ICALENDAR_WRAPPER, ONLY : txios(calendar_wrapper), xios(get_default_calendar_wrapper_handle)
       USE icalendar_wrapper_attr, ONLY : xios(set_calendar_wrapper_attr_hdl)
@@ -30,4 +32,10 @@
       TYPE(txios(date)),     OPTIONAL, INTENT(IN) :: start_date
       TYPE(txios(date)),     OPTIONAL, INTENT(IN) :: time_origin
+      INTEGER,               OPTIONAL, INTENT(IN) :: day_length
+      INTEGER,               OPTIONAL, INTENT(IN) :: month_lengths(:)
+      INTEGER,               OPTIONAL, INTENT(IN) :: year_length
+      REAL (KIND=8),         OPTIONAL, INTENT(IN) :: leap_year_drift
+      REAL (KIND=8),         OPTIONAL, INTENT(IN) :: leap_year_drift_offset
+      INTEGER,               OPTIONAL, INTENT(IN) :: leap_year_month
       TYPE(txios(calendar_wrapper)) :: calendar_wrapper
 
@@ -38,4 +46,22 @@
          CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, timestep=timestep)
       END IF
+      IF (PRESENT(day_length)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, day_length=day_length)
+      END IF
+      IF (PRESENT(month_lengths)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, month_lengths=month_lengths)
+      END IF
+      IF (PRESENT(year_length)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, year_length=year_length)
+      END IF
+      IF (PRESENT(leap_year_month)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_month=leap_year_month)
+      END IF
+      IF (PRESENT(leap_year_drift)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_drift=leap_year_drift)
+      END IF
+      IF (PRESENT(leap_year_drift_offset)) THEN
+         CALL xios(set_calendar_wrapper_attr_hdl)(calendar_wrapper, leap_year_drift_offset=leap_year_drift_offset)
+      END IF
 
       CALL xios(create_calendar)(calendar_wrapper)
Index: /XIOS/trunk/src/interface/fortran_attr/calendar_wrapper_interface_attr.F90
===================================================================
--- /XIOS/trunk/src/interface/fortran_attr/calendar_wrapper_interface_attr.F90	(revision 549)
+++ /XIOS/trunk/src/interface/fortran_attr/calendar_wrapper_interface_attr.F90	(revision 550)
@@ -10,4 +10,101 @@
     
     
+    SUBROUTINE cxios_set_calendar_wrapper_day_length(calendar_wrapper_hdl, day_length) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)      , VALUE :: day_length
+    END SUBROUTINE cxios_set_calendar_wrapper_day_length
+    
+    SUBROUTINE cxios_get_calendar_wrapper_day_length(calendar_wrapper_hdl, day_length) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)             :: day_length
+    END SUBROUTINE cxios_get_calendar_wrapper_day_length
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_day_length
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_day_length
+    
+    
+    SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl, leap_year_drift) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      REAL (KIND=C_DOUBLE)      , VALUE :: leap_year_drift
+    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift
+    
+    SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl, leap_year_drift) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      REAL (KIND=C_DOUBLE)             :: leap_year_drift
+    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_drift
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift
+    
+    
+    SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl, leap_year_drift_offset) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      REAL (KIND=C_DOUBLE)      , VALUE :: leap_year_drift_offset
+    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_drift_offset
+    
+    SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl, leap_year_drift_offset) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      REAL (KIND=C_DOUBLE)             :: leap_year_drift_offset
+    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_drift_offset
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_drift_offset
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_drift_offset
+    
+    
+    SUBROUTINE cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_hdl, leap_year_month) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)      , VALUE :: leap_year_month
+    END SUBROUTINE cxios_set_calendar_wrapper_leap_year_month
+    
+    SUBROUTINE cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_hdl, leap_year_month) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)             :: leap_year_month
+    END SUBROUTINE cxios_get_calendar_wrapper_leap_year_month
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_leap_year_month
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_leap_year_month
+    
+    
+    SUBROUTINE cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_hdl, month_lengths, extent1) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE       :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)     , DIMENSION(*) :: month_lengths
+      INTEGER (kind = C_INT), VALUE  :: extent1
+    END SUBROUTINE cxios_set_calendar_wrapper_month_lengths
+    
+    SUBROUTINE cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_hdl, month_lengths, extent1) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE       :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)     , DIMENSION(*) :: month_lengths
+      INTEGER (kind = C_INT), VALUE  :: extent1
+    END SUBROUTINE cxios_get_calendar_wrapper_month_lengths
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_month_lengths
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_month_lengths
+    
+    
     SUBROUTINE cxios_set_calendar_wrapper_start_date(calendar_wrapper_hdl, start_date, start_date_size) BIND(C)
       USE ISO_C_BINDING
@@ -94,4 +191,23 @@
     
     
+    SUBROUTINE cxios_set_calendar_wrapper_year_length(calendar_wrapper_hdl, year_length) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)      , VALUE :: year_length
+    END SUBROUTINE cxios_set_calendar_wrapper_year_length
+    
+    SUBROUTINE cxios_get_calendar_wrapper_year_length(calendar_wrapper_hdl, year_length) BIND(C)
+      USE ISO_C_BINDING
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+      INTEGER (KIND=C_INT)             :: year_length
+    END SUBROUTINE cxios_get_calendar_wrapper_year_length
+    
+    FUNCTION cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_hdl ) BIND(C)
+      USE ISO_C_BINDING
+      LOGICAL(kind=C_BOOL) :: cxios_is_defined_calendar_wrapper_year_length
+      INTEGER (kind = C_INTPTR_T), VALUE :: calendar_wrapper_hdl
+    END FUNCTION cxios_is_defined_calendar_wrapper_year_length
+    
+    
     END INTERFACE
   
Index: /XIOS/trunk/src/interface/fortran_attr/icalendar_wrapper_attr.F90
===================================================================
--- /XIOS/trunk/src/interface/fortran_attr/icalendar_wrapper_attr.F90	(revision 549)
+++ /XIOS/trunk/src/interface/fortran_attr/icalendar_wrapper_attr.F90	(revision 550)
@@ -12,44 +12,87 @@
   
   SUBROUTINE xios(set_calendar_wrapper_attr)  &
-    ( calendar_wrapper_id, start_date, time_origin, timestep, type )
+    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
     
     IMPLICIT NONE
       TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl
       CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id
+      INTEGER  , OPTIONAL, INTENT(IN) :: day_length
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset
+      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month
+      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin
       TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type
+      INTEGER  , OPTIONAL, INTENT(IN) :: year_length
       
       CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl)
       CALL xios(set_calendar_wrapper_attr_hdl_)   &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(set_calendar_wrapper_attr)
   
   SUBROUTINE xios(set_calendar_wrapper_attr_hdl)  &
-    ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      INTEGER  , OPTIONAL, INTENT(IN) :: day_length
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset
+      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month
+      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin
       TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type
+      INTEGER  , OPTIONAL, INTENT(IN) :: year_length
       
       CALL xios(set_calendar_wrapper_attr_hdl_)  &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(set_calendar_wrapper_attr_hdl)
   
   SUBROUTINE xios(set_calendar_wrapper_attr_hdl_)   &
-    ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  &
+    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      INTEGER  , OPTIONAL, INTENT(IN) :: day_length_
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_
+      REAL (KIND=8) , OPTIONAL, INTENT(IN) :: leap_year_drift_offset_
+      INTEGER  , OPTIONAL, INTENT(IN) :: leap_year_month_
+      INTEGER  , OPTIONAL, INTENT(IN) :: month_lengths_(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date_
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin_
       TYPE(txios(duration))  , OPTIONAL, INTENT(IN) :: timestep_
       CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_
+      INTEGER  , OPTIONAL, INTENT(IN) :: year_length_
+      
+      IF (PRESENT(day_length_)) THEN
+        CALL cxios_set_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr, day_length_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_)) THEN
+        CALL cxios_set_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr, leap_year_drift_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_offset_)) THEN
+        CALL cxios_set_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr, leap_year_drift_offset_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_month_)) THEN
+        CALL cxios_set_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr, leap_year_month_)
+      ENDIF
+      
+      IF (PRESENT(month_lengths_)) THEN
+        CALL cxios_set_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr, month_lengths_,size(month_lengths_,1))
+      ENDIF
       
       IF (PRESENT(start_date_)) THEN
@@ -69,4 +112,8 @@
       ENDIF
       
+      IF (PRESENT(year_length_)) THEN
+        CALL cxios_set_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr, year_length_)
+      ENDIF
+      
       
     
@@ -74,44 +121,87 @@
   
   SUBROUTINE xios(get_calendar_wrapper_attr)  &
-    ( calendar_wrapper_id, start_date, time_origin, timestep, type )
+    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
     
     IMPLICIT NONE
       TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl
       CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id
+      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset
+      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month
+      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin
       TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type
+      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length
       
       CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl)
       CALL xios(get_calendar_wrapper_attr_hdl_)   &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(get_calendar_wrapper_attr)
   
   SUBROUTINE xios(get_calendar_wrapper_attr_hdl)  &
-    ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset
+      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month
+      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin
       TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type
+      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length
       
       CALL xios(get_calendar_wrapper_attr_hdl_)  &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(get_calendar_wrapper_attr_hdl)
   
   SUBROUTINE xios(get_calendar_wrapper_attr_hdl_)   &
-    ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  &
+    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      INTEGER  , OPTIONAL, INTENT(OUT) :: day_length_
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_
+      REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: leap_year_drift_offset_
+      INTEGER  , OPTIONAL, INTENT(OUT) :: leap_year_month_
+      INTEGER  , OPTIONAL, INTENT(OUT) :: month_lengths_(:)
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date_
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin_
       TYPE(txios(duration))  , OPTIONAL, INTENT(OUT) :: timestep_
       CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_
+      INTEGER  , OPTIONAL, INTENT(OUT) :: year_length_
+      
+      IF (PRESENT(day_length_)) THEN
+        CALL cxios_get_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr, day_length_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_)) THEN
+        CALL cxios_get_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr, leap_year_drift_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_offset_)) THEN
+        CALL cxios_get_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr, leap_year_drift_offset_)
+      ENDIF
+      
+      IF (PRESENT(leap_year_month_)) THEN
+        CALL cxios_get_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr, leap_year_month_)
+      ENDIF
+      
+      IF (PRESENT(month_lengths_)) THEN
+        CALL cxios_get_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr, month_lengths_,size(month_lengths_,1))
+      ENDIF
       
       IF (PRESENT(start_date_)) THEN
@@ -131,4 +221,8 @@
       ENDIF
       
+      IF (PRESENT(year_length_)) THEN
+        CALL cxios_get_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr, year_length_)
+      ENDIF
+      
       
     
@@ -136,9 +230,20 @@
   
   SUBROUTINE xios(is_defined_calendar_wrapper_attr)  &
-    ( calendar_wrapper_id, start_date, time_origin, timestep, type )
+    ( calendar_wrapper_id, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
     
     IMPLICIT NONE
       TYPE(txios(calendar_wrapper))  :: calendar_wrapper_hdl
       CHARACTER(LEN=*), INTENT(IN) ::calendar_wrapper_id
+      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length
+      LOGICAL(KIND=C_BOOL) :: day_length_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month
+      LOGICAL(KIND=C_BOOL) :: leap_year_month_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths
+      LOGICAL(KIND=C_BOOL) :: month_lengths_tmp
       LOGICAL, OPTIONAL, INTENT(OUT) :: start_date
       LOGICAL(KIND=C_BOOL) :: start_date_tmp
@@ -149,16 +254,30 @@
       LOGICAL, OPTIONAL, INTENT(OUT) :: type
       LOGICAL(KIND=C_BOOL) :: type_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length
+      LOGICAL(KIND=C_BOOL) :: year_length_tmp
       
       CALL xios(get_calendar_wrapper_handle)(calendar_wrapper_id,calendar_wrapper_hdl)
       CALL xios(is_defined_calendar_wrapper_attr_hdl_)   &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(is_defined_calendar_wrapper_attr)
   
   SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl)  &
-    ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+    , month_lengths, start_date, time_origin, timestep, type, year_length )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length
+      LOGICAL(KIND=C_BOOL) :: day_length_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month
+      LOGICAL(KIND=C_BOOL) :: leap_year_month_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths
+      LOGICAL(KIND=C_BOOL) :: month_lengths_tmp
       LOGICAL, OPTIONAL, INTENT(OUT) :: start_date
       LOGICAL(KIND=C_BOOL) :: start_date_tmp
@@ -169,15 +288,29 @@
       LOGICAL, OPTIONAL, INTENT(OUT) :: type
       LOGICAL(KIND=C_BOOL) :: type_tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length
+      LOGICAL(KIND=C_BOOL) :: year_length_tmp
       
       CALL xios(is_defined_calendar_wrapper_attr_hdl_)  &
-      ( calendar_wrapper_hdl, start_date, time_origin, timestep, type )
+      ( calendar_wrapper_hdl, day_length, leap_year_drift, leap_year_drift_offset, leap_year_month  &
+      , month_lengths, start_date, time_origin, timestep, type, year_length )
     
   END SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl)
   
   SUBROUTINE xios(is_defined_calendar_wrapper_attr_hdl_)   &
-    ( calendar_wrapper_hdl, start_date_, time_origin_, timestep_, type_ )
-    
-    IMPLICIT NONE
-      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+    ( calendar_wrapper_hdl, day_length_, leap_year_drift_, leap_year_drift_offset_, leap_year_month_  &
+    , month_lengths_, start_date_, time_origin_, timestep_, type_, year_length_ )
+    
+    IMPLICIT NONE
+      TYPE(txios(calendar_wrapper)) , INTENT(IN) :: calendar_wrapper_hdl
+      LOGICAL, OPTIONAL, INTENT(OUT) :: day_length_
+      LOGICAL(KIND=C_BOOL) :: day_length__tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift__tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_drift_offset_
+      LOGICAL(KIND=C_BOOL) :: leap_year_drift_offset__tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: leap_year_month_
+      LOGICAL(KIND=C_BOOL) :: leap_year_month__tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: month_lengths_
+      LOGICAL(KIND=C_BOOL) :: month_lengths__tmp
       LOGICAL, OPTIONAL, INTENT(OUT) :: start_date_
       LOGICAL(KIND=C_BOOL) :: start_date__tmp
@@ -188,4 +321,31 @@
       LOGICAL, OPTIONAL, INTENT(OUT) :: type_
       LOGICAL(KIND=C_BOOL) :: type__tmp
+      LOGICAL, OPTIONAL, INTENT(OUT) :: year_length_
+      LOGICAL(KIND=C_BOOL) :: year_length__tmp
+      
+      IF (PRESENT(day_length_)) THEN
+        day_length__tmp=cxios_is_defined_calendar_wrapper_day_length(calendar_wrapper_hdl%daddr)
+        day_length_=day_length__tmp
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_)) THEN
+        leap_year_drift__tmp=cxios_is_defined_calendar_wrapper_leap_year_drift(calendar_wrapper_hdl%daddr)
+        leap_year_drift_=leap_year_drift__tmp
+      ENDIF
+      
+      IF (PRESENT(leap_year_drift_offset_)) THEN
+        leap_year_drift_offset__tmp=cxios_is_defined_calendar_wrapper_leap_year_drift_offset(calendar_wrapper_hdl%daddr)
+        leap_year_drift_offset_=leap_year_drift_offset__tmp
+      ENDIF
+      
+      IF (PRESENT(leap_year_month_)) THEN
+        leap_year_month__tmp=cxios_is_defined_calendar_wrapper_leap_year_month(calendar_wrapper_hdl%daddr)
+        leap_year_month_=leap_year_month__tmp
+      ENDIF
+      
+      IF (PRESENT(month_lengths_)) THEN
+        month_lengths__tmp=cxios_is_defined_calendar_wrapper_month_lengths(calendar_wrapper_hdl%daddr)
+        month_lengths_=month_lengths__tmp
+      ENDIF
       
       IF (PRESENT(start_date_)) THEN
@@ -209,4 +369,9 @@
       ENDIF
       
+      IF (PRESENT(year_length_)) THEN
+        year_length__tmp=cxios_is_defined_calendar_wrapper_year_length(calendar_wrapper_hdl%daddr)
+        year_length_=year_length__tmp
+      ENDIF
+      
       
     
Index: /XIOS/trunk/src/node/calendar_wrapper.cpp
===================================================================
--- /XIOS/trunk/src/node/calendar_wrapper.cpp	(revision 549)
+++ /XIOS/trunk/src/node/calendar_wrapper.cpp	(revision 550)
@@ -95,7 +95,50 @@
 #include "calendar_type.conf"
 #undef DECLARE_CALENDAR
+      // Special case for the user defined calendar
+      if (type.getValue() == type_attr::user_defined)
+      {
+        if (day_length.isEmpty())
+          ERROR("CCalendarWrapper::createCalendar(void)",
+                << "The day length must be configured when using an user defined calendar.");
+        if (month_lengths.isEmpty() == year_length.isEmpty())
+          ERROR("CCalendarWrapper::createCalendar(void)",
+                << "Either the month lengths or the year length must be configured when using an user defined calendar.");
+        if (leap_year_drift.isEmpty() != leap_year_month.isEmpty())
+          ERROR("CCalendarWrapper::createCalendar(void)",
+                << "Both leap_year_drift and leap_year_month attributes must be set if you wish to configure leap years.");
+        if (leap_year_drift.isEmpty() && !leap_year_drift_offset.isEmpty())
+          ERROR("CCalendarWrapper::createCalendar(void)",
+                << "Both leap_year_drift and leap_year_month attributes are mandatory if you wish to use leap_year_drift_offset attribute.");
+
+        boost::shared_ptr<CUserDefinedCalendar> userDefinedCalendar;
+        if (year_length.isEmpty())
+          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), month_lengths.getValue()));
+        else
+          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), year_length.getValue()));
+
+        if (!leap_year_month.isEmpty())
+          userDefinedCalendar->configureLeapYear(leap_year_month.getValue(),
+                                                 leap_year_drift.getValue(),
+                                                 leap_year_drift_offset.isEmpty() ? 0.0 : leap_year_drift_offset.getValue());
+
+        calendar = userDefinedCalendar;
+      }
+      else
+      {
+#define CHECK_EMPTY(attr)                                                                       \
+        if (!attr.isEmpty())                                                                    \
+          ERROR("CCalendarWrapper::createCalendar(void)",                                       \
+                << "The attribute \"" #attr "\" can only be used with user defined calendar.");
+        CHECK_EMPTY(day_length)
+        CHECK_EMPTY(month_lengths)
+        CHECK_EMPTY(year_length)
+        CHECK_EMPTY(leap_year_month)
+        CHECK_EMPTY(leap_year_drift)
+        CHECK_EMPTY(leap_year_drift_offset)
+#undef CHECK_EMPTY
+      }
 
       if (!calendar)
-        ERROR("CCalendarWrapper::parse(xml::CXMLNode& node)",
+        ERROR("CCalendarWrapper::createCalendar(void)",
               << "[ type = " << type.getStringValue() << " ] "
               << "The calendar is not properly handled!");
@@ -121,5 +164,5 @@
     else if (!start_date.isEmpty() || !time_origin.isEmpty())
     {
-      ERROR("CCalendarWrapper::parse(xml::CXMLNode& node)",
+      ERROR("CCalendarWrapper::createCalendar(void)",
             << "The calendar type must be set before defining the start date or the time origin!");
     }
Index: /XIOS/trunk/src/node/calendar_wrapper.hpp
===================================================================
--- /XIOS/trunk/src/node/calendar_wrapper.hpp	(revision 549)
+++ /XIOS/trunk/src/node/calendar_wrapper.hpp	(revision 550)
@@ -6,4 +6,5 @@
 #include "attribute_enum.hpp"
 #include "attribute_enum_impl.hpp"
+#include "attribute_array.hpp"
 #include "declare_attribute.hpp"
 #include "object_template.hpp"
Index: /XIOS/trunk/src/node/context.cpp
===================================================================
--- /XIOS/trunk/src/node/context.cpp	(revision 549)
+++ /XIOS/trunk/src/node/context.cpp	(revision 550)
@@ -700,4 +700,6 @@
       else if (calendar->getTimeStep() == NoneDu)
         ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"")
+      // Calendar first update to set the current date equals to the start date
+      calendar->update(0);
 
       // Find all inheritance in xml structure
Index: /XIOS/trunk/src/test/test_client.f90
===================================================================
--- /XIOS/trunk/src/test/test_client.f90	(revision 549)
+++ /XIOS/trunk/src/test/test_client.f90	(revision 550)
@@ -13,5 +13,5 @@
   TYPE(xios_duration) :: dtime
   TYPE(xios_date) :: date
-  CHARACTER(len=10) :: calendar_type
+  CHARACTER(len=15) :: calendar_type
   TYPE(xios_context) :: ctx_hdl
   INTEGER,PARAMETER :: ni_glo=100
