source: tags/libIGCM_v1_12/libIGCM_date/libIGCM_date.ksh

Last change on this file was 522, checked in by sdipsl, 13 years ago

Source driver from ${SUBMIT_DIR}/DRIVER/ if it exists ; otherwise back to default
Add yyyymm_m1, yyyymm_p1, month_m1, month_p1 and day as available global variables. Needed by LMDZ-REPROBUS
Add IGCM_date_GetYearMonthDay function
JG

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