C $Header: /u/gcmpack/MITgcm/pkg/cal/cal_daysformonth.F,v 1.3 2012/04/19 19:43:31 heimbach Exp $
C $Name: $
#include "CAL_OPTIONS.h"
subroutine CAL_DAYSFORMONTH(
I imonth,
O firstday,
O lastday,
O ndays,
I mythid
& )
c ==================================================================
c SUBROUTINE cal_DaysForMonth
c ==================================================================
c
c o Given the current month of the integration this routine returns
c first, the last and the number of calendar days that will have
c to be performed.
c
c This routine also checks consistency of variables quite
c extensively.
c
c started: Christian Eckert eckert@mit.edu 06-Apr-2000
c
c changed:
c
c ==================================================================
c SUBROUTINE cal_DaysForMonth
c ==================================================================
implicit none
c == global variables ==
#include "cal.h"
c == routine arguments ==
integer imonth
integer firstday
integer lastday
integer ndays
integer mythid
c == local variables ==
integer i
integer ierr
integer nummonths
integer numdays
integer firstyear
integer firstmonth
integer firstd
integer lyfirst
integer lastyear
integer lastmonth
integer lastd
integer lastsecs
integer lylast
integer currentyear
integer currentmonth
integer lycurrent
c == external ==
integer cal_IntMonths
external
integer cal_IsLeap
external
c == end of interface ==
lyfirst = cal_IsLeap( firstyear, mythid )
lylast = cal_IsLeap( lastyear, mythid )
nummonths = cal_Intmonths( mythid )
firstyear = modelstartdate(1)/10000
firstmonth = mod(modelstartdate(1)/100,100)
firstd = mod(modelstartdate(1),100)
lastyear = modelenddate(1)/10000
lastmonth = mod(modelenddate(1)/100,100)
lastd = mod(modelenddate(1),100)
lastsecs = modelenddate(2)/10000*secondsperhour +
& mod(modelenddate(2)/100,100)*secondsperminute +
& mod(modelenddate(2),100)
if ( nummonths .eq. 1 ) then
if ( imonth .eq. 1 ) then
c-- Get the number of days in the first month.
if ( firstmonth .eq. lastmonth ) then
if (lastsecs .eq. 0) then
c-- Not really another day.
lastday = lastd - 1
else
lastday = lastd
endif
firstday = 1
else if ( mod(firstmonth+1,nmonthyear) .eq. lastmonth ) then
c-- This can only happen if we end at midnight of the first
c-- day of the next month.
if ( ( modelenddate(2) .eq. 0 ) .and.
& ( mod(modelenddate(1),100) .eq. 1 ) ) then
firstday = firstd
lastday = ndaymonth(firstmonth,lyfirst)
else
c-- We do not end at midnight of the first day of
c-- the next month.
ierr = 2704
call CAL_PRINTERROR( ierr, mythid )
stop ' stopped in cal_DaysForMonth.'
endif
else
c-- The first and the last month are inconsistent with imonth.
ierr = 2703
call CAL_PRINTERROR( ierr, mythid )
stop ' stopped in cal_DaysForMonth.'
endif
else
c-- The variables nummonths and imonth are inconsistent;
c-- ( imonth .gt. nummonths ).
ierr = 2702
call CAL_PRINTERROR( ierr, mythid )
stop ' stopped in cal_DaysForMonth.'
endif
else if ( nummonths .gt. 1 ) then
c-- More than one month of integration.
if ( imonth .eq. 1 ) then
firstday = 1
lastday = ndaymonth(firstmonth,lyfirst) - firstd + 1
else if ( ( imonth .gt. 1 ) .and.
& ( imonth .lt. nummonths ) ) then
c-- Somewhere between first and last month.
currentmonth = firstmonth
currentyear = firstyear
numdays = ndaymonth(firstmonth,lyfirst) - firstd + 1
do i = 2,imonth-1
c-- Accumulate days of the intermediate months.
currentmonth = mod(currentmonth+1,nmonthyear)
if ( currentmonth .eq. 0 ) then
currentmonth = 12
endif
if ( currentmonth .eq. 1 ) then
currentyear = currentyear + 1
endif
lycurrent = cal_IsLeap( currentyear, mythid )
numdays = numdays + ndaymonth(currentmonth,lycurrent)
enddo
currentmonth = mod(currentmonth+1,nmonthyear)
if ( currentmonth .eq. 0 ) then
currentmonth = 12
endif
if ( currentmonth .eq. 1 ) then
currentyear = currentyear + 1
endif
lycurrent = cal_IsLeap( currentyear, mythid )
firstday = numdays + 1
lastday = numdays + ndaymonth(currentmonth,lycurrent)
else if ( imonth .eq. nummonths ) then
c-- The last month of the integration.
currentmonth = firstmonth
currentyear = firstyear
numdays = ndaymonth(firstmonth,lyfirst) - firstd + 1
do i = 2,nummonths-1
c-- Accumulate days of the intermediate months.
currentmonth = mod(currentmonth+1,nmonthyear)
if ( currentmonth .eq. 0 ) then
currentmonth = 12
endif
if ( currentmonth .eq. 1 ) then
currentyear = currentyear + 1
endif
lycurrent = cal_IsLeap( currentyear, mythid )
numdays = numdays + ndaymonth(currentmonth,lycurrent)
enddo
c-- Prepare for the last month of integration.
currentmonth = mod(currentmonth+1,nmonthyear)
if ( currentmonth .eq. 0 ) then
currentmonth = 12
endif
if ( currentmonth .eq. 1 ) then
currentyear = currentyear + 1
endif
lycurrent = cal_IsLeap( currentyear, mythid )
if ( ( modelenddate(2) .eq. 0 ) .and.
& ( mod(modelenddate(1),100) .eq. 1 ) ) then
c-- This can only happen if we end at midnight of the first
c-- day of the next month.
lastday = numdays + ndaymonth(currentmonth,lycurrent)
else
c-- We do not stop at midnight of the first day of the
c-- next month.
if (lastsecs .eq. 0) then
c-- But we might stop at midnight of a day.
lastday = numdays + lastd - 1
else
lastday = numdays + lastd
endif
endif
firstday = numdays + 1
else
c-- The variables imonth and nummonths are inconsistent.
ierr = 2705
call CAL_PRINTERROR( ierr, mythid )
stop ' stopped in cal_DaysForMonth.'
endif
else
c-- The number of months to integrate is wrong; check cal_IntMonths.
ierr = 2701
call CAL_PRINTERROR( ierr, mythid )
stop ' stopped in cal_DaysForMonth.'
endif
c-- The number of days to integrate in the given month.
ndays = lastday - firstday + 1
return
end