source: tags/libIGCM_v1_7/libIGCM_date/libIGCM_date.ksh @ 302

Last change on this file since 302 was 283, checked in by mmaipsl, 14 years ago

MM, PC: suppress leading zeros in some mathematical operations to

protect them against ksh octal cast.

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