44
55# Will Holmgren, University of Arizona, 2014-2016.
66
7- import pathlib
87import datetime
8+ import pathlib
9+ from zoneinfo import ZoneInfo
910
11+ import h5py
1012import pandas as pd
1113import pytz
12- import h5py
1314
14- from pvlib import solarposition , clearsky , atmosphere , irradiance
15+ from pvlib import atmosphere , clearsky , irradiance , solarposition
16+ from pvlib ._deprecation import warn_deprecated
1517from pvlib .tools import _degrees_to_index
1618
1719
@@ -21,10 +23,12 @@ class Location:
2123 timezone, and altitude data associated with a particular
2224 geographic location. You can also assign a name to a location object.
2325
24- Location objects have two timezone attributes:
26+ Location objects have one timezone attribute:
27+
28+ * ``tz`` is a IANA-compatible standard-library zoneinfo.ZoneInfo.
2529
26- * ``tz`` is a IANA timezone string.
27- * ``pytz`` is a pytz timezone object .
30+ Thus, the passed timezone must be representable by one of the values in
31+ zoneinfo.available_timezones() .
2832
2933 Location objects support the print method.
3034
@@ -38,12 +42,12 @@ class Location:
3842 Positive is east of the prime meridian.
3943 Use decimal degrees notation.
4044
41- tz : str, int, float, or pytz. timezone, default 'UTC'.
42- See
43- http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
44- for a list of valid time zones .
45- pytz.timezone objects will be converted to strings.
46- ints and floats must be in hours from UTC .
45+ tz : str, int, float, zoneinfo.ZoneInfo, datetime.timezone, or pytz timezone (deprecated) , default 'UTC'.
46+ See http://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a
47+ list of valid time zone strings, or use the function
48+ zoneinfo.available_timezones() .
49+ ints and floats must be in hours N from UTC, and are converted to the
50+ Etc/GMT+N or Etc/GMT-N format depending on the sign of N .
4751
4852 altitude : float, optional
4953 Altitude from sea level in meters.
@@ -59,33 +63,43 @@ class Location:
5963 pvlib.pvsystem.PVSystem
6064 """
6165
62- def __init__ (self , latitude , longitude , tz = 'UTC' , altitude = None ,
63- name = None ):
66+ def __init__ (
67+ self , latitude , longitude , tz = 'UTC' , altitude = None , name = None
68+ ):
69+
70+ if name is None :
71+ name = ""
72+
73+ self .name = name
6474
6575 self .latitude = latitude
6676 self .longitude = longitude
6777
68- if isinstance (tz , str ):
69- self .tz = tz
70- self .pytz = pytz .timezone (tz )
71- elif isinstance (tz , datetime .timezone ):
72- self .tz = 'UTC'
73- self .pytz = pytz .UTC
74- elif isinstance (tz , datetime .tzinfo ):
75- self .tz = tz .zone
76- self .pytz = tz
77- elif isinstance (tz , (int , float )):
78- self .tz = tz
79- self .pytz = pytz .FixedOffset (tz * 60 )
80- else :
81- raise TypeError ('Invalid tz specification' )
82-
8378 if altitude is None :
8479 altitude = lookup_altitude (latitude , longitude )
8580
8681 self .altitude = altitude
8782
88- self .name = name
83+ if isinstance (tz , str ):
84+ self .tz = ZoneInfo (tz )
85+ elif isinstance (tz , int ):
86+ self .tz = ZoneInfo (f"Etc/GMT{ - tz :+d} " )
87+ elif isinstance (tz , float ):
88+ self .tz = ZoneInfo (f"Etc/GMT{ int (- tz ):+d} " )
89+ elif isinstance (tz , ZoneInfo ):
90+ self .tz = tz
91+ elif isinstance (tz , datetime .timezone ):
92+ self .tz = ZoneInfo (str (tz ))
93+ elif isinstance (tz , pytz .BaseTzInfo ):
94+ warn_deprecated (
95+ "0.11.3" ,
96+ message = 'pytz timezones are deprecated' ,
97+ alternative = 'use zoneinfo.ZoneInfo from the standard library' ,
98+ obj_type = 'function argument type' ,
99+ )
100+ self .tz = ZoneInfo (tz .zone )
101+ else :
102+ raise TypeError (f'Invalid tz specification: { tz } ' )
89103
90104 def __repr__ (self ):
91105 attrs = ['name' , 'latitude' , 'longitude' , 'altitude' , 'tz' ]
0 commit comments