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