Pytz: return Olson time zone name only from GMT GMT

I have an outdated application that I will need to supplement with some data. We currently have a DB table that stores the United States (and its territories) postal codes, as well as GMT GMT and a flag indicating whether this Zipcode uses daylight saving time. This has been downloaded from some free provider that I cannot find now.

Now I have to supplement this table with the full Olson name (for example, America/New York) of each zip code, because this is apparently the only good way to convert the given date / time stored in the database, as local for this customer, to UTC aware datetime.

Here's a look at the table:

zip    state  city          lat      lon       gmt  dst 
00605  PR     AGUADILLA     18.4372  -67.1593  -4   f
02830  RI     HARRISVILLE   41.9782  -71.7679  -5   t
99503  AK     ANCHORAGE     61.1895  -149.874  -9   t

In another related table Purchases, I have a column postres timestamp without tzthat currently contains something like 2014-05-27T15:54:26that represents the local purchase time in this zip code. (ignore the stupidity of deleting timezone information when storing these localized timestamps in the database)

The big question is:

How to create normalized UTC timefrom this row timestampfor each zipcode in a table zipcode? This assumes that the timestamp was written to the database as local to each row of the example in the table zipcode.

For example, manually looking at the Olson time zone names for each item in the example table, I come to the following:

>>> timestring = '2014-05-27T15:54:26'
>>> dt_naive = datetime.strptime(timestring, '%Y-%m-%dT%H:%M:%S')

>>> # First example - Puerto Rico (no DST since 1945)
>>> print pytz.utc.normalize(pytz.timezone('America/Puerto_Rico').localize(dt_naive))
2014-05-27 19:54:26+00:00

# Second example - Road Island (At that timestamp, UTC Offset was same as PR because of DST)
>>> print pytz.utc.normalize(pytz.timezone('US/Eastern').localize(dt_naive))
>>> 2014-05-27 19:54:26+00:00

# Third Example - Anchorage, AK (AKDT at timestamp)
>>> print pytz.utc.normalize(pytz.timezone('America/Anchorage').localize(dt_naive))
2014-05-27 23:54:26+00:00

, zipcode, zipcode → . , , "EST" . , , ( ) olson . :

zipcode_olson_lookup = {
    ('PR', 'f', 'AST'): 'America/Puerto_Rico',
    ('AK', 'f', 'AKDT',): 'America/Anchorage',
    ('AK', 't', 'AKT',): 'America/Anchorage',
    ...
}

!

+3
1

UTC ( , ):

#!/usr/bin/env python
from datetime import datetime, timedelta
import pytz # $ pip install pytz

input_utc_offset = timedelta(hours=-4)
timezone_ids = set()
now = datetime.now(pytz.utc) #XXX: use date that corresponds to input_utc_offset instead!
for tz in map(pytz.timezone, pytz.all_timezones_set):
    dt = now.astimezone(tz)    
    tzinfos = getattr(tz, '_tzinfos',
                      [(dt.tzname(), dt.dst(), dt.utcoffset())])        
    if any(utc_offset == input_utc_offset for utc_offset, _, _ in tzinfos):
        # match timezones that have/had/will have the same utc offset 
        timezone_ids.add(tz.zone)
print(timezone_ids)

{'America/Anguilla',
 'America/Antigua',
 'America/Argentina/Buenos_Aires',
 ...,
 'Cuba',
 'EST5EDT',
 'Jamaica',
 'US/East-Indiana',
 'US/Eastern',
 'US/Michigan'}

, pytz.country_timezones['us'], : 'America/Puerto_Rico'.


(, ); : -:

#!/usr/bin/env python
from geopy import geocoders # pip install "geopy[timezone]"

g = geocoders.GoogleV3()
for coords in [(18.4372,  -67.159), (41.9782,  -71.7679), (61.1895,  -149.874)]:
    print(g.timezone(coords).zone)

America/Puerto_Rico
America/New_York
America/Anchorage

: , , . is_dst=None .localize() .

tz utc , .. UTC ( ).

+2

Source: https://habr.com/ru/post/1705835/


All Articles