@@ -20,6 +20,7 @@ module ncvar_mod
20
20
type (datetime) :: start_date
21
21
integer :: nx, ny
22
22
integer :: dt
23
+ integer :: units_as_seconds
23
24
character (len= 9 ) :: calendar
24
25
25
26
integer :: idx_guess
@@ -32,7 +33,7 @@ module ncvar_mod
32
33
procedure , pass(self), public :: refresh = > ncvar_refresh
33
34
procedure , pass(self), public :: read_data = > ncvar_read_data
34
35
procedure , pass(self) :: get_index_for_datetime
35
- procedure , pass(self) :: get_start_date_and_calendar
36
+ procedure , pass(self) :: get_time_metadata
36
37
endtype ncvar
37
38
38
39
contains
@@ -120,9 +121,10 @@ subroutine ncvar_refresh(self, filename, &
120
121
call ncheck(nf90_get_var(self% ncid, time_varid, self% times), &
121
122
' ncvar get_var time in: ' // trim (self% filename))
122
123
123
- self% dt = int ((self% times(2 ) - self% times(1 ))* 3600 )
124
124
! Initialise start date and calendar
125
- call self% get_start_date_and_calendar(time_varid, self% start_date, self% calendar)
125
+ call self% get_time_metadata(time_varid, self% start_date, self% calendar, &
126
+ self% units_as_seconds)
127
+ self% dt = int ((self% times(2 ) - self% times(1 ))* self% units_as_seconds)
126
128
127
129
status = nf90_get_att(self% ncid, time_varid, " bounds" , time_bnds_name)
128
130
if (status == nf90_noerr) then
@@ -147,35 +149,39 @@ subroutine ncvar_refresh(self, filename, &
147
149
148
150
end subroutine
149
151
150
- subroutine get_start_date_and_calendar (self , time_varid , start_date , calendar )
152
+ ! > Return the start_date, calendar and time dimenstion units
153
+ subroutine get_time_metadata (self , time_varid , start_date , calendar , units_as_seconds )
151
154
class(ncvar), intent (in ) :: self
152
155
integer , intent (in ) :: time_varid
153
156
type (datetime), intent (out ) :: start_date
154
157
character (len= 9 ), intent (out ) :: calendar
158
+ integer , intent (out ) :: units_as_seconds
155
159
156
160
character (len= 256 ) :: time_str
157
161
type (tm_struct) :: ctime
158
162
integer :: rc, idx
159
163
160
164
! Getcalendar
161
165
call ncheck(nf90_get_att(self% ncid, time_varid, " calendar" , calendar), &
162
- ' get_start_date_and_calendar : nf90_get_att: ' // calendar)
166
+ ' get_time_metadata : nf90_get_att: ' // calendar)
163
167
if (trim (calendar) == ' NOLEAP' ) then
164
168
calendar = ' noleap'
165
169
endif
166
170
call assert(trim (calendar) == ' noleap' .or. trim (calendar) == ' gregorian' , &
167
- ' get_start_date_and_calendar : unrecognized calendar type' )
171
+ ' get_time_metadata : unrecognized calendar type' )
168
172
169
173
! Get start date
170
174
call ncheck(nf90_get_att(self% ncid, time_varid, " units" , time_str), &
171
- ' get_start_date_and_calendar : nf90_get_att: ' // time_str)
175
+ ' get_time_metadata : nf90_get_att: ' // time_str)
172
176
173
177
! See whether it has the expected format
174
178
idx = index (trim (time_str), " days since" )
175
179
time_str = replace_text(time_str, " days since " , " " )
180
+ units_as_seconds = 86400
176
181
if (idx <= 0 ) then
177
182
idx = index (trim (time_str), " hours since" )
178
183
time_str = replace_text(time_str, " hours since " , " " )
184
+ units_as_seconds = 3600
179
185
endif
180
186
call assert(idx > 0 , " ncvar invalid time format" )
181
187
@@ -189,7 +195,7 @@ subroutine get_start_date_and_calendar(self, time_varid, start_date, calendar)
189
195
call assert(rc /= 0 , ' strptime in get_start_date_and_calendar failed on ' // time_str)
190
196
start_date = tm2date(ctime)
191
197
192
- end subroutine get_start_date_and_calendar
198
+ end subroutine get_time_metadata
193
199
194
200
! > Return the time index of a particular date.
195
201
function get_index_for_datetime (self , target_date , from_beginning , guess )
@@ -218,11 +224,11 @@ function get_index_for_datetime(self, target_date, from_beginning, guess)
218
224
! Must convert to days _and_ seconds rather than just days to avoid
219
225
! integer overflow.
220
226
hours = floor (self% time_bnds(1 , i))
221
- seconds = nint ((self% time_bnds(1 , i) - hours)* 3600 )
227
+ seconds = nint ((self% time_bnds(1 , i) - hours)* self % units_as_seconds )
222
228
td_before = timedelta(hours= hours, seconds= seconds)
223
229
224
230
hours = floor (self% time_bnds(2 , i))
225
- seconds = nint ((self% time_bnds(2 , i) - hours)* 3600 )
231
+ seconds = nint ((self% time_bnds(2 , i) - hours)* self % units_as_seconds )
226
232
td_after = timedelta(hours= hours, seconds= seconds)
227
233
228
234
if (target_date >= (self% start_date + td_before) .and. &
@@ -235,7 +241,7 @@ function get_index_for_datetime(self, target_date, from_beginning, guess)
235
241
else
236
242
do i= self% idx_guess, size (self% times)
237
243
hours = floor (self% times(i))
238
- seconds = nint ((self% times(i) - hours)* 3600 )
244
+ seconds = nint ((self% times(i) - hours)* self % units_as_seconds )
239
245
td = timedelta(hours= hours, seconds= seconds)
240
246
241
247
if (target_date == (self% start_date + td)) then
0 commit comments