Skip to content

Commit fb5dcee

Browse files
authored
forecast compat with pandas 1.0, fix bug in Location tz handling (#879)
* fix location tz bug with datetime.timezone.utc * update whatsnew * issue in whatsnew * fix whatsnew class typo
1 parent a18ee10 commit fb5dcee

File tree

5 files changed

+57
-23
lines changed

5 files changed

+57
-23
lines changed

docs/sphinx/source/whatsnew/v0.7.2.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
v0.7.2 (Month day, year)
44
-------------------------
55

6+
API Changes
7+
~~~~~~~~~~~
8+
* :py:class:`pvlib.forecast.ForecastModel` now requires ``start`` and ``end``
9+
arguments to be tz-localized. (:issue:`877`, :pull:`879`)
10+
611
Enhancements
712
~~~~~~~~~~~~
813
* TMY3 dataframe returned by :py:func:`~pvlib.iotools.read_tmy3` now contains
@@ -15,6 +20,8 @@ Bug fixes
1520
a leap year (:pull:`866`)
1621
* Implement NREL Developer Network API key for consistent success with API
1722
calls in :py:mod:`pvlib.tests.iotools.test_psm3` (:pull:`873`)
23+
* Fix issue with :py:class:`pvlib.location.Location` creation when
24+
passing ``tz=datetime.timezone.utc`` (:pull:`879`)
1825

1926
Documentation
2027
~~~~~~~~~~~~~
@@ -29,3 +36,6 @@ Contributors
2936
* Mark Mikofski (:ghuser:`mikofski`)
3037
* Cliff Hansen (:ghuser:`cwhanse`)
3138
* Cameron T. Stark (:ghuser:`camerontstark`)
39+
* Will Holmgren (:ghuser:`wholmgren`)
40+
* Kevin Anderson (:ghuser:`kanderso-nrel`)
41+
* Karthikeyan Singaravelan (:ghuser:`tirkarthi`)

pvlib/forecast.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,25 @@ def set_dataset(self):
165165
self.ncss = NCSS(self.access_url)
166166
self.query = self.ncss.query()
167167

168+
def set_query_time_range(self, start, end):
169+
"""
170+
Parameters
171+
----------
172+
start : datetime.datetime, pandas.Timestamp
173+
Must be tz-localized.
174+
end : datetime.datetime, pandas.Timestamp
175+
Must be tz-localized.
176+
177+
Notes
178+
-----
179+
Assigns ``self.start``, ``self.end``. Modifies ``self.query``
180+
"""
181+
self.start = pd.Timestamp(start)
182+
self.end = pd.Timestamp(end)
183+
if self.start.tz is None or self.end.tz is None:
184+
raise TypeError('start and end must be tz-localized')
185+
self.query.time_range(self.start, self.end)
186+
168187
def set_query_latlon(self):
169188
'''
170189
Sets the NCSS query location latitude and longitude.
@@ -180,24 +199,24 @@ def set_query_latlon(self):
180199
self.lbox = False
181200
self.query.lonlat_point(self.longitude, self.latitude)
182201

183-
def set_location(self, time, latitude, longitude):
202+
def set_location(self, tz, latitude, longitude):
184203
'''
185204
Sets the location for the query.
186205
187206
Parameters
188207
----------
189-
time: datetime or DatetimeIndex
190-
Time range of the query.
191-
'''
192-
if isinstance(time, datetime.datetime):
193-
tzinfo = time.tzinfo
194-
else:
195-
tzinfo = time.tz
208+
tz: tzinfo
209+
Timezone of the query
210+
latitude: float
211+
Latitude of the query
212+
longitude: float
213+
Longitude of the query
196214
197-
if tzinfo is None:
198-
self.location = Location(latitude, longitude)
199-
else:
200-
self.location = Location(latitude, longitude, tz=tzinfo)
215+
Notes
216+
-----
217+
Assigns ``self.location``.
218+
'''
219+
self.location = Location(latitude, longitude, tz=tz)
201220

202221
def get_data(self, latitude, longitude, start, end,
203222
vert_level=None, query_variables=None,
@@ -243,14 +262,12 @@ def get_data(self, latitude, longitude, start, end,
243262
else:
244263
self.query_variables = query_variables
245264

265+
self.set_query_time_range(start, end)
266+
246267
self.latitude = latitude
247268
self.longitude = longitude
248269
self.set_query_latlon() # modifies self.query
249-
self.set_location(start, latitude, longitude)
250-
251-
self.start = start
252-
self.end = end
253-
self.query.time_range(self.start, self.end)
270+
self.set_location(self.start.tz, latitude, longitude)
254271

255272
if self.vert_level is not None:
256273
self.query.vertical_level(self.vert_level)

pvlib/location.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ def __init__(self, latitude, longitude, tz='UTC', altitude=0,
6666
if isinstance(tz, str):
6767
self.tz = tz
6868
self.pytz = pytz.timezone(tz)
69+
elif isinstance(tz, datetime.timezone):
70+
self.tz = 'UTC'
71+
self.pytz = pytz.UTC
6972
elif isinstance(tz, datetime.tzinfo):
7073
self.tz = tz.zone
7174
self.pytz = tz

pvlib/tests/test_forecast.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from datetime import datetime, timedelta
2-
from pytz import timezone
1+
from datetime import datetime, timedelta, timezone
32
import warnings
43

54
import pandas as pd
@@ -114,7 +113,7 @@ def test_vert_level():
114113
@requires_siphon
115114
def test_datetime():
116115
amodel = NAM()
117-
start = datetime.now()
116+
start = datetime.now(tz=timezone.utc)
118117
end = start + timedelta(days=1)
119118
amodel.get_processed_data(_latitude, _longitude, start, end)
120119

@@ -138,7 +137,6 @@ def test_full():
138137
GFS(set_type='full')
139138

140139

141-
@requires_siphon
142140
def test_temp_convert():
143141
amodel = GFS()
144142
data = pd.DataFrame({'temp_air': [273.15]})
@@ -157,14 +155,19 @@ def test_temp_convert():
157155
# variables=new_variables)
158156

159157

160-
@requires_siphon
161158
def test_set_location():
162159
amodel = GFS()
163160
latitude, longitude = 32.2, -110.9
164-
time = datetime.now(timezone('UTC'))
161+
time = 'UTC'
165162
amodel.set_location(time, latitude, longitude)
166163

167164

165+
def test_set_query_time_range_tzfail():
166+
amodel = GFS()
167+
with pytest.raises(TypeError):
168+
amodel.set_query_time_range(datetime.now(), datetime.now())
169+
170+
168171
def test_cloud_cover_to_transmittance_linear():
169172
amodel = GFS()
170173
assert_allclose(amodel.cloud_cover_to_transmittance_linear(0), 0.75)

pvlib/tests/test_location.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def test_location_all():
2929

3030
@pytest.mark.parametrize('tz', [
3131
pytz.timezone('US/Arizona'), 'America/Phoenix', -7, -7.0,
32+
datetime.timezone.utc
3233
])
3334
def test_location_tz(tz):
3435
Location(32.2, -111, tz)

0 commit comments

Comments
 (0)