0
# Timezone Database Access
1
2
Access to dateutil's bundled timezone database with metadata support, providing an alternative to system timezone data. Includes both modern and deprecated interfaces.
3
4
## Capabilities
5
6
### ZoneInfoFile Class
7
8
```python { .api }
9
class ZoneInfoFile:
10
def __init__(self, zonefile_stream=None):
11
"""
12
Interface to timezone database from tarball stream.
13
14
Parameters:
15
- zonefile_stream (file-like, optional): Stream containing zoneinfo tarball data
16
If None, creates empty ZoneInfoFile
17
"""
18
19
def get(self, name, default=None):
20
"""
21
Get timezone by name from the database.
22
23
Parameters:
24
- name (str): IANA timezone name (e.g., 'America/New_York')
25
- default: Value to return if timezone not found
26
27
Returns:
28
tzfile | default: Timezone object or default value
29
"""
30
31
# Attributes
32
zones: dict[str, tzfile] # Dictionary mapping timezone names to tzfile objects
33
metadata: dict | None # Database metadata (version, build info, etc.)
34
```
35
36
**Usage Examples:**
37
38
```python
39
from dateutil.zoneinfo import ZoneInfoFile, get_zonefile_instance
40
from datetime import datetime
41
42
# Use the default instance (recommended)
43
zif = get_zonefile_instance()
44
45
# Get specific timezone
46
ny_tz = zif.get('America/New_York')
47
if ny_tz:
48
dt = datetime(2023, 12, 25, 12, 0, tzinfo=ny_tz)
49
print(f"Time in NY: {dt}")
50
51
# Handle missing timezone gracefully
52
unknown_tz = zif.get('Invalid/Timezone', default=None)
53
if unknown_tz is None:
54
print("Timezone not found")
55
56
# Explore available timezones
57
print(f"Available timezones: {len(zif.zones)}")
58
print(f"Sample timezones: {list(zif.zones.keys())[:10]}")
59
60
# Check metadata
61
if zif.metadata:
62
print(f"Database version: {zif.metadata.get('version', 'unknown')}")
63
```
64
65
### Timezone Database Instance Management
66
67
```python { .api }
68
def get_zonefile_instance(new_instance=False):
69
"""
70
Get cached or new ZoneInfoFile instance using dateutil's bundled data.
71
72
Parameters:
73
- new_instance (bool): If True, create and cache new instance
74
If False, return existing cached instance
75
76
Returns:
77
ZoneInfoFile: Timezone database instance
78
"""
79
```
80
81
**Usage Examples:**
82
83
```python
84
from dateutil.zoneinfo import get_zonefile_instance
85
86
# Get default cached instance (efficient for repeated use)
87
zif1 = get_zonefile_instance()
88
zif2 = get_zonefile_instance()
89
print(f"Same instance: {zif1 is zif2}") # True
90
91
# Force new instance creation
92
zif_new = get_zonefile_instance(new_instance=True)
93
print(f"New instance: {zif1 is zif_new}") # False
94
95
# Subsequent calls return the new cached instance
96
zif3 = get_zonefile_instance()
97
print(f"Uses new cache: {zif3 is zif_new}") # True
98
```
99
100
### Internal Database Access
101
102
```python { .api }
103
def getzoneinfofile_stream():
104
"""
105
Get the raw zoneinfo tarball data as a stream.
106
107
Returns:
108
BytesIO | None: Stream containing dateutil's bundled zoneinfo tarball data,
109
or None if file cannot be read
110
111
Warning:
112
Internal function - prefer using get_zonefile_instance() for normal usage
113
"""
114
```
115
116
**Usage Examples:**
117
118
```python
119
from dateutil.zoneinfo import getzoneinfofile_stream, ZoneInfoFile
120
121
# Get raw zoneinfo stream (advanced usage)
122
stream = getzoneinfofile_stream()
123
if stream:
124
# Create custom ZoneInfoFile instance
125
custom_zif = ZoneInfoFile(stream)
126
print(f"Loaded {len(custom_zif.zones)} timezones")
127
else:
128
print("Could not access zoneinfo data")
129
```
130
131
### Custom ZoneInfo Loading
132
133
```python
134
from dateutil.zoneinfo import ZoneInfoFile
135
from io import BytesIO
136
137
# Load from custom tarball data (advanced usage)
138
with open('custom-zoneinfo.tar.gz', 'rb') as f:
139
custom_zif = ZoneInfoFile(f)
140
141
# Use custom timezone data
142
custom_tz = custom_zif.get('Custom/Timezone')
143
print(f"Custom zones available: {len(custom_zif.zones)}")
144
```
145
146
## Deprecated Interface
147
148
**Warning**: The following functions are deprecated as of dateutil 2.6 and will be removed in future versions. Use ZoneInfoFile class instead.
149
150
### Deprecated Functions
151
152
```python { .api }
153
def gettz(name):
154
"""
155
Get timezone from dateutil's bundled zoneinfo tarball.
156
157
DEPRECATED: Use get_zonefile_instance().get(name) instead.
158
159
Parameters:
160
- name (str): IANA timezone name
161
162
Returns:
163
tzfile | None: Timezone object or None if not found
164
165
Warnings:
166
DeprecationWarning: This function will be removed in future versions
167
"""
168
169
def gettz_db_metadata():
170
"""
171
Get zoneinfo database metadata.
172
173
DEPRECATED: Use get_zonefile_instance().metadata instead.
174
175
Returns:
176
dict | None: Database metadata dictionary
177
178
Warnings:
179
DeprecationWarning: This function will be removed in future versions
180
"""
181
```
182
183
**Migration Examples:**
184
185
```python
186
# OLD (deprecated) - will show deprecation warnings
187
from dateutil.zoneinfo import gettz, gettz_db_metadata
188
189
old_tz = gettz('America/New_York') # DeprecationWarning
190
old_metadata = gettz_db_metadata() # DeprecationWarning
191
192
# NEW (recommended) - no warnings
193
from dateutil.zoneinfo import get_zonefile_instance
194
195
zif = get_zonefile_instance()
196
new_tz = zif.get('America/New_York')
197
new_metadata = zif.metadata
198
```
199
200
## Advanced Usage Patterns
201
202
### Timezone Database Exploration
203
204
```python
205
from dateutil.zoneinfo import get_zonefile_instance
206
import json
207
208
def explore_timezone_database():
209
"""Explore the contents of the timezone database."""
210
zif = get_zonefile_instance()
211
212
# Basic statistics
213
total_zones = len(zif.zones)
214
print(f"Total timezone entries: {total_zones}")
215
216
# Group by continent
217
continents = {}
218
for zone_name in zif.zones.keys():
219
if '/' in zone_name:
220
continent = zone_name.split('/')[0]
221
continents[continent] = continents.get(continent, 0) + 1
222
223
print("\nTimezones by continent:")
224
for continent, count in sorted(continents.items()):
225
print(f" {continent}: {count}")
226
227
# Show metadata
228
if zif.metadata:
229
print(f"\nDatabase metadata:")
230
print(json.dumps(zif.metadata, indent=2))
231
232
return {
233
'total_zones': total_zones,
234
'continents': continents,
235
'metadata': zif.metadata
236
}
237
238
# Run exploration
239
db_info = explore_timezone_database()
240
```
241
242
### Timezone Validation
243
244
```python
245
from dateutil.zoneinfo import get_zonefile_instance
246
from dateutil.tz import gettz
247
248
def validate_timezone_name(tz_name):
249
"""
250
Validate timezone name against multiple sources.
251
252
Returns dict with validation results from different sources.
253
"""
254
results = {
255
'system_tz': None,
256
'dateutil_bundled': None,
257
'is_valid': False
258
}
259
260
# Check system timezone
261
system_tz = gettz(tz_name)
262
results['system_tz'] = system_tz is not None
263
264
# Check dateutil bundled data
265
zif = get_zonefile_instance()
266
bundled_tz = zif.get(tz_name)
267
results['dateutil_bundled'] = bundled_tz is not None
268
269
# Overall validity
270
results['is_valid'] = results['system_tz'] or results['dateutil_bundled']
271
272
return results
273
274
# Test various timezone names
275
test_timezones = [
276
'America/New_York',
277
'Europe/London',
278
'Invalid/Timezone',
279
'UTC',
280
'US/Eastern' # Legacy name
281
]
282
283
for tz_name in test_timezones:
284
validation = validate_timezone_name(tz_name)
285
print(f"{tz_name}: {validation}")
286
```
287
288
### Performance Comparison
289
290
```python
291
from dateutil.zoneinfo import get_zonefile_instance, gettz
292
from dateutil.tz import gettz as tz_gettz
293
import time
294
295
def benchmark_timezone_access():
296
"""Compare performance of different timezone access methods."""
297
timezone_names = [
298
'America/New_York', 'Europe/London', 'Asia/Tokyo',
299
'America/Los_Angeles', 'Europe/Paris', 'Asia/Shanghai'
300
]
301
302
# Benchmark system gettz
303
start = time.time()
304
for name in timezone_names * 100:
305
tz = tz_gettz(name)
306
system_time = time.time() - start
307
308
# Benchmark ZoneInfoFile (single instance)
309
zif = get_zonefile_instance()
310
start = time.time()
311
for name in timezone_names * 100:
312
tz = zif.get(name)
313
bundled_time = time.time() - start
314
315
# Benchmark deprecated gettz (with warnings suppressed)
316
import warnings
317
with warnings.catch_warnings():
318
warnings.simplefilter("ignore")
319
start = time.time()
320
for name in timezone_names * 100:
321
tz = gettz(name) # Deprecated function
322
deprecated_time = time.time() - start
323
324
print("Timezone access performance (600 lookups):")
325
print(f"System gettz(): {system_time:.4f}s")
326
print(f"ZoneInfoFile.get(): {bundled_time:.4f}s")
327
print(f"Deprecated gettz(): {deprecated_time:.4f}s")
328
329
benchmark_timezone_access()
330
```
331
332
### Database Comparison Tool
333
334
```python
335
from dateutil.zoneinfo import get_zonefile_instance
336
from dateutil.tz import gettz
337
from datetime import datetime
338
339
def compare_timezone_implementations(tz_name, test_datetime):
340
"""Compare system vs bundled timezone implementations."""
341
342
# Get timezone from both sources
343
system_tz = gettz(tz_name)
344
345
zif = get_zonefile_instance()
346
bundled_tz = zif.get(tz_name)
347
348
if not system_tz or not bundled_tz:
349
return f"Timezone {tz_name} not available in one or both sources"
350
351
# Create datetime with each timezone
352
system_dt = test_datetime.replace(tzinfo=system_tz)
353
bundled_dt = test_datetime.replace(tzinfo=bundled_tz)
354
355
# Compare properties
356
comparison = {
357
'timezone_name': tz_name,
358
'test_datetime': test_datetime,
359
'system': {
360
'utc_offset': system_tz.utcoffset(test_datetime),
361
'dst_offset': system_tz.dst(test_datetime),
362
'tzname': system_tz.tzname(test_datetime)
363
},
364
'bundled': {
365
'utc_offset': bundled_tz.utcoffset(test_datetime),
366
'dst_offset': bundled_tz.dst(test_datetime),
367
'tzname': bundled_tz.tzname(test_datetime)
368
}
369
}
370
371
# Check for differences
372
comparison['differences'] = []
373
for prop in ['utc_offset', 'dst_offset', 'tzname']:
374
if comparison['system'][prop] != comparison['bundled'][prop]:
375
comparison['differences'].append(prop)
376
377
return comparison
378
379
# Test with specific datetime
380
test_dt = datetime(2023, 7, 15, 12, 0) # Summer time
381
result = compare_timezone_implementations('America/New_York', test_dt)
382
print(f"Comparison results: {result}")
383
```
384
385
## Constants
386
387
```python { .api }
388
ZONEFILENAME = "dateutil-zoneinfo.tar.gz" # Default zoneinfo tarball filename
389
METADATA_FN = 'METADATA' # Metadata filename within tarball
390
```
391
392
## Types
393
394
```python { .api }
395
from dateutil.tz import tzfile
396
from typing import BinaryIO
397
398
class ZoneInfoFile:
399
zones: dict[str, tzfile]
400
metadata: dict | None
401
402
def get(self, name: str, default=None) -> tzfile | None: ...
403
404
# Function return types
405
ZoneInfoInstance = ZoneInfoFile
406
TzFileResult = tzfile | None
407
MetadataResult = dict | None
408
409
# File stream types for custom loading
410
ZoneInfoStream = BinaryIO | None
411
```