11
11
import MpasRelativeDelta
12
12
from mpas_analysis .test import TestCase
13
13
from mpas_analysis .shared .timekeeping .utility import stringToDatetime , \
14
- stringToRelativedelta , clampToNumpyDatetime64
14
+ stringToRelativeDelta , clampToNumpyDatetime64
15
15
16
16
17
17
class TestTimekeeping (TestCase ):
@@ -29,113 +29,100 @@ def test_timekeeping(self):
29
29
# YYYY-MM-DD
30
30
# SSSSS
31
31
32
- # test datetime.datetime
33
- # YYYY-MM-DD_hh:mm:ss
34
- date1 = stringToDatetime ('0001-01-01_00:00:00' )
35
- date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
36
- second = 0 )
37
- self .assertEqual (date1 , date2 )
38
-
39
- # test relativedelta
40
- # YYYY-MM-DD_hh:mm:ss
41
- # gregorian_noleap
42
- calendar = 'gregorian_noleap'
43
- date1 = stringToRelativedelta ('0001-00-00_00:00:00' ,
44
- calendar = calendar )
45
- date2 = MpasRelativeDelta (years = 1 , months = 0 , days = 0 , hours = 0 ,
46
- minutes = 0 , seconds = 0 , calendar = calendar )
47
- self .assertEqual (date1 , date2 )
48
-
49
- # gregorian
50
- calendar = 'gregorian'
51
- date1 = stringToRelativedelta ('0001-00-00_00:00:00' ,
52
- calendar = calendar )
53
- date2 = MpasRelativeDelta (years = 1 , months = 0 , days = 0 , hours = 0 ,
54
- minutes = 0 , seconds = 0 , calendar = calendar )
55
- self .assertEqual (date1 , date2 )
56
-
57
- # YYYY-MM-DD_hh.mm.ss
58
- date1 = stringToDatetime ('0001-01-01_00.00.00' )
59
- date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
60
- second = 0 )
61
- self .assertEqual (date1 , date2 )
62
-
63
- # YYYY-MM-DD_SSSSS
64
- date1 = stringToDatetime ('0001-01-01_00002' )
65
- date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
66
- second = 2 )
67
- self .assertEqual (date1 , date2 )
68
-
69
- # DDD_hh:mm:ss
70
- calendar = 'gregorian_noleap'
71
- date1 = stringToRelativedelta ('0001_00:00:01' ,
72
- calendar = calendar )
73
- date2 = MpasRelativeDelta (years = 0 , months = 0 , days = 1 , hours = 0 ,
74
- minutes = 0 , seconds = 1 , calendar = calendar )
75
- self .assertEqual (date1 , date2 )
76
-
77
- # DDD_hh.mm.ss
78
- date1 = stringToRelativedelta ('0002_01.00.01' ,
79
- calendar = calendar )
80
- date2 = MpasRelativeDelta (years = 0 , months = 0 , days = 2 , hours = 1 ,
81
- minutes = 0 , seconds = 1 , calendar = calendar )
82
- self .assertEqual (date1 , date2 )
83
-
84
- # DDD_SSSSS
85
- date1 = stringToRelativedelta ('0002_00003' ,
86
- calendar = calendar )
87
- date2 = MpasRelativeDelta (years = 0 , months = 0 , days = 2 , hours = 0 ,
88
- minutes = 0 , seconds = 3 , calendar = calendar )
89
- self .assertEqual (date1 , date2 )
90
-
91
- # hh:mm:ss
92
- date1 = stringToDatetime ('00:00:01' )
93
- date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
94
- second = 1 )
95
- self .assertEqual (date1 , date2 )
96
-
97
- # hh.mm.ss
98
- calendar = 'gregorian'
99
- date1 = stringToRelativedelta ('00.00.01' ,
100
- calendar = calendar )
101
- date2 = MpasRelativeDelta (years = 0 , months = 0 , days = 0 , hours = 0 ,
102
- minutes = 0 , seconds = 1 , calendar = calendar )
103
- self .assertEqual (date1 , date2 )
104
-
105
- # YYYY-MM-DD
106
- date1 = stringToDatetime ('0001-01-01' )
107
- date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
108
- second = 0 )
109
- self .assertEqual (date1 , date2 )
110
-
111
- # SSSSS
112
- date1 = stringToRelativedelta ('00005' ,
113
- calendar = calendar )
114
- date2 = MpasRelativeDelta (years = 0 , months = 0 , days = 0 , hours = 0 ,
115
- minutes = 0 , seconds = 5 , calendar = calendar )
116
- self .assertEqual (date1 , date2 )
117
-
118
- date1 = stringToDatetime ('1996-01-15' )
119
- date2 = stringToRelativedelta ('0005-00-00' ,
120
- calendar = 'gregorian' )
121
- diff = date1 - date2
122
- self .assertEqual (diff , stringToDatetime ('1991-01-15' ))
123
-
124
- date1 = stringToDatetime ('1996-01-15' )
125
- date2 = stringToRelativedelta ('0000-02-00' ,
126
- calendar = 'gregorian' )
127
- diff = date1 - date2
128
- self .assertEqual (diff , stringToDatetime ('1995-11-15' ))
129
-
130
- date1 = stringToDatetime ('1996-01-15' )
131
- date2 = stringToRelativedelta ('0000-00-20' ,
132
- calendar = 'gregorian' )
133
- diff = date1 - date2
134
- self .assertEqual (diff , stringToDatetime ('1995-12-26' ))
32
+ for calendar in ['gregorian' , 'gregorian_noleap' ]:
33
+ # test datetime.datetime
34
+ # YYYY-MM-DD_hh:mm:ss
35
+ date1 = stringToDatetime ('0001-01-01_00:00:00' )
36
+ date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
37
+ second = 0 )
38
+ self .assertEqual (date1 , date2 )
39
+
40
+ delta1 = stringToRelativeDelta ('0001-00-00_00:00:00' ,
41
+ calendar = calendar )
42
+ delta2 = MpasRelativeDelta (years = 1 , months = 0 , days = 0 , hours = 0 ,
43
+ minutes = 0 , seconds = 0 , calendar = calendar )
44
+ self .assertEqual (delta1 , delta2 )
45
+
46
+ # YYYY-MM-DD_hh.mm.ss
47
+ date1 = stringToDatetime ('0001-01-01_00.00.00' )
48
+ date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
49
+ second = 0 )
50
+ self .assertEqual (date1 , date2 )
51
+
52
+ # YYYY-MM-DD_SSSSS
53
+ date1 = stringToDatetime ('0001-01-01_00002' )
54
+ date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
55
+ second = 2 )
56
+ self .assertEqual (date1 , date2 )
57
+
58
+ # DDD_hh:mm:ss
59
+ delta1 = stringToRelativeDelta ('0001_00:00:01' ,
60
+ calendar = calendar )
61
+ delta2 = MpasRelativeDelta (years = 0 , months = 0 , days = 1 , hours = 0 ,
62
+ minutes = 0 , seconds = 1 , calendar = calendar )
63
+ self .assertEqual (delta1 , delta2 )
64
+
65
+ # DDD_hh.mm.ss
66
+ delta1 = stringToRelativeDelta ('0002_01.00.01' ,
67
+ calendar = calendar )
68
+ delta2 = MpasRelativeDelta (years = 0 , months = 0 , days = 2 , hours = 1 ,
69
+ minutes = 0 , seconds = 1 , calendar = calendar )
70
+ self .assertEqual (delta1 , delta2 )
71
+
72
+ # DDD_SSSSS
73
+ delta1 = stringToRelativeDelta ('0002_00003' ,
74
+ calendar = calendar )
75
+ delta2 = MpasRelativeDelta (years = 0 , months = 0 , days = 2 , hours = 0 ,
76
+ minutes = 0 , seconds = 3 , calendar = calendar )
77
+ self .assertEqual (delta1 , delta2 )
78
+
79
+ # hh:mm:ss
80
+ date1 = stringToDatetime ('00:00:01' )
81
+ date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
82
+ second = 1 )
83
+ self .assertEqual (date1 , date2 )
84
+
85
+ # hh.mm.ss
86
+ delta1 = stringToRelativeDelta ('00.00.01' ,
87
+ calendar = calendar )
88
+ delta2 = MpasRelativeDelta (years = 0 , months = 0 , days = 0 , hours = 0 ,
89
+ minutes = 0 , seconds = 1 , calendar = calendar )
90
+ self .assertEqual (delta1 , delta2 )
91
+
92
+ # YYYY-MM-DD
93
+ date1 = stringToDatetime ('0001-01-01' )
94
+ date2 = datetime .datetime (year = 1 , month = 1 , day = 1 , hour = 0 , minute = 0 ,
95
+ second = 0 )
96
+ self .assertEqual (date1 , date2 )
97
+
98
+ # SSSSS
99
+ delta1 = stringToRelativeDelta ('00005' ,
100
+ calendar = calendar )
101
+ delta2 = MpasRelativeDelta (years = 0 , months = 0 , days = 0 , hours = 0 ,
102
+ minutes = 0 , seconds = 5 , calendar = calendar )
103
+ self .assertEqual (delta1 , delta2 )
104
+
105
+ date1 = stringToDatetime ('1996-01-15' )
106
+ delta = stringToRelativeDelta ('0005-00-00' ,
107
+ calendar = calendar )
108
+ date2 = date1 - delta
109
+ self .assertEqual (date2 , stringToDatetime ('1991-01-15' ))
110
+
111
+ date1 = stringToDatetime ('1996-01-15' )
112
+ delta = stringToRelativeDelta ('0000-02-00' ,
113
+ calendar = calendar )
114
+ date2 = date1 - delta
115
+ self .assertEqual (date2 , stringToDatetime ('1995-11-15' ))
116
+
117
+ date1 = stringToDatetime ('1996-01-15' )
118
+ delta = stringToRelativeDelta ('0000-00-20' ,
119
+ calendar = calendar )
120
+ date2 = date1 - delta
121
+ self .assertEqual (date2 , stringToDatetime ('1995-12-26' ))
135
122
136
123
# since pandas and xarray use the numpy type 'datetime[ns]`, which
137
- # has a limited range of dates, the date 0001-01-01 gets increased to
138
- # the minimum allowed year boundary, 1678-01-01 to avoid invalid
124
+ # has a limited range of dates, the date 0001-01-01 gets increased
125
+ # to the minimum allowed year boundary, 1678-01-01 to avoid invalid
139
126
# dates.
140
127
date1 = clampToNumpyDatetime64 (stringToDatetime ('0001-01-01' ),
141
128
yearOffset = 0 )
@@ -148,53 +135,92 @@ def test_timekeeping(self):
148
135
self .assertEqual (date1 , date2 )
149
136
150
137
# since pandas and xarray use the numpy type 'datetime[ns]`, which
151
- # has a limited range of dates, the date 9999-01-01 gets decreased to
152
- # the maximum allowed year boundary, 2262-01-01 to avoid invalid
138
+ # has a limited range of dates, the date 9999-01-01 gets decreased
139
+ # to the maximum allowed year boundary, 2262-01-01 to avoid invalid
153
140
# dates.
154
141
date1 = clampToNumpyDatetime64 (stringToDatetime ('9999-01-01' ),
155
142
yearOffset = 0 )
156
143
date2 = datetime .datetime (year = 2262 , month = 1 , day = 1 )
157
144
self .assertEqual (date1 , date2 )
158
145
159
- # test if the calendars behave as they should
160
- self .assertEqual (stringToDatetime ('2016-02-28' ) +
161
- stringToRelativedelta ('0000-00-01' ,
162
- calendar = 'gregorian' ),
163
- stringToDatetime ('2016-02-29' ))
164
-
165
- self .assertEqual (stringToDatetime ('2016-02-28' ) +
166
- stringToRelativedelta ('0000-00-01' ,
167
- calendar = 'gregorian_noleap' ),
168
- stringToDatetime ('2016-03-01' ))
169
-
170
- self .assertEqual (stringToDatetime ('2016-03-01' ) -
171
- stringToRelativedelta ('0000-00-01' ,
172
- calendar = 'gregorian' ),
173
- stringToDatetime ('2016-02-29' ))
174
-
175
- self .assertEqual (stringToDatetime ('2016-03-01' ) -
176
- stringToRelativedelta ('0000-00-01' ,
177
- calendar = 'gregorian_noleap' ),
178
- stringToDatetime ('2016-02-28' ))
179
-
180
- self .assertEqual (stringToDatetime ('2016-01-31' ) +
181
- stringToRelativedelta ('0000-01-00' ,
182
- calendar = 'gregorian' ),
183
- stringToDatetime ('2016-02-29' ))
184
-
185
- self .assertEqual (stringToDatetime ('2016-01-31' ) +
186
- stringToRelativedelta ('0000-01-00' ,
187
- calendar = 'gregorian_noleap' ),
188
- stringToDatetime ('2016-02-28' ))
189
-
190
- self .assertEqual (stringToDatetime ('2016-03-31' ) -
191
- stringToRelativedelta ('0000-01-00' ,
192
- calendar = 'gregorian' ),
193
- stringToDatetime ('2016-02-29' ))
194
-
195
- self .assertEqual (stringToDatetime ('2016-03-31' ) -
196
- stringToRelativedelta ('0000-01-00' ,
197
- calendar = 'gregorian_noleap' ),
198
- stringToDatetime ('2016-02-28' ))
146
+ def test_MpasRelativeDeltaOps (self ):
147
+ # test if the calendars behave as they should close to leap day
148
+ # both calendars with adding one day
149
+ for calendar , expected in zip (['gregorian' , 'gregorian_noleap' ],
150
+ ['2016-02-29' , '2016-03-01' ]):
151
+ self .assertEqual (stringToDatetime ('2016-02-28' ) +
152
+ stringToRelativeDelta ('0000-00-01' ,
153
+ calendar = calendar ),
154
+ stringToDatetime (expected ))
155
+
156
+ # both calendars with subtracting one day
157
+ for calendar , expected in zip (['gregorian' , 'gregorian_noleap' ],
158
+ ['2016-02-29' , '2016-02-28' ]):
159
+ self .assertEqual (stringToDatetime ('2016-03-01' ) -
160
+ stringToRelativeDelta ('0000-00-01' ,
161
+ calendar = calendar ),
162
+ stringToDatetime (expected ))
163
+
164
+ # both calendars with adding one month
165
+ for calendar , expected in zip (['gregorian' , 'gregorian_noleap' ],
166
+ ['2016-02-29' , '2016-02-28' ]):
167
+ self .assertEqual (stringToDatetime ('2016-01-31' ) +
168
+ stringToRelativeDelta ('0000-01-00' ,
169
+ calendar = calendar ),
170
+ stringToDatetime (expected ))
171
+
172
+ # both calendars with subtracting one month
173
+ for calendar , expected in zip (['gregorian' , 'gregorian_noleap' ],
174
+ ['2016-02-29' , '2016-02-28' ]):
175
+ self .assertEqual (stringToDatetime ('2016-03-31' ) -
176
+ stringToRelativeDelta ('0000-01-00' ,
177
+ calendar = calendar ),
178
+ stringToDatetime (expected ))
179
+
180
+ for calendar in ['gregorian' , 'gregorian_noleap' ]:
181
+ # we have already tested addition and subtraction of the form
182
+ # datetime.datetime +/- MpasRelativeDelta above
183
+
184
+ delta1 = stringToRelativeDelta ('0000-01-00' , calendar = calendar )
185
+ delta2 = stringToRelativeDelta ('0000-00-01' , calendar = calendar )
186
+ deltaSum = stringToRelativeDelta ('0000-01-01' , calendar = calendar )
187
+ # test MpasRelativeDelta + MpasRelativeDelta
188
+ self .assertEqual (delta1 + delta2 , deltaSum )
189
+ # test MpasRelativeDelta - MpasRelativeDelta
190
+ self .assertEqual (deltaSum - delta2 , delta1 )
191
+
192
+ # test MpasRelativeDelta(date1, date2)
193
+ date1 = stringToDatetime ('0002-02-02' )
194
+ date2 = stringToDatetime ('0001-01-01' )
195
+ delta = stringToRelativeDelta ('0001-01-01' , calendar = calendar )
196
+ self .assertEqual (MpasRelativeDelta (dt1 = date1 , dt2 = date2 ,
197
+ calendar = calendar ),
198
+ delta )
199
+
200
+ # test MpasRelativeDelta + datetime.datetime (an odd order but
201
+ # it's allowed...)
202
+ date1 = stringToDatetime ('0001-01-01' )
203
+ delta = stringToRelativeDelta ('0001-01-01' , calendar = calendar )
204
+ date2 = stringToDatetime ('0002-02-02' )
205
+ self .assertEqual (delta + date1 , date2 )
206
+
207
+ # test multiplication/division by scalars
208
+ delta1 = stringToRelativeDelta ('0001-01-01' , calendar = calendar )
209
+ delta2 = stringToRelativeDelta ('0002-02-02' , calendar = calendar )
210
+ self .assertEqual (2 * delta1 , delta2 )
211
+ self .assertEqual (delta2 / 2 , delta1 )
212
+
213
+
214
+ # make sure there's an error when we try to add MpasRelativeDeltas
215
+ # with different calendars
216
+ with self .assertRaisesRegexp (ValueError ,
217
+ 'MpasRelativeDelta objects can only be '
218
+ 'added if their calendars match.' ):
219
+ delta1 = stringToRelativeDelta ('0000-01-00' ,
220
+ calendar = 'gregorian' )
221
+ delta2 = stringToRelativeDelta ('0000-00-01' ,
222
+ calendar = 'gregorian_noleap' )
223
+ deltaSum = delta1 + delta2
224
+
199
225
200
226
# vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python
0 commit comments