diff --git a/lib/nexrad/storm.py b/lib/nexrad/storm.py index 70d99b6..e9128b9 100644 --- a/lib/nexrad/storm.py +++ b/lib/nexrad/storm.py @@ -1,3 +1,4 @@ +import re import gzip import csv import datetime @@ -19,16 +20,58 @@ def time_from_str(time: str): int(time[size-2:]) % 60 ) -def timestamp_from_parts(yearmonth: str, day: str, time: str) -> datetime.datetime: +def timestamp_from_parts(tz: datetime.tzinfo, yearmonth: str, day: str, time: str) -> datetime.datetime: hour, minute = time_from_str(time) return datetime.datetime( + tzinfo = tz, year = int(yearmonth[0:4]), month = int(yearmonth[4:6]), day = int(day), hour = hour, minute = minute - ) + ).astimezone(datetime.UTC) + +TIMEZONES = { + '-12': datetime.timezone(datetime.timedelta(hours=-12)), + '-11': datetime.timezone(datetime.timedelta(hours=-11)), + '-10': datetime.timezone(datetime.timedelta(hours=-10)), + '-9': datetime.timezone(datetime.timedelta(hours=-9)), + '-8': datetime.timezone(datetime.timedelta(hours=-8)), + '-7': datetime.timezone(datetime.timedelta(hours=-7)), + '-6': datetime.timezone(datetime.timedelta(hours=-6)), + '-5': datetime.timezone(datetime.timedelta(hours=-5)), + '-4': datetime.timezone(datetime.timedelta(hours=-4)), + '-3': datetime.timezone(datetime.timedelta(hours=-3)), + '-2': datetime.timezone(datetime.timedelta(hours=-2)), + '-1': datetime.timezone(datetime.timedelta(hours=-1)), + '-0': datetime.UTC, + '+0': datetime.UTC, + '+1': datetime.timezone(datetime.timedelta(hours=1)), + '+2': datetime.timezone(datetime.timedelta(hours=2)), + '+3': datetime.timezone(datetime.timedelta(hours=3)), + '+4': datetime.timezone(datetime.timedelta(hours=4)), + '+5': datetime.timezone(datetime.timedelta(hours=5)), + '+6': datetime.timezone(datetime.timedelta(hours=6)), + '+7': datetime.timezone(datetime.timedelta(hours=7)), + '+8': datetime.timezone(datetime.timedelta(hours=8)), + '+9': datetime.timezone(datetime.timedelta(hours=9)), + '+10': datetime.timezone(datetime.timedelta(hours=10)), + '+11': datetime.timezone(datetime.timedelta(hours=11)), + '+12': datetime.timezone(datetime.timedelta(hours=12)), +} + +TIMEZONE_RE = re.compile(r'^(?:[A-Z]+)([+\-]\d)$') + +def timezone_from_str(text: str) -> datetime.timezone: + match = TIMEZONE_RE.match(text) + + if match is None: + return datetime.UTC + + tz = TIMEZONES.get(match[1]) + + return datetime.UTC if tz is None else tz def coord_from_str(text_lat: str, text_lon: str): lat = 0.0 if text_lat == '' else float(text_lat) @@ -60,8 +103,10 @@ class StormReport(): def from_csv_row(row: dict): report = StormReport() - report.timestamp_start = timestamp_from_parts(row['BEGIN_YEARMONTH'], row['BEGIN_DAY'], row['BEGIN_TIME']) - report.timestamp_end = timestamp_from_parts(row['END_YEARMONTH'], row['END_DAY'], row['END_TIME']) + tz = timezone_from_str(row['CZ_TIMEZONE']) + + report.timestamp_start = timestamp_from_parts(tz, row['BEGIN_YEARMONTH'], row['BEGIN_DAY'], row['BEGIN_TIME']) + report.timestamp_end = timestamp_from_parts(tz, row['END_YEARMONTH'], row['END_DAY'], row['END_TIME']) report.episode_id = int(row['EPISODE_ID']) report.event_id = int(row['EVENT_ID']) report.state = row['STATE']