1 |
C $Header: /u/u3/gcmpack/MITgcm/pkg/cal/cal_daysformonth.F,v 1.1.20.2 2003/10/07 20:46:37 adcroft Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "CAL_OPTIONS.h" |
5 |
|
6 |
subroutine cal_DaysForMonth( |
7 |
I imonth, |
8 |
O firstday, |
9 |
O lastday, |
10 |
O ndays, |
11 |
I mythid |
12 |
& ) |
13 |
|
14 |
c ================================================================== |
15 |
c SUBROUTINE cal_DaysForMonth |
16 |
c ================================================================== |
17 |
c |
18 |
c o Given the current month of the integration this routine returns |
19 |
c first, the last and the number of calendar days that will have |
20 |
c to be performed. |
21 |
c |
22 |
c This routine also checks consistency of variables quite |
23 |
c extensively. |
24 |
c |
25 |
c started: Christian Eckert eckert@mit.edu 06-Apr-2000 |
26 |
c |
27 |
c changed: |
28 |
c |
29 |
c ================================================================== |
30 |
c SUBROUTINE cal_DaysForMonth |
31 |
c ================================================================== |
32 |
|
33 |
implicit none |
34 |
|
35 |
c == global variables == |
36 |
|
37 |
#include "cal.h" |
38 |
|
39 |
c == routine arguments == |
40 |
|
41 |
integer imonth |
42 |
integer firstday |
43 |
integer lastday |
44 |
integer ndays |
45 |
integer mythid |
46 |
|
47 |
c == local variables == |
48 |
|
49 |
integer i |
50 |
integer ierr |
51 |
integer nummonths |
52 |
integer numdays |
53 |
integer firstyear |
54 |
integer firstmonth |
55 |
integer firstd |
56 |
integer lyfirst |
57 |
integer lastyear |
58 |
integer lastmonth |
59 |
integer lastd |
60 |
integer lastsecs |
61 |
integer lylast |
62 |
integer currentyear |
63 |
integer currentmonth |
64 |
integer lycurrent |
65 |
|
66 |
c == external == |
67 |
|
68 |
integer cal_IntMonths |
69 |
external cal_IntMonths |
70 |
integer cal_IsLeap |
71 |
external cal_IsLeap |
72 |
|
73 |
c == end of interface == |
74 |
|
75 |
lyfirst = cal_IsLeap( firstyear, mythid ) |
76 |
lylast = cal_IsLeap( lastyear, mythid ) |
77 |
|
78 |
nummonths = cal_Intmonths( mythid ) |
79 |
|
80 |
firstyear = modelstartdate(1)/10000 |
81 |
firstmonth = mod(modelstartdate(1)/100,100) |
82 |
firstd = mod(modelstartdate(1),100) |
83 |
lastyear = modelenddate(1)/10000 |
84 |
lastmonth = mod(modelenddate(1)/100,100) |
85 |
lastd = mod(modelenddate(1),100) |
86 |
lastsecs = modelenddate(2)/10000*secondsperhour + |
87 |
& mod(modelenddate(2)/100,100)*secondsperminute + |
88 |
& mod(modelenddate(2),100) |
89 |
|
90 |
if ( nummonths .eq. 1 ) then |
91 |
if ( imonth .eq. 1 ) then |
92 |
c-- Get the number of days in the first month. |
93 |
if ( firstmonth .eq. lastmonth ) then |
94 |
if (lastsecs .eq. 0) then |
95 |
c-- Not really another day. |
96 |
lastday = lastd - 1 |
97 |
else |
98 |
lastday = lastd |
99 |
endif |
100 |
firstday = 1 |
101 |
else if ( mod(firstmonth+1,nmonthyear) .eq. lastmonth ) then |
102 |
c-- This can only happen if we end at midnight of the first |
103 |
c-- day of the next month. |
104 |
if ( ( modelenddate(2) .eq. 0 ) .and. |
105 |
& ( mod(modelenddate(1),100) .eq. 1 ) ) then |
106 |
firstday = firstd |
107 |
lastday = ndaymonth(firstmonth,lyfirst) |
108 |
else |
109 |
c-- We do not end at midnight of the first day of |
110 |
c-- the next month. |
111 |
ierr = 2704 |
112 |
call cal_PrintError( ierr, mythid ) |
113 |
stop ' stopped in cal_DaysForMonth.' |
114 |
endif |
115 |
else |
116 |
c-- The first and the last month are inconsistent with imonth. |
117 |
ierr = 2703 |
118 |
call cal_PrintError( ierr, mythid ) |
119 |
stop ' stopped in cal_DaysForMonth.' |
120 |
endif |
121 |
else |
122 |
c-- The variables nummonths and imonth are inconsistent; |
123 |
c-- ( imonth .gt. nummonths ). |
124 |
ierr = 2702 |
125 |
call cal_PrintError( ierr, mythid ) |
126 |
stop ' stopped in cal_DaysForMonth.' |
127 |
endif |
128 |
|
129 |
else if ( nummonths .gt. 1 ) then |
130 |
c-- More than one month of integration. |
131 |
if ( imonth .eq. 1 ) then |
132 |
firstday = 1 |
133 |
lastday = ndaymonth(firstmonth,lyfirst) - firstd + 1 |
134 |
else if ( ( imonth .gt. 1 ) .and. |
135 |
& ( imonth .lt. nummonths ) ) then |
136 |
c-- Somewhere between first and last month. |
137 |
currentmonth = firstmonth |
138 |
currentyear = firstyear |
139 |
numdays = ndaymonth(firstmonth,lyfirst) - firstd + 1 |
140 |
do i = 2,imonth-1 |
141 |
c-- Accumulate days of the intermediate months. |
142 |
currentmonth = mod(currentmonth+1,nmonthyear) |
143 |
if ( currentmonth .eq. 1 ) then |
144 |
currentyear = currentyear + 1 |
145 |
endif |
146 |
lycurrent = cal_IsLeap( currentyear, mythid ) |
147 |
numdays = numdays + ndaymonth(currentmonth,lycurrent) |
148 |
enddo |
149 |
currentmonth = mod(currentmonth+1,nmonthyear) |
150 |
if ( currentmonth .eq. 1 ) then |
151 |
currentyear = currentyear + 1 |
152 |
endif |
153 |
lycurrent = cal_IsLeap( currentyear, mythid ) |
154 |
firstday = numdays + 1 |
155 |
lastday = numdays + ndaymonth(currentmonth,lycurrent) |
156 |
else if ( imonth .eq. nummonths ) then |
157 |
c-- The last month of the integration. |
158 |
currentmonth = firstmonth |
159 |
currentyear = firstyear |
160 |
numdays = ndaymonth(firstmonth,lyfirst) - firstd + 1 |
161 |
do i = 2,nummonths-1 |
162 |
c-- Accumulate days of the intermediate months. |
163 |
currentmonth = mod(currentmonth+1,nmonthyear) |
164 |
if ( currentmonth .eq. 1 ) then |
165 |
currentyear = currentyear + 1 |
166 |
endif |
167 |
lycurrent = cal_IsLeap( currentyear, mythid ) |
168 |
numdays = numdays + ndaymonth(currentmonth,lycurrent) |
169 |
enddo |
170 |
c-- Prepare for the last month of integration. |
171 |
currentmonth = mod(currentmonth+1,nmonthyear) |
172 |
if ( currentmonth .eq. 1 ) then |
173 |
currentyear = currentyear + 1 |
174 |
endif |
175 |
lycurrent = cal_IsLeap( currentyear, mythid ) |
176 |
if ( ( modelenddate(2) .eq. 0 ) .and. |
177 |
& ( mod(modelenddate(1),100) .eq. 1 ) ) then |
178 |
c-- This can only happen if we end at midnight of the first |
179 |
c-- day of the next month. |
180 |
lastday = numdays + ndaymonth(currentmonth,lycurrent) |
181 |
else |
182 |
c-- We do not stop at midnight of the first day of the |
183 |
c-- next month. |
184 |
if (lastsecs .eq. 0) then |
185 |
c-- But we might stop at midnight of a day. |
186 |
lastday = numdays + lastd - 1 |
187 |
else |
188 |
lastday = numdays + lastd |
189 |
endif |
190 |
endif |
191 |
firstday = numdays + 1 |
192 |
else |
193 |
c-- The variables imonth and nummonths are inconsistent. |
194 |
ierr = 2705 |
195 |
call cal_PrintError( ierr, mythid ) |
196 |
stop ' stopped in cal_DaysForMonth.' |
197 |
endif |
198 |
else |
199 |
c-- The number of months to integrate is wrong; check cal_IntMonths. |
200 |
ierr = 2701 |
201 |
call cal_PrintError( ierr, mythid ) |
202 |
stop ' stopped in cal_DaysForMonth.' |
203 |
endif |
204 |
|
205 |
c-- The number of days to integrate in the given month. |
206 |
ndays = lastday - firstday + 1 |
207 |
|
208 |
return |
209 |
end |
210 |
|