source: trunk/libIGCM/libIGCM_date/libIGCM_date.ksh @ 148

Last change on this file since 148 was 148, checked in by sdipsl, 15 years ago
  • Typo correction
  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

    The fact that you are presently reading this means that you have had
    knowledge of the CeCILL license and that you accept its terms.
  • Property svn:keywords set to Date Author Revision
File size: 22.8 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Sebastien Denvil
5# Contact: Sebastien.Denvil@ipsl.jussieu.fr
6# $Date$
7# $Author$
8# $Revision$
9# IPSL (2006)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11# History:
12# Modification:
13#
14#**************************************************************
15
16#==================================================
17# The documentation of this file can be automatically generated
18# if you use the prefix #D- for comments to be extracted.
19# Extract with command: cat lib* | grep "^#D-" | cut -c "4-"
20#==================================================
21
22#D-#==================================================================
23#D-libIGCM_date
24#D-This ksh library handles date calculs and convertions in different calendars.
25#D-  types of calendars are possible :
26#D-
27#D-  - gregorian (other name leap) :
28#D-      The normal calendar. The time origin for the
29#D-      julian day in this case is 24 Nov -4713.
30#D-  - noleap :
31#D-      A 365 day year without leap years.
32#D-  - all_leap :
33#D-      A 366 day year with only leap years.
34#D-  - 360d :
35#D-      Year of 360 days with month of equal length.
36
37# Number of digit in the year
38typeset -r dY=${dY:=4}
39#typeset -r MaxpY=$( echo "10^"$((dY+1)) | bc -l )
40# Number of digit in non-human date representation
41typeset -r pY=$(( dY+4 ))
42
43#==================================================================
44function IGCM_date_YearDigit
45{
46    IGCM_debug_PushStack "IGCM_date_YearDigit" $@
47
48    NUM=$(( 10#${1} ))
49    echo $( gawk "BEGIN { printf \"%0${dY}d\",${NUM} }" )
50
51    IGCM_debug_PopStack "IGCM_date_YearDigit"
52}
53
54#==================================================================
55function IGCM_date_GregorianDigit
56{
57    IGCM_debug_PushStack "IGCM_date_GregorianDigit" $@
58
59    NUM=$(( 10#${1} ))
60    echo $( gawk "BEGIN { printf \"%0${pY}d\",${NUM} }" )
61
62    IGCM_debug_PopStack "IGCM_date_GregorianDigit"
63}
64
65#==================================================================
66function IGCM_date_HumanDigit
67{
68    IGCM_debug_PushStack "IGCM_date_HumanDigit" $@
69
70    echo $( IGCM_date_GregorianDigit $( print ${1} | sed 's/-//g' ) ) \
71        | sed -e "s/\([0-9]\{${dY}\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1-\2-\3/"
72
73    IGCM_debug_PopStack "IGCM_date_HumanDigit"
74}
75
76#==================================================================
77function IGCM_date_ConvertFormatToGregorian
78{
79    IGCM_debug_PushStack "IGCM_date_ConvertFormatToGregorian" $@
80
81    # from a yyyy-mm-dd date format return
82    # a yyymmdd date format
83    # usage IGCM_date_ConvertFormat yyyy-mm-dd
84
85    # if there is no argument on the command line,
86    # then assume that a y-m-d formated date is being
87    # piped in
88    typeset ymd
89    if [ $# = 0 ]
90        then
91        read ymd
92    else
93        ymd=$1
94    fi
95
96    IGCM_date_GregorianDigit $( print ${ymd} | sed 's/-//g' )
97
98    IGCM_debug_PopStack "IGCM_date_ConvertFormatToGregorian"
99}
100
101#==================================================================
102function IGCM_date_ConvertFormatToHuman
103{
104    IGCM_debug_PushStack "IGCM_date_ConvertFormatToHuman" $@
105
106    # from a yyyymmdd date format return
107    # a yyyy-mm-dd date format
108    # usage IGCM_date_ConvertFormat yyyymmdd
109
110    # if there is no argument on the command line,
111    # then assume that a yyyymmdd formated date is being
112    # piped in
113    typeset dt
114    if [ $# = 0 ]
115        then
116        read dt
117    else
118        dt=$1
119    fi
120
121    # break the yyyymmdd into separate parts for year, month and day
122    echo $( IGCM_date_GregorianDigit ${dt} ) \
123        | sed -e "s/\([0-9]\{${dY}\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1-\2-\3/"
124
125    IGCM_debug_PopStack "IGCM_date_ConvertFormatToHuman"
126}
127
128#==================================================================
129function IGCM_date_GetYearMonth
130{
131    IGCM_debug_PushStack "IGCM_date_GetYearMonth" $@
132
133    # from a yyyymmdd date format return
134    # a yyyy year and mm month
135    # usage IGCM_date_GetYearMonth yyyymmdd year_var month_var
136
137    # if there is no argument on the command line,
138    # then assume that a yyyymmdd formated date is being
139    # piped in
140    typeset dt
141    if [ $# = 0 ]
142        then
143        read dt
144    else
145        dt=$1
146    fi
147
148    # break the yyyymmdd into separate parts for year, month and day
149    eval $2=$( echo $( IGCM_date_GregorianDigit ${dt} ) \
150        | sed -e "s/\([0-9]\{${dY}\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1/" )
151    eval $3=$( echo $( IGCM_date_GregorianDigit ${dt} ) \
152        | sed -e "s/\([0-9]\{${dY}\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\2/" )
153
154    IGCM_debug_PopStack "IGCM_date_GetYearMonth"
155}
156
157#D-#==================================================================
158#D-function IGCM_date_DaysInYear
159#D-* Purpose: Return the number of days in a year
160#D-* Usage: IGCM_date_DaysInYear yyyy
161#D-         if there is no argument on the command line,
162#D-         then assume that a yyyy is being piped in
163#D-
164function IGCM_date_DaysInYear
165{
166#    IGCM_debug_PushStack "IGCM_date_DaysInYear" $@
167    # return the number of days in a year
168    # usage IGCM_date_DaysInYear yyyy
169
170    # What is the calendar :
171    case ${config_UserChoices_CalendarType} in
172        360d)
173            if [ X$2 = X ] ; then
174                echo 360
175            else
176                eval $2=360 > /dev/null 2>&1
177            fi
178#       IGCM_debug_PopStack "IGCM_date_DaysInYear"
179            return;;
180        noleap)
181            if [ X$2 = X ] ; then
182                echo 365
183            else
184                eval $2=365 > /dev/null 2>&1
185            fi
186
187#           IGCM_debug_PopStack "IGCM_date_DaysInYear"
188            return;;
189        all_leap)
190            if [ X$2 = X ] ; then
191                echo 366
192            else
193                eval $2=366 > /dev/null 2>&1
194            fi
195
196#               IGCM_debug_PopStack "IGCM_date_DaysInYear"
197            return;;
198    esac
199
200    typeset y a
201
202    # if there is no argument on the command line,
203    # then assume that a yyyy is being piped in
204    if [ $# = 0 ]
205        then
206        read y
207    else
208        y=$(( 10#${1} ))
209    fi
210
211    # a year is a leap year if it is even divisible by 4
212    # but not evenly divisible by 100
213    # unless it is evenly divisible by 400
214
215    # if it is evenly divisible by 400 it must be a leap year
216    a=$(( $y % 400 ))
217    if [ $a = 0 ]
218        then
219        if [ X$2 = X ] ; then
220            echo 366
221        else
222            eval $2=366 > /dev/null 2>&1
223        fi
224
225#       IGCM_debug_PopStack "IGCM_date_DaysInYear"
226        return
227    fi
228
229    #if it is evenly divisible by 100 it must not be a leap year
230    a=$(( $y % 100 ))
231    if [ $a = 0 ]
232        then
233        if [ X$2 = X ] ; then
234            echo 365
235        else
236            eval $2=365 > /dev/null 2>&1
237        fi
238
239#       IGCM_debug_PopStack "IGCM_date_DaysInYear"
240        return
241    fi
242       
243    # if it is evenly divisible by 4 it must be a leap year
244    a=$(( $y % 4 ))
245    if [ $a = 0 ]
246        then
247        if [ X$2 = X ] ; then
248            echo 366
249        else
250            eval $2=366 > /dev/null 2>&1
251        fi
252
253#       IGCM_debug_PopStack "IGCM_date_DaysInYear"
254        return
255    fi
256
257    # otherwise it is not a leap year
258    if [ X$2 = X ] ; then
259        echo 365
260    else
261        eval $2=365 > /dev/null 2>&1
262    fi
263
264#    IGCM_debug_PopStack "IGCM_date_DaysInYear"
265}
266
267#D-#==================================================================
268#D-function IGCM_date_DaysInMonth
269#D-* Purpose: Calculate the number of days in a month
270#D-* Usage: IGCM_date_DaysInMonth yyyy mm
271#D-         or IGCM_date_DaysInMonth yyyymmdd
272#D-         if there are no command line arguments then
273#D-         assume that a yyyymmdd is being piped in and read the value.
274#D-         if there is only one argument assume it is a yyyymmdd on the command line
275#D-         other wise it is a yyyy and mm on the command line
276function IGCM_date_DaysInMonth
277{
278#    IGCM_debug_PushStack "IGCM_date_DaysInMonth" $@
279
280    # calculates the number of days in a month
281    # usage IGCM_date_DaysInMonth yyyy mm
282    # or IGCM_date_DaysInMonth yyyymmdd
283   
284    # What is the calendar :
285    if [ "${config_UserChoices_CalendarType}" = "360d" ] ; then
286        if [ X$3 = X ] ; then
287            echo 30
288        else
289            eval $3=30 > /dev/null 2>&1
290        fi
291
292#       IGCM_debug_PopStack "IGCM_date_DaysInMonth"
293        return
294    fi
295
296    typeset ymd y m
297
298    # if there are no command line arguments then assume that a yyyymmdd is being
299    # piped in and read the value.
300    # if there is only one argument assume it is a yyyymmdd on the command line
301    # other wise it is a yyyy and mm on the command line
302    if [ $# = 0 ]
303        then
304        read ymd
305    elif [ $# = 1 ] 
306        then
307        ymd=$1
308    else
309        ymd=$(( ( $1 * 10000 ) + ( $2 * 100 ) + 1 ))
310    fi
311
312    # extract the year and the month
313    y=$(( $ymd / 10000 )) ;
314    m=$(( ( $ymd % 10000 ) / 100 )) ;
315
316    # 30 days hath september etc.
317    case $m in
318        1|3|5|7|8|10|12) 
319            if [ X$3 = X ] ; then
320                echo 31
321            else
322                eval $3=31 > /dev/null 2>&1
323            fi
324
325#           IGCM_debug_PopStack "IGCM_date_DaysInMonth"
326            return ;;
327        4|6|9|11) 
328            if [ X$3 = X ] ; then
329                echo 30
330            else
331                eval $3=30 > /dev/null 2>&1
332            fi
333       
334#           IGCM_debug_PopStack "IGCM_date_DaysInMonth"
335            return ;;
336        *) ;;
337    esac
338
339    # except for month 2 which depends on whether the year is a leap year
340    # Use IGCM_date_DaysInYear to get the number of days in the year and return a value
341    # accordingly.
342    IGCM_date_DaysInYear $y diy
343    case $diy in
344        365) 
345            if [ X$3 = X ] ; then
346                echo 28
347            else
348                eval $3=28 > /dev/null 2>&1
349            fi
350
351#           IGCM_debug_PopStack "IGCM_date_DaysInMonth"
352            return ;;
353        366) 
354            if [ X$3 = X ] ; then
355                echo 29
356            else
357                eval $3=29 > /dev/null 2>&1
358            fi
359
360#           IGCM_debug_PopStack "IGCM_date_DaysInMonth"
361            return ;;
362    esac
363
364#    IGCM_debug_PopStack "IGCM_date_DaysInMonth"
365}
366
367#D-#==================================================================
368#D-function IGCM_date_ConvertGregorianDateToJulian
369#D-* Purpose: Convert yyyymmdd to yyyyddd
370#D-* Usage: IGCM_date_ConvertGregorianDateToJulian 19980429
371#D-         if there is no command line argument, then assume that the date
372#D-         is coming in on a pipe and use read to collect it
373#D-
374function IGCM_date_ConvertGregorianDateToJulian
375{
376    IGCM_debug_PushStack "IGCM_date_ConvertGregorianDateToJulian" $@
377
378    # IGCM_date_ConvertGregorianDateToJulian converts yyyymmdd to yyyyddd
379    # usage IGCM_date_ConvertGregorianDateToJulian 19980429
380
381    typeset dt y m d x jul
382
383    # if there is no command line argument, then assume that the date
384    # is coming in on a pipe and use read to collect it   
385    if [ $# = 0 ]
386        then
387        read dt
388    else
389        dt=$1
390    fi
391
392    # break the yyyymmdd into separate parts for year, month and day
393    y=$(( $dt / 10000 ))
394    m=$(( ( $dt % 10000 ) / 100 ))
395    d=$(( ( $dt % 100 ) ))
396
397    # add the days in each month up to (but not including the month itself)
398    # into the days. For example if the date is 19980203 then extract the
399    # number of days in January and add it to 03. If the date is June 14, 1998
400    # then extract the number of days in January, February, March, April and May
401    # and add them to 14.
402    x=1
403    while [ $x -lt $m ]
404      do
405      IGCM_date_DaysInMonth $y $x md
406      d=$(( $d + $md ))
407      x=$(( $x + 1 ))
408    done
409
410    # combine the year and day back together again and you have the julian date.
411    jul=$(( ( $y * 1000 ) + $d ))
412    echo $jul
413
414    IGCM_debug_PopStack "IGCM_date_ConvertGregorianDateToJulian"
415}
416
417#D-#==================================================================
418#D-function IGCM_date_ConvertJulianDateToGregorian()
419#D-* Purpose: Convert yyyyddd to yyyymmdd
420#D-* Usage: IGCM_date_ConvertJulianDateToGregorian 1998213
421#D-         if there is no command line argument, assume one is being
422#D-         piped in and read it
423#D-
424function IGCM_date_ConvertJulianDateToGregorian
425{
426    IGCM_debug_PushStack "IGCM_date_ConvertJulianDateToGregorian" $@
427
428    # IGCM_date_ConvertJulianDateToGregorian converts yyyyddd to yyyymmdd
429    # usage IGCM_date_ConvertJulianDateToGregorian 1998213
430
431    typeset dt y m d grg
432
433    # if there is no command line argument, assume one is being
434    # piped in and read it
435    if [ X$1 = X ]
436        then
437        read dt
438    else
439        dt=$1
440    fi
441       
442    # break apart the year and the days
443    y=$(( $dt / 1000 ))
444    d=$(( $dt % 1000 ))
445       
446    # subtract the number of days in each month starting from 1
447    # from the days in the date. When the day goes below 1, you
448    # have the current month. Add back the number of days in the
449    # month to get the correct day of the month
450    m=1
451    while [ $d -gt 0 ]
452      do
453      IGCM_date_DaysInMonth $y $m md
454      d=$(( $d - $md ))
455      m=$(( $m + 1 ))
456    done
457
458    d=$(( $d + $md ))
459
460    # the loop steps one past the correct month, so back up the month
461    m=$(( $m - 1 ))
462
463    # assemble the results into a gregorian date
464    grg=$(( ( $y * 10000 ) + ( $m * 100 ) + $d ))
465    echo $( IGCM_date_GregorianDigit $grg )
466
467    IGCM_debug_PopStack "IGCM_date_ConvertJulianDateToGregorian"
468}
469
470#D-#==================================================================
471#D-function IGCM_date_AddDaysToJulianDate
472#D-* Purpose: Add days to a yyyyddd formatted date
473#D-* Usage: IGCM_date_AddDaysToJulianDate 1998312 { ,-}14
474#D-         Read the difference from the command lines
475#D-         and the date from the command line, or standard input
476#D-
477function IGCM_date_AddDaysToJulianDate
478{
479    IGCM_debug_PushStack "IGCM_date_AddDaysToJulianDate" $@
480
481    # IGCM_date_AddDaysToJulianDate adds days to a yyyyddd formatted date
482    # usage IGCM_date_AddDaysToJulianDate 1998312 { ,-}14
483
484    typeset dif yd d y
485
486    # Read the difference from the command lines
487    # and the date from the command line, or standard input
488    if [ X$2 = X ]
489        then
490        dif=$1
491        read yd
492    else
493        yd=$1
494        dif=$2
495    fi
496
497    # Break it into pieces
498    d=$(( $yd % 1000 ))
499    y=$(( $yd / 1000 ))
500
501    # Add the number of days (if days is negative this results is
502    # a subtraction)
503    d=$(( $d + $dif ))
504
505    # Extract the days in the year
506    IGCM_date_DaysInYear $y diy
507
508    # If the calculated day exceeds the days in the year,
509    # add one year to the year and subtract the days in the year from the
510    # calculated days. Extract the days in the new year and repeat
511    # test until you end up with a day number that falls within the
512    # days of the year
513    while [ $d -gt $diy ]
514      do
515      d=$(( $d - $diy ))
516      y=$(( $y + 1 ))
517      IGCM_date_DaysInYear $y diy
518    done
519
520    # This is the reverse process. If the calculated number of days
521    # is less than 1, move back one year. Extract
522    # the days in this year and add the days in the year
523    # loop on this test until you end up with a number that
524    # falls within the days of the year
525    while [ $d -lt 1 ]
526      do
527      y=$(( $y - 1 ))
528      IGCM_date_DaysInYear $y diy
529      d=$(( $d + $diy ))
530    done
531
532    # put the year and day back together and echo the result
533    yd=$(( ( $y * 1000 ) + $d ))
534
535    echo $yd
536
537    IGCM_debug_PopStack "IGCM_date_AddDaysToJulianDate"
538}
539
540#D-#==================================================================
541#D-function IGCM_date_AddDaysToGregorianDate
542#D-* Purpose: Add days to a yyyymmdd formatted date
543#D-* Usage: IGCM_date_AddDaysToGregorianDate 19980312 { ,-}14
544#D-         Read the difference from the command lines
545#D-         and the date from the command line, or standard input
546#D-
547function IGCM_date_AddDaysToGregorianDate
548{
549    IGCM_debug_PushStack "IGCM_date_AddDaysToGregorianDate" $@
550
551    # IGCM_date_AddDaysToGregorianDate adds days to a yyyymmdd formatted date
552    # usage IGCM_date_AddDaysToGregorianDate 19980312 { ,-}14
553
554    # Read the difference from the command lines
555    # and the date from the command line, or standard input
556    typeset dif yd tmp res
557    if [ X$2 = X ]
558        then
559        dif=$1
560        read yd
561    else
562        yd=$1
563        dif=$2
564    fi
565
566    tmp=$( IGCM_date_ConvertGregorianDateToJulian $yd )
567    tmp=$( IGCM_date_AddDaysToJulianDate $tmp $dif )
568    res=$( IGCM_date_ConvertJulianDateToGregorian $tmp )
569   
570    echo $res
571
572    IGCM_debug_PopStack "IGCM_date_AddDaysToGregorianDate"
573}
574
575#D-#==================================================================
576#D-function IGCM_date_DaysBetweenJulianDate
577#D-* Purpose: Calculate the days difference between two dates and reports
578#D-           the number days as jul1 - jul2
579#D-* Usage: IGCM_date_DaysBetweenJulianDate jul1 jul2
580#D-         where julian date is in the form yyyyddd
581#D-
582function IGCM_date_DaysBetweenJulianDate
583{
584    IGCM_debug_PushStack "IGCM_date_DaysBetweenJulianDate" $@
585
586    # calculates the days difference between two dates and reports
587    # the number days as jul1 - jul2
588    # usage IGCM_date_DaysBetweenJulianDate jul1 jul2
589    # where julian date is in the form yyyyddd
590   
591    usage () {
592        echo "Usage:"
593        echo " IGCM_date_DaysBetweenJulianDate jul1 jul2"
594        echo ""
595        echo " Calculates the day difference between"
596        echo " two julian dates (jul1 -jul2)"
597        echo " where a julian date is in the form of yyyyddd."
598    }
599 
600    if [ $# -lt 2 ]; then
601        usage
602        IGCM_debug_Exit "IGCM_date_DaysBetweenJulianDate"
603    fi
604 
605    # This process subtracts arg2 from arg1. If arg2 is larger
606    # then reverse the arguments. The calculations are done, and
607    # then the sign is reversed
608    if [ $1 -lt $2 ]
609        then
610        jul1=$2
611        jul2=$1
612    elif [ $1 -gt $2 ]
613        then
614        jul1=$1
615        jul2=$2
616    else
617        echo 0
618        IGCM_debug_PopStack "IGCM_date_DaysBetweenJulianDate"
619        return
620    fi
621
622    # Break the dates in to year and day portions
623    yyyy1=$(( $jul1 / 1000 ))
624    yyyy2=$(( $jul2 / 1000 ))
625    ddd1=$(( $jul1 % 1000 ))
626    ddd2=$(( $jul2 % 1000 ))
627
628    # Subtract days
629    res=$(( $ddd1 - $ddd2 ))
630
631    # Then add days in year until year2 matches year1
632
633    if [ "${config_UserChoices_CalendarType}" = "360d" ] ; then
634        res=$(( ( ( $yyyy1 - $yyyy2 ) * 360 ) + $res ))
635    elif [ "${config_UserChoices_CalendarType}" = "noleap" ] ; then
636        res=$(( ( ( $yyyy1 - $yyyy2 ) * 365 ) + $res ))
637    elif [ "${config_UserChoices_CalendarType}" = "all_leap" ] ; then
638        res=$(( ( ( $yyyy1 - $yyyy2 ) * 366 ) + $res ))
639    elif ( [ "${config_UserChoices_CalendarType}" = "leap" ] || [ "${config_UserChoices_CalendarType}" = "gregorian" ] ) ; then
640        while [ $yyyy2 -lt $yyyy1 ]
641          do
642          IGCM_date_DaysInYear $yyyy2 diy
643          res=$(( $res + $diy ))
644          yyyy2=$(( $yyyy2 + 1 ))
645        done
646    fi
647
648    # if argument 2 was larger than argument 1 then
649    # the arguments were reversed before calculating
650    # adjust by reversing the sign
651    if [ $1 -lt $2 ]
652        then
653        res=$(( $res * -1 ))
654    fi
655 
656    # and output the results
657    echo $res
658
659    IGCM_debug_PopStack "IGCM_date_DaysBetweenJulianDate"
660}
661
662#D-#==================================================================
663#D-function IGCM_date_DaysBetweenGregorianDate ()
664#D-* Purpose: Calculate the days difference between two dates and reports
665#D-           the number days as grg1 - grg2
666#D-* Usage: IGCM_date_DaysBetweenGregorianDate grg1 grg2
667#D-         where gregorian date is in the form yyyymmdd
668#D-
669function IGCM_date_DaysBetweenGregorianDate
670{
671    IGCM_debug_PushStack "IGCM_date_DaysBetweenGregorianDate" $@
672
673    # calculates the days difference between two dates and reports
674    # the number days as grg1 - grg2
675    # usage IGCM_date_DaysBetweenGregorianDate grg1 grg2
676    # where gregorian date is in the form yyyymmdd
677
678    usage () {
679        echo "Usage:"
680        echo " IGCM_date_DaysBetweenGregorianDate grg1 grg2"
681        echo ""
682        echo " Calculate day difference between"
683        echo " two gregorian dates (grg1 - grg2)"
684        echo " where a gregorian date is in the form of yyyymmdd."
685    }
686
687    if [ $# -lt 2 ]; then
688        usage
689        IGCM_debug_Exit "IGCM_date_DaysBetweenGregorianDate"
690    fi
691
692    # convert each date to julian
693    grg1=$1
694    grg2=$2
695
696    jul1=$( IGCM_date_ConvertGregorianDateToJulian $grg1 )
697    jul2=$( IGCM_date_ConvertGregorianDateToJulian $grg2 )
698
699    if [ $jul1 -ne $jul2 ]; then
700    # calculate the answer using IGCM_date_DaysBetweenJulianDate
701        res=$( IGCM_date_DaysBetweenJulianDate $jul1 $jul2 )
702    # and output the results
703        echo $res
704    else
705        echo 0
706    fi
707
708    IGCM_debug_PopStack "IGCM_date_DaysBetweenGregorianDate"
709}
710
711#D-#==================================================================
712#D-function IGCM_date_DaysSinceJC ()
713#D-* Purpose: Calculate the days difference between a date and 00010101
714#D-* Usage: IGCM_date_DaysSinceJC grg1
715#D-         where gregorian date is in the form yyyymmdd
716#D-
717function IGCM_date_DaysSinceJC
718{
719    IGCM_debug_PushStack "IGCM_date_DaysSinceJC" $@
720
721    # calculates the days difference between a date and 00010101
722    # usage IGCM_date_DaysSinceJC grg1
723    # where gregorian date is in the form yyyymmdd
724
725    usage () {
726        echo "Usage:"
727        echo " IGCM_date_DaysSinceJC grg1"
728        echo ""
729        echo " Calculate day difference between"
730        echo " a gregorian date and 00010101"
731        echo " where a gregorian date is in the form of yyyymmdd."
732    }
733
734    if [ $# -lt 1 ]; then
735        usage
736        IGCM_debug_Exit "IGCM_date_DaysSinceJC"
737    fi
738   
739    typeset aux num
740
741    if   [ ${1} -lt  5000000 ]; then
742        case ${config_UserChoices_CalendarType} in
743            360d) 
744                aux=-360;;
745            noleap)
746                aux=-365;;
747            all_leap) 
748                aux=-366;;
749            leap|gregorian)
750                aux=-366;;
751        esac
752        num=101
753    elif [ ${1} -lt 15000000 ]; then
754        # To save CPU type we use auxiliary value
755        # which is number of days since JC and 10000101
756        case ${config_UserChoices_CalendarType} in
757            360d) 
758                aux=359640;;
759            noleap)
760                aux=364635;;
761            all_leap) 
762                aux=365634;;
763            leap|gregorian)
764                aux=364877;;
765        esac
766        num=10000101
767    else
768        # To save CPU type we use auxiliary value
769        # which is number of days since JC and 19000101
770        case ${config_UserChoices_CalendarType} in
771            360d) 
772                aux=683640;;
773            noleap)
774                aux=693135;;
775            all_leap) 
776                aux=695034;;
777            leap|gregorian)
778                aux=693595;;
779        esac
780        num=19000101
781    fi
782    echo $(( $( IGCM_date_DaysBetweenGregorianDate $1 ${num} ) + $aux ))
783
784    IGCM_debug_PopStack "IGCM_date_DaysSinceJC"
785}
786
787#D-#==================================================================
788#D-function IGCM_date_Check
789#D- * Purpose: Check the present file by comparison with a reference file
790function IGCM_date_Check
791{
792    IGCM_debug_PushStack "IGCM_date_Check"
793
794#---------------------
795    if [ ! -n "${libIGCM}" ] ; then
796        echo "Check libIGCM_date ...........................................[ FAILED ]"
797        echo "--Error--> libIGCM variable is not defined"
798        IGCM_debug_Exit "IGCM_date_Check"
799    fi
800
801#---------------------
802    whence -v gawk > /dev/null 2>&1
803    if [ ! $? -eq 0 ] ; then
804        echo "Check libIGCM_date ...........................................[ FAILED ]"
805        echo "--Error--> gawk command is not defined"
806        IGCM_debug_Exit "IGCM_date_Check"
807    fi
808
809#---------------------
810    ${libIGCM}/libIGCM_date/IGCM_date_Test.ksh > IGCM_date_Test.ref.failed 2>&1
811   
812    if diff IGCM_date_Test.ref.failed ${libIGCM}/libIGCM_date/IGCM_date_Test${dY}.ref > /dev/null 2>&1 ; then
813        echo "Check libIGCM_date ...............................................[ OK ]"
814        rm -f IGCM_date_Test.ref.failed
815    else
816        echo "Check libIGCM_date ...........................................[ FAILED ]"
817        echo "--Error--> Execution of ${libIGCM}/libIGCM_date/IGCM_date_Test.ksh"
818        echo "           has produced the file IGCM_date_Test.ref.failed"
819        echo "           Please analyse differences with the reference file by typing:"
820        echo "           diff IGCM_date_Test.ref.failed ${libIGCM}/libIGCM_date/IGCM_date_Test${dY}.ref"
821        echo "           Report errors to the author: Sebastien.Denvil@ipsl.jussieu.fr"
822        IGCM_debug_Exit "IGCM_date_Check"
823    fi
824
825#---------------------
826    IGCM_debug_PopStack "IGCM_date_Check"
827}
828
829#==================================================================
Note: See TracBrowser for help on using the repository browser.