Timezone can bring a lot headaches when programming.
Luckly our peers have written many great libraries that we can use.
Here is a tutorial on how to deal with timezone in python and Django.
pytc is a timezone definition package, and it is very powerful dealing with tiemzones.
you can install it through pip
:
pip install pytz # in python environment
from datetime import datetime
from pytz import timezone
date_str = "2009-05-05 22:28:15"
datetime_obj = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
datetime_obj_utc = datetime_obj.replace(tzinfo=timezone('UTC'))
print(datetime_obj_utc.strftime("%Y-%m-%d %H:%M:%S %Z%z"))
ATTENTION: datetime.replace()
does not handle daylight savings time correctly.
The correct way is to use timezone.localize()
from datetime import datetime
from pytz import timezone
date_str = "2014-05-28 22:28:15"
datetime_obj_naive = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
# Wrong way!
datetime_obj_pacific = datetime_obj_naive.replace(tzinfo=timezone('US/Pacific'))
print(datetime_obj_pacific.strftime("%Y-%m-%d %H:%M:%S %Z%z"))
# Right way!
datetime_obj_pacific = timezone('US/Pacific').localize(datetime_obj_naive)
print(datetime_obj_pacific.strftime("%Y-%m-%d %H:%M:%S %Z%z"))
Use datetime.astimezone(tz)
to convert timezone
from datetime import datetime
from pytz import timezone
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
# Current time in UTC
now_utc = datetime.now(timezone('UTC'))
print(now_utc.strftime(fmt))
# Convert to US/Pacific time zone
now_pacific = now_utc.astimezone(timezone('US/Pacific'))
print(now_pacific.strftime(fmt))
# Convert to Europe/Berlin time zone
now_berlin = now_pacific.astimezone(timezone('Europe/Berlin'))
print(now_berlin.strftime(fmt))
There are 593 time zones included in the current pytz version.
# Check pytz version
import pytz
print(pytz.__version__)
# Check how many timezonmes
from pytz import all_timezones
print(len(all_timezones))
# Print all the timezone in US
for zone in all_timezones:
if 'US' in zone:
print(zone)
NOTE: all the above content is referenced from Converting time zones for datetime objects in Python - SaltyCrane Blog with slight modification
Windows Registry
# A big dictionary mapping windows registry timezone format
# to the format readable by python
TIMEZONES = {
"AUSCENTRALSTANDARDTIME": "Australia/Darwin",
"AUSEASTERNSTANDARDTIME": "Australia/Sydney",
"AFGHANISTANSTANDARDTIME": "Asia/Kabul",
"ALASKANSTANDARDTIME": "America/Anchorage",
"ARABSTANDARDTIME": "Asia/Riyadh",
"ARABIANSTANDARDTIME": "Asia/Dubai",
"ARABICSTANDARDTIME": "Asia/Baghdad",
"ARGENTINASTANDARDTIME": "America/Buenos_Aires",
"ATLANTICSTANDARDTIME": "America/Halifax",
"AZERBAIJANSTANDARDTIME": "Asia/Baku",
"AZORESSTANDARDTIME": "Atlantic/Azores",
"BAHIASTANDARDTIME": "America/Bahia",
"BANGLADESHSTANDARDTIME": "Asia/Dhaka",
"BELARUSSTANDARDTIME": "Europe/Minsk",
"CANADACENTRALSTANDARDTIME": "America/Regina",
"CAPEVERDESTANDARDTIME": "Atlantic/Cape_Verde",
"CAUCASUSSTANDARDTIME": "Asia/Yerevan",
"CENAUSTRALIASTANDARDTIME": "Australia/Adelaide",
"CENTRALAMERICASTANDARDTIME": "America/Guatemala",
"CENTRALASIASTANDARDTIME": "Asia/Almaty",
"CENTRALBRAZILIANSTANDARDTIME": "America/Cuiaba",
"CENTRALEUROPESTANDARDTIME": "Europe/Budapest",
"CENTRALEUROPEANSTANDARDTIME": "Europe/Warsaw",
"CENTRALPACIFICSTANDARDTIME": "Pacific/Guadalcanal",
"CENTRALSTANDARDTIME": "America/Chicago",
"CENTRALSTANDARDTIME(MEXICO)": "America/Mexico_City",
"CHINASTANDARDTIME": "Asia/Shanghai",
"DATELINESTANDARDTIME": "Etc/GMT+12",
"EAFRICASTANDARDTIME": "Africa/Nairobi",
"EAUSTRALIASTANDARDTIME": "Australia/Brisbane",
"EEUROPESTANDARDTIME": "Europe/Chisinau",
"ESOUTHAMERICASTANDARDTIME": "America/Sao_Paulo",
"EASTERNSTANDARDTIME": "America/New_York",
"EGYPTSTANDARDTIME": "Africa/Cairo",
"EKATERINBURGSTANDARDTIME": "Asia/Yekaterinburg",
"FLESTANDARDTIME": "Europe/Kiev",
"FIJISTANDARDTIME": "Pacific/Fiji",
"GMTSTANDARDTIME": "Europe/London",
"GTBSTANDARDTIME": "Europe/Bucharest",
"GEORGIANSTANDARDTIME": "Asia/Tbilisi",
"GREENLANDSTANDARDTIME": "America/Godthab",
"GREENWICHSTANDARDTIME": "Atlantic/Reykjavik",
"HAWAIIANSTANDARDTIME": "Pacific/Honolulu",
"INDIASTANDARDTIME": "Asia/Calcutta",
"IRANSTANDARDTIME": "Asia/Tehran",
"ISRAELSTANDARDTIME": "Asia/Jerusalem",
"JORDANSTANDARDTIME": "Asia/Amman",
"KALININGRADSTANDARDTIME": "Europe/Kaliningrad",
"KAMCHATKASTANDARDTIME": "Pacific/Fiji", # this timezone is UTC+12
"KOREASTANDARDTIME": "Asia/Seoul",
"LIBYASTANDARDTIME": "Africa/Tripoli",
"LINEISLANDSSTANDARDTIME": "Pacific/Kiritimati",
"MAGADANSTANDARDTIME": "Asia/Magadan",
"MAURITIUSSTANDARDTIME": "Indian/Mauritius",
"MIDATLANTICSTANDARDTIME": "Etc/GMT+2", # this timezone is UTC-2
"MIDDLEEASTSTANDARDTIME": "Asia/Beirut",
"MONTEVIDEOSTANDARDTIME": "America/Montevideo",
"MOROCCOSTANDARDTIME": "Africa/Casablanca",
"MOUNTAINSTANDARDTIME": "America/Denver",
"MOUNTAINSTANDARDTIME(MEXICO)": "America/Chihuahua",
"MYANMARSTANDARDTIME": "Asia/Rangoon",
"NCENTRALASIASTANDARDTIME": "Asia/Novosibirsk",
"NAMIBIASTANDARDTIME": "Africa/Windhoek",
"NEPALSTANDARDTIME": "Asia/Katmandu",
"NEWZEALANDSTANDARDTIME": "Pacific/Auckland",
"NEWFOUNDLANDSTANDARDTIME": "America/St_Johns",
"NORTHASIAEASTSTANDARDTIME": "Asia/Irkutsk",
"NORTHASIASTANDARDTIME": "Asia/Krasnoyarsk",
"PACIFICSASTANDARDTIME": "America/Santiago",
"PACIFICSTANDARDTIME": "America/Los_Angeles",
"PACIFICSTANDARDTIME(MEXICO)": "America/Tijuana",
"PAKISTANSTANDARDTIME": "Asia/Karachi",
"PARAGUAYSTANDARDTIME": "America/Asuncion",
"ROMANCESTANDARDTIME": "Europe/Paris",
"RUSSIATIMEZONE10": "Asia/Srednekolymsk",
"RUSSIATIMEZONE11": "Asia/Kamchatka",
"RUSSIATIMEZONE3": "Europe/Samara",
"RUSSIANSTANDARDTIME": "Europe/Moscow",
"SAEASTERNSTANDARDTIME": "America/Cayenne",
"SAPACIFICSTANDARDTIME": "America/Bogota",
"SAWESTERNSTANDARDTIME": "America/La_Paz",
"SEASIASTANDARDTIME": "Asia/Bangkok",
"SAMOASTANDARDTIME": "Pacific/Apia",
"SINGAPORESTANDARDTIME": "Asia/Singapore",
"SOUTHAFRICASTANDARDTIME": "Africa/Johannesburg",
"SRILANKASTANDARDTIME": "Asia/Colombo",
"SYRIASTANDARDTIME": "Asia/Damascus",
"TAIPEISTANDARDTIME": "Asia/Taipei",
"TASMANIASTANDARDTIME": "Australia/Hobart",
"TOKYOSTANDARDTIME": "Asia/Tokyo",
"TONGASTANDARDTIME": "Pacific/Tongatapu",
"TURKEYSTANDARDTIME": "Europe/Istanbul",
"USEASTERNSTANDARDTIME": "America/Indianapolis",
"USMOUNTAINSTANDARDTIME": "America/Phoenix",
"UTC": "Etc/GMT",
"UTC+12": "Etc/GMT-12",
"UTC02": "Etc/GMT+2",
"UTC11": "Etc/GMT+11",
"ULAANBAATARSTANDARDTIME": "Asia/Ulaanbaatar",
"VENEZUELASTANDARDTIME": "America/Caracas",
"VLADIVOSTOKSTANDARDTIME": "Asia/Vladivostok",
"WAUSTRALIASTANDARDTIME": "Australia/Perth",
"WCENTRALAFRICASTANDARDTIME": "Africa/Lagos",
"WEUROPESTANDARDTIME": "Europe/Berlin",
"WESTASIASTANDARDTIME": "Asia/Tashkent",
"WESTPACIFICSTANDARDTIME": "Pacific/Port_Moresby",
"YAKUTSKSTANDARDTIME": "Asia/Yakutsk",
}
from datetime import timedelta
from datetime import timezone
from pytz import timezone as tz
from pytz import all_timezones_set
raw_date = "2018-09-17+06:30" # test timezone
# Parse the raw date string
utc_offset = timedelta(
hours=int(raw_date[-5:-3]), minutes=int(raw_date[-2:])
)
# Use the first timezone info returned
_timezone_info = next(
_tz.zone
for _tz in map(tz, all_timezones_set)
if datetime.now().astimezone(_tz).utcoffset() == utc_offset
)
print("Processed timezone is:", _timezone_info)
# Get the correct timezone with raw date
date_without_timezone = datetime.strptime(raw_date[:10], "%Y-%m-%d")
print(date_without_timezone)
date_with_timezone = tz(_timezone_info).localize(date_without_timezone)
print(date_with_timezone, type(date_with_timezone))
Lets look closer at these two dates
date_without_timezone
date_with_timezone