Index: trunk/tools/generic_tools.py
===================================================================
--- trunk/tools/generic_tools.py	(revision 2419)
+++ trunk/tools/generic_tools.py	(revision 2421)
@@ -106,4 +106,5 @@
 # DateTimeStr_date: Function to transform a string date-time ([YYYY][MM][DD][HH][MI][SS] format) to a date object
 # datetimeStr_datetime: Function to transform a string date-time ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object
+# days_month: Function to give the number of days of a month of a given year
 # DegMinSec_angle: Function to transform Degrees Minutes Seconds to an angle
 # dictionary_key: Function to provide the first key in a dictionay with a given value
@@ -490,4 +491,20 @@
     return combos
 
+def days_month(year,month):
+    """ Function to give the number of days of a month of a given year
+    >>> days_month(1976,2)
+    29
+    """
+    import datetime as dt
+
+    date1=dt.date(year,month,1)
+    if month+1 > 12:
+        date2=dt.date(year+1,1,1)
+    else:
+        date2=dt.date(year,month+1,1)
+
+    diffdate = date2-date1
+    return diffdate.days
+
 def datetimeStr_datetime(StringDT):
     """ Function to transform a string date ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object
@@ -529,4 +546,10 @@
       [typeSi/o]
         'cfTime',[units]: time in CF-convention format [units] = [tunits] since [refdate]
+        'cfTimeCal',[units],[calendar]: time in CF-convention format 
+           [units] = [tunits] since [refdate] taking into account the [calendar]
+            attribute (available values: 
+              * leap years: 'leap', '365d', 'gregorian', 'Gregorian', 'standard', 
+                'Standard'
+              * no-leap years: 'noleap', '360d'
         'matYmdHMS': numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]]
         'YmdHMS': [YYYY][MM][DD][HH][MI][SS] format
@@ -551,4 +574,6 @@
     availableSio = {'cfTime,[units]': 'time in CF-convention format [units] = ' +    \
         '[tunits] since [refdate]',                                                  \
+        'cfTimeCal,[units],[calendar]': 'time in CF-convention format [units] = ' +  \
+        '[tunits] since [refdate] & [calendar]',                                     \
         'matYmdHMS': 'numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]]', \
         'YmdHMS': '[YYYY][MM][DD][HH][MI][SS] format',                               \
@@ -562,4 +587,6 @@
 
     availcftimeu = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']
+    availcalendar = ['leap', '366d', 'gregorian', 'Gregorian', 'standard',           \
+      'Standard', 'noleap', '365d', '360d']
 
     if StringDT[0:1] == 'h':
@@ -607,4 +634,77 @@
             newdate = refdate + dt.timedelta(seconds=float(timeval))
         elif tunits == 'milliseconds':
+            newdate = refdate + dt.timedelta(milliseconds=float(timeval))
+        else:
+              print errormsg
+              print '  ' + fname + ': time units"' + tunits + '" not ready!!!!'
+              print '    available ones:', availcftimeu
+              quit(-1)
+
+        yr = newdate.year
+        mo = newdate.month
+        da = newdate.day
+        ho = newdate.hour
+        mi = newdate.minute
+        se = newdate.second
+    elif typeSi[0:6] == 'cfTimeCal':
+        timeval = np.float(StringDT)
+        tunits = typeSi.split(',')[1].split(' ')[0]
+        Srefdate = typeSi.split(',')[1].split(' ')[2]
+        calendar = typeSi.split(',')[2]
+
+        if not gen.searchInlist(availcalendar , calendar):
+            print errormsg
+            print '  ' + fname + ": calendar '" + + "' not ready !!"
+            print '    avaialable ones:', availcalendar
+            quit(-1)
+
+# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
+##
+        yrref=Srefdate[0:4]
+        monref=Srefdate[5:7]
+        dayref=Srefdate[8:10]
+
+        trefT = typeSi.split(',')[1].find(':')
+        if not trefT == -1:
+            if len(typeSi.split(',')[1].split(' ')) == 3:
+                horref=Srefdate[11:13]
+                minref=Srefdate[14:16]
+                secref=Srefdate[17:19]
+            else:
+                Sreftime = typeSi.split(',')[1].split(' ')[3]
+                horref=Sreftime[0:2]
+                minref=Sreftime[3:5]
+                secref=Sreftime[6:8]                
+            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
+              '_' + horref + ':' + minref + ':' + secref)
+        else:
+            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
+              '_00:00:00')
+
+        if calendar == 'noleap' or calendar == '365d':
+            removeleap = False
+            newdate = refdate + dt.timedelta(weeks=float(timeval))
+            if days_month(newdate.year,2) == 29:
+                if newdate.mon == 2 and newdate.day == 28:
+                    removeleap = True
+                elif newdate.mon > 2: removeleap = True
+
+        if tunits == 'weeks':
+            if removeleap: timeval = timeval - 1./7.
+            newdate = refdate + dt.timedelta(weeks=float(timeval))
+        elif tunits == 'days':
+            if removeleap: timeval = timeval - 1.
+            newdate = refdate + dt.timedelta(days=float(timeval))
+        elif tunits == 'hours':
+            if removeleap: timeval = timeval - 1.*24.
+            newdate = refdate + dt.timedelta(hours=float(timeval))
+        elif tunits == 'minutes':
+            if removeleap: timeval = timeval - 1.*24.*60.
+            newdate = refdate + dt.timedelta(minutes=float(timeval))
+        elif tunits == 'seconds':
+            if removeleap: timeval = timeval - 1.*24.*3600.
+            newdate = refdate + dt.timedelta(seconds=float(timeval))
+        elif tunits == 'milliseconds':
+            if removeleap: timeval = timeval - 1.*24.*3600.*1000.
             newdate = refdate + dt.timedelta(milliseconds=float(timeval))
         else:
@@ -737,4 +837,74 @@
         else:
             totsecs = difft.days()*24*3600. + difft.seconds()
+
+        if tunits == 'weeks':
+            cfdt = totsecs / (7*24*3600)
+        elif tunits == 'days':
+            cfdt = totsecs / (24*3600)
+        elif tunits == 'hours':
+            cfdt = totsecs / (3600)
+        elif tunits == 'minutes':
+            cfdt = totsecs / (60)
+        elif tunits == 'seconds':
+            cfdt = totsecs
+        elif tunits == 'milliseconds':
+            cfdt = totsecs*100.
+        else:
+              print errormsg
+              print '  ' + fname + ': time units"' + tunits + '" not ready!!!!'
+              print '    available ones:', availcftimeu
+              quit(-1)
+        dateYmdHMS = cfdt
+        
+    elif typeSo[0:6] == 'cfTimeCal':
+        tunits = typeSo.split(',')[1].split(' ')[0]
+        Srefdate = typeSo.split(',')[1].split(' ')[2]
+        calendar = typeSo.split(',')[2]
+
+        if not gen.searchInlist(availcalendar , calendar):
+            print errormsg
+            print '  ' + fname + ": calendar '" + + "' not ready !!"
+            print '    avaialable ones:', availcalendar
+            quit(-1)
+
+# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
+##
+        yrref=Srefdate[0:4]
+        monref=Srefdate[5:7]
+        dayref=Srefdate[8:10]
+
+        trefT = typeSo.split(',')[1].find(':')
+        if not trefT == -1:
+#            print '  ' + fname + ': refdate with time!'
+            if len(typeSo.split(',')[1].split(' ')) == 3:
+                horref=Srefdate[11:13]
+                minref=Srefdate[14:16]
+                secref=Srefdate[17:19]
+            else:
+                Sreftime = typeSo.split(',')[1].split(' ')[3]
+                horref=Sreftime[0:2]
+                minref=Sreftime[3:5]
+                secref=Sreftime[6:8]                
+
+            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
+              '_' + horref + ':' + minref + ':' + secref)
+        else:
+            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
+              '_00:00:00')
+        datei = dt.datetime(yr, mo, da, ho, mi, se)
+        difft = datei - refdate
+
+        if searchInlist(dir(difft),'total_seconds'):
+            totsecs = difft.total_seconds()
+        else:
+            totsecs = difft.days()*24*3600. + difft.seconds()
+
+        if calendar == 'noleap' or calendar == '365d':
+            removeleap = False
+            if days_month(newdate.year,2) == 29:
+                if datei.mon == 2 and datei.day == 28:
+                    totsecs = totsecs - 24.*3600.
+                if datei.mon > 2:
+                    totsecs = totsecs - 24.*3600.
 
         if tunits == 'weeks':
@@ -5215,20 +5385,4 @@
     return diffunits
 
-def days_month(year,month):
-    """ Function to give the number of days of a month of a given year
-    >>> days_month(1976,2)
-    29
-    """
-    import datetime as dt
-
-    date1=dt.date(year,month,1)
-    if month+1 > 12:
-        date2=dt.date(year+1,1,1)
-    else:
-        date2=dt.date(year,month+1,1)
-
-    diffdate = date2-date1
-    return diffdate.days
-
 def mid_period(yr1,mon1,day1,hour1,min1,sec1,yr2,mon2,day2,hour2,min2,sec2):
     """ Function to give the mid poiint of a period
