@@ -86,7 +86,9 @@ def test_cf_datetime(self):
86
86
for calendar in ['standard' , 'gregorian' , 'proleptic_gregorian' ]:
87
87
expected = nc4 .num2date (num_dates , units , calendar )
88
88
print (num_dates , units , calendar )
89
- actual = conventions .decode_cf_datetime (num_dates , units , calendar )
89
+ with warnings .catch_warnings ():
90
+ warnings .filterwarnings ('ignore' , 'Unable to decode time axis' )
91
+ actual = conventions .decode_cf_datetime (num_dates , units , calendar )
90
92
if (isinstance (actual , np .ndarray )
91
93
and np .issubdtype (actual .dtype , np .datetime64 )):
92
94
self .assertEqual (actual .dtype , np .dtype ('M8[ns]' ))
@@ -111,8 +113,6 @@ def test_cf_datetime(self):
111
113
112
114
@requires_netCDF4
113
115
def test_decoded_cf_datetime_array (self ):
114
- import netCDF4 as nc4
115
-
116
116
actual = conventions .DecodedCFDatetimeArray (
117
117
[0 , 1 , 2 ], 'days since 1900-01-01' , 'standard' )
118
118
expected = pd .date_range ('1900-01-01' , periods = 3 ).values
@@ -125,13 +125,103 @@ def test_decoded_cf_datetime_array(self):
125
125
self .assertEqual (actual .dtype , np .dtype ('datetime64[ns]' ))
126
126
self .assertArrayEqual (actual , expected )
127
127
128
- num_dates = [722000 , 720000.5 ]
129
- units = 'days since 0001-01-01 0:0:0'
128
+ @requires_netCDF4
129
+ def test_decode_non_standard_calendar (self ):
130
+ import netCDF4 as nc4
131
+
132
+ for calendar in ['noleap' , '365_day' , '360_day' , 'julian' , 'all_leap' ,
133
+ '366_day' ]:
134
+ units = 'days since 0001-01-01'
135
+ times = pd .date_range ('2001-04-01-00' , end = '2001-04-30-23' ,
136
+ freq = 'H' )
137
+ noleap_time = nc4 .date2num (times .to_pydatetime (), units ,
138
+ calendar = calendar )
139
+ expected = times .values
140
+ with warnings .catch_warnings ():
141
+ warnings .filterwarnings ('ignore' , 'Unable to decode time axis' )
142
+ actual = conventions .decode_cf_datetime (noleap_time , units ,
143
+ calendar = calendar )
144
+ self .assertEqual (actual .dtype , np .dtype ('M8[ns]' ))
145
+ self .assertArrayEqual (actual , expected )
146
+
147
+ @requires_netCDF4
148
+ def test_decode_non_standard_calendar_single_element (self ):
149
+ units = 'days since 0001-01-01'
150
+ for calendar in ['noleap' , '365_day' , '360_day' , 'julian' , 'all_leap' ,
151
+ '366_day' ]:
152
+ for num_time in [735368 , [735368 ], [[735368 ]]]:
153
+ with warnings .catch_warnings ():
154
+ warnings .filterwarnings ('ignore' , 'Unable to decode time axis' )
155
+ actual = conventions .decode_cf_datetime (num_time , units ,
156
+ calendar = calendar )
157
+ self .assertEqual (actual .dtype , np .dtype ('M8[ns]' ))
158
+
159
+ @requires_netCDF4
160
+ def test_decode_non_standard_calendar_single_element_fallback (self ):
161
+ import netCDF4 as nc4
162
+
163
+ units = 'days since 0001-01-01'
164
+ dt = nc4 .netcdftime .datetime (2001 , 2 , 29 )
165
+ for calendar in ['360_day' , 'all_leap' , '366_day' ]:
166
+ num_time = nc4 .date2num (dt , units , calendar )
167
+ with warnings .catch_warnings (record = True ) as w :
168
+ warnings .simplefilter ('always' )
169
+ actual = conventions .decode_cf_datetime (num_time , units ,
170
+ calendar = calendar )
171
+ self .assertEqual (len (w ), 1 )
172
+ self .assertIn ('Unable to decode time axis' ,
173
+ str (w [0 ].message ))
174
+ expected = np .asarray (nc4 .num2date (num_time , units , calendar ))
175
+ print (num_time , calendar , actual , expected )
176
+ self .assertEqual (actual .dtype , np .dtype ('O' ))
177
+ self .assertEqual (expected , actual )
178
+
179
+ @requires_netCDF4
180
+ def test_decode_non_standard_calendar_multidim_time (self ):
181
+ import netCDF4 as nc4
182
+
130
183
calendar = 'noleap'
131
- actual = conventions .DecodedCFDatetimeArray (num_dates , units , calendar )
132
- expected = nc4 .num2date (num_dates , units , calendar )
133
- self .assertEqual (actual .dtype , np .dtype ('O' ))
134
- self .assertArrayEqual (actual , expected )
184
+ units = 'days since 0001-01-01'
185
+ times1 = pd .date_range ('2001-04-01' , end = '2001-04-05' , freq = 'D' )
186
+ times2 = pd .date_range ('2001-05-01' , end = '2001-05-05' , freq = 'D' )
187
+ noleap_time1 = nc4 .date2num (times1 .to_pydatetime (), units ,
188
+ calendar = calendar )
189
+ noleap_time2 = nc4 .date2num (times2 .to_pydatetime (), units ,
190
+ calendar = calendar )
191
+ mdim_time = np .empty ((len (noleap_time1 ), 2 ), )
192
+ mdim_time [:, 0 ] = noleap_time1
193
+ mdim_time [:, 1 ] = noleap_time2
194
+
195
+ expected1 = times1 .values
196
+ expected2 = times2 .values
197
+ with warnings .catch_warnings ():
198
+ warnings .filterwarnings ('ignore' , 'Unable to decode time axis' )
199
+ actual = conventions .decode_cf_datetime (mdim_time , units ,
200
+ calendar = calendar )
201
+ self .assertEqual (actual .dtype , np .dtype ('M8[ns]' ))
202
+ self .assertArrayEqual (actual [:, 0 ], expected1 )
203
+ self .assertArrayEqual (actual [:, 1 ], expected2 )
204
+
205
+ @requires_netCDF4
206
+ def test_decode_non_standard_calendar_fallback (self ):
207
+ import netCDF4 as nc4
208
+ for year in [2010 , 2011 , 2012 , 2013 , 2014 ]: # insure leap year doesn't matter
209
+ for calendar in ['360_day' , '366_day' , 'all_leap' ]:
210
+ calendar = '360_day'
211
+ units = 'days since {0}-01-01' .format (year )
212
+ num_times = np .arange (100 )
213
+ expected = nc4 .num2date (num_times , units , calendar )
214
+
215
+ with warnings .catch_warnings (record = True ) as w :
216
+ warnings .simplefilter ('always' )
217
+ actual = conventions .decode_cf_datetime (num_times , units ,
218
+ calendar = calendar )
219
+ self .assertEqual (len (w ), 1 )
220
+ self .assertIn ('Unable to decode time axis' ,
221
+ str (w [0 ].message ))
222
+
223
+ self .assertEqual (actual .dtype , np .dtype ('O' ))
224
+ self .assertArrayEqual (actual , expected )
135
225
136
226
@requires_netCDF4
137
227
def test_cf_datetime_nan (self ):
0 commit comments