source: branches/libIGCM_MPI_OpenMP/libIGCM_date/libIGCM_date.ksh @ 559

Last change on this file since 559 was 435, checked in by mmaipsl, 13 years ago

Add switches to accept all synonyms of calendar names (respecfull with CF Convention)

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