Merge pull request #145 from bobloy/fifo_develop

FIFO add timezone support for cron
pull/146/head
bobloy 4 years ago committed by GitHub
commit 5940ab1af9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,9 +1,10 @@
from datetime import datetime from datetime import datetime, tzinfo
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.cron import CronTrigger
from dateutil import parser from dateutil import parser
from discord.ext.commands import BadArgument, Converter from discord.ext.commands import BadArgument, Converter
from pytz import timezone
from fifo.timezones import assemble_timezones from fifo.timezones import assemble_timezones
@ -12,6 +13,18 @@ if TYPE_CHECKING:
CronConverter = str CronConverter = str
else: else:
class TimezoneConverter(Converter):
async def convert(self, ctx, argument) -> tzinfo:
tzinfos = assemble_timezones()
if argument.upper() in tzinfos:
return tzinfos[argument.upper()]
timez = timezone(argument)
if timez is not None:
return timez
raise BadArgument()
class DatetimeConverter(Converter): class DatetimeConverter(Converter):
async def convert(self, ctx, argument) -> datetime: async def convert(self, ctx, argument) -> datetime:
dt = parser.parse(argument, fuzzy=True, tzinfos=assemble_timezones()) dt = parser.parse(argument, fuzzy=True, tzinfos=assemble_timezones())

@ -1,5 +1,5 @@
import logging import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta, tzinfo
from typing import Optional, Union from typing import Optional, Union
import discord import discord
@ -12,7 +12,7 @@ from redbot.core.bot import Red
from redbot.core.commands import TimedeltaConverter from redbot.core.commands import TimedeltaConverter
from redbot.core.utils.chat_formatting import pagify from redbot.core.utils.chat_formatting import pagify
from .datetime_cron_converters import CronConverter, DatetimeConverter from .datetime_cron_converters import CronConverter, DatetimeConverter, TimezoneConverter
from .task import Task from .task import Task
schedule_log = logging.getLogger("red.fox_v3.fifo.scheduler") schedule_log = logging.getLogger("red.fox_v3.fifo.scheduler")
@ -58,6 +58,8 @@ class FIFO(commands.Cog):
self.scheduler = None self.scheduler = None
self.jobstore = None self.jobstore = None
self.tz_cog = None
async def red_delete_data_for_user(self, **kwargs): async def red_delete_data_for_user(self, **kwargs):
"""Nothing to delete""" """Nothing to delete"""
return return
@ -132,6 +134,24 @@ class FIFO(commands.Cog):
async def _remove_job(self, task: Task): async def _remove_job(self, task: Task):
return self.scheduler.remove_job(job_id=_assemble_job_id(task.name, task.guild_id)) return self.scheduler.remove_job(job_id=_assemble_job_id(task.name, task.guild_id))
async def _get_tz(self, user: Union[discord.User, discord.Member]) -> Union[None, tzinfo]:
if self.tz_cog is None:
self.tz_cog = self.bot.get_cog("Timezone")
if self.tz_cog is None:
self.tz_cog = False # only try once to get the timezone cog
if not self.tz_cog:
return None
try:
usertime = await self.tz_cog.config.user(user).usertime()
except AttributeError:
return None
if usertime:
return await TimezoneConverter().convert(None, usertime)
else:
return None
@checks.is_owner() @checks.is_owner()
@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
@ -140,7 +160,7 @@ class FIFO(commands.Cog):
self.scheduler.remove_all_jobs() self.scheduler.remove_all_jobs()
await self.config.guild(ctx.guild).tasks.clear() await self.config.guild(ctx.guild).tasks.clear()
await self.config.jobs.clear() await self.config.jobs.clear()
await self.config.jobs_index.clear() # await self.config.jobs_index.clear()
await ctx.tick() await ctx.tick()
@checks.is_owner() # Will be reduced when I figure out permissions later @checks.is_owner() # Will be reduced when I figure out permissions later
@ -411,7 +431,7 @@ class FIFO(commands.Cog):
job: Job = await self._process_task(task) job: Job = await self._process_task(task)
delta_from_now: timedelta = job.next_run_time - datetime.now(job.next_run_time.tzinfo) delta_from_now: timedelta = job.next_run_time - datetime.now(job.next_run_time.tzinfo)
await ctx.maybe_send_embed( await ctx.maybe_send_embed(
f"Task `{task_name}` added interval of {interval_str} to its scheduled runtimes\n" f"Task `{task_name}` added interval of {interval_str} to its scheduled runtimes\n\n"
f"Next run time: {job.next_run_time} ({delta_from_now.total_seconds()} seconds)" f"Next run time: {job.next_run_time} ({delta_from_now.total_seconds()} seconds)"
) )
@ -432,7 +452,9 @@ class FIFO(commands.Cog):
) )
return return
result = await task.add_trigger("date", datetime_str) maybe_tz = await self._get_tz(ctx.author)
result = await task.add_trigger("date", datetime_str, maybe_tz)
if not result: if not result:
await ctx.maybe_send_embed( await ctx.maybe_send_embed(
"Failed to add a date trigger to this task, see console for logs" "Failed to add a date trigger to this task, see console for logs"
@ -449,7 +471,12 @@ class FIFO(commands.Cog):
@fifo_trigger.command(name="cron") @fifo_trigger.command(name="cron")
async def fifo_trigger_cron( async def fifo_trigger_cron(
self, ctx: commands.Context, task_name: str, *, cron_str: CronConverter self,
ctx: commands.Context,
task_name: str,
optional_tz: Optional[TimezoneConverter] = None,
*,
cron_str: CronConverter,
): ):
""" """
Add a cron "time of day" trigger to the specified task Add a cron "time of day" trigger to the specified task
@ -465,7 +492,10 @@ class FIFO(commands.Cog):
) )
return return
result = await task.add_trigger("cron", cron_str) if optional_tz is None:
optional_tz = await self._get_tz(ctx.author) # might still be None
result = await task.add_trigger("cron", cron_str, optional_tz)
if not result: if not result:
await ctx.maybe_send_embed( await ctx.maybe_send_embed(
"Failed to add a cron trigger to this task, see console for logs" "Failed to add a cron trigger to this task, see console for logs"

@ -3,14 +3,14 @@
"Bobloy" "Bobloy"
], ],
"min_bot_version": "3.4.0", "min_bot_version": "3.4.0",
"description": "[ALPHA] Schedule commands to be run at certain times or intervals", "description": "[BETA] Schedule commands to be run at certain times or intervals",
"hidden": false, "hidden": false,
"install_msg": "Thank you for installing FIFO.\nGet started with `[p]load fifo`, then `[p]help FIFO`", "install_msg": "Thank you for installing FIFO.\nGet started with `[p]load fifo`, then `[p]help FIFO`",
"short": "[ALPHA] Schedule commands to be run at certain times or intervals", "short": "[BETA] Schedule commands to be run at certain times or intervals",
"end_user_data_statement": "This cog does not store any End User Data", "end_user_data_statement": "This cog does not store any End User Data",
"requirements": [ "requirements": [
"apscheduler", "apscheduler",
"python-dateutil" "pytz"
], ],
"tags": [ "tags": [
"bobloy", "bobloy",
@ -24,6 +24,7 @@
"date", "date",
"datetime", "datetime",
"time", "time",
"calendar" "calendar",
"timezone"
] ]
} }

@ -9,6 +9,7 @@ from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.date import DateTrigger from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.interval import IntervalTrigger
from discord.utils import time_snowflake from discord.utils import time_snowflake
from pytz import timezone
from redbot.core import Config, commands from redbot.core import Config, commands
from redbot.core.bot import Red from redbot.core.bot import Red
@ -25,10 +26,10 @@ def get_trigger(data):
return IntervalTrigger(days=parsed_time.days, seconds=parsed_time.seconds) return IntervalTrigger(days=parsed_time.days, seconds=parsed_time.seconds)
if data["type"] == "date": if data["type"] == "date":
return DateTrigger(data["time_data"]) return DateTrigger(data["time_data"], timezone=data["tzinfo"])
if data["type"] == "cron": if data["type"] == "cron":
return CronTrigger.from_crontab(data["time_data"]) return CronTrigger.from_crontab(data["time_data"], timezone=data["tzinfo"])
return False return False
@ -70,6 +71,7 @@ class Task:
default_trigger = { default_trigger = {
"type": "", "type": "",
"time_data": None, # Used for Interval and Date Triggers "time_data": None, # Used for Interval and Date Triggers
"tzinfo": None,
} }
def __init__( def __init__(
@ -99,7 +101,13 @@ class Task:
if t["type"] == "date": # Convert into datetime if t["type"] == "date": # Convert into datetime
dt: datetime = t["time_data"] dt: datetime = t["time_data"]
triggers.append({"type": t["type"], "time_data": dt.isoformat()}) triggers.append(
{
"type": t["type"],
"time_data": dt.isoformat(),
"tzinfo": getattr(t["tzinfo"], "zone", None),
}
)
# triggers.append( # triggers.append(
# { # {
# "type": t["type"], # "type": t["type"],
@ -117,9 +125,18 @@ class Task:
continue continue
if t["type"] == "cron": if t["type"] == "cron":
if t["tzinfo"] is None:
triggers.append(t) # already a string, nothing to do triggers.append(t) # already a string, nothing to do
else:
triggers.append(
{
"type": t["type"],
"time_data": t["time_data"],
"tzinfo": getattr(t["tzinfo"], "zone", None),
}
)
continue continue
raise NotImplemented raise NotImplemented
return triggers return triggers
@ -128,18 +145,27 @@ class Task:
if not self.data or not self.data.get("triggers", None): if not self.data or not self.data.get("triggers", None):
return return
for n, t in enumerate(self.data["triggers"]): for t in self.data["triggers"]:
# Backwards compatibility
if "tzinfo" not in t:
t["tzinfo"] = None
# First decode timezone if there is one
if t["tzinfo"] is not None:
t["tzinfo"] = timezone(t["tzinfo"])
if t["type"] == "interval": # Convert into timedelta if t["type"] == "interval": # Convert into timedelta
self.data["triggers"][n]["time_data"] = timedelta(**t["time_data"]) t["time_data"] = timedelta(**t["time_data"])
continue continue
if t["type"] == "date": # Convert into datetime if t["type"] == "date": # Convert into datetime
# self.data["triggers"][n]["time_data"] = datetime(**t["time_data"]) # self.data["triggers"][n]["time_data"] = datetime(**t["time_data"])
self.data["triggers"][n]["time_data"] = datetime.fromisoformat(t["time_data"]) t["time_data"] = datetime.fromisoformat(t["time_data"])
continue continue
if t["type"] == "cron": if t["type"] == "cron":
continue # already a string continue # already a string
raise NotImplemented raise NotImplemented
# async def load_from_data(self, data: Dict): # async def load_from_data(self, data: Dict):
@ -300,8 +326,16 @@ class Task:
self.data["command_str"] = command_str self.data["command_str"] = command_str
return True return True
async def add_trigger(self, param, parsed_time: Union[timedelta, datetime, str]): async def add_trigger(
trigger_data = {"type": param, "time_data": parsed_time} self, param, parsed_time: Union[timedelta, datetime, str], timezone=None
):
# TODO: Save timezone separately for cron and date triggers
trigger_data = self.default_trigger.copy()
trigger_data["type"] = param
trigger_data["time_data"] = parsed_time
if timezone is not None:
trigger_data["tzinfo"] = timezone
if not get_trigger(trigger_data): if not get_trigger(trigger_data):
return False return False

@ -4,7 +4,8 @@ Timezone information for the dateutil parser
All credit to https://github.com/prefrontal/dateutil-parser-timezones All credit to https://github.com/prefrontal/dateutil-parser-timezones
""" """
from dateutil.tz import gettz # from dateutil.tz import gettz
from pytz import timezone
def assemble_timezones(): def assemble_timezones():
@ -14,182 +15,182 @@ def assemble_timezones():
""" """
timezones = {} timezones = {}
timezones['ACDT'] = gettz('Australia/Darwin') # Australian Central Daylight Savings Time (UTC+10:30) timezones['ACDT'] = timezone('Australia/Darwin') # Australian Central Daylight Savings Time (UTC+10:30)
timezones['ACST'] = gettz('Australia/Darwin') # Australian Central Standard Time (UTC+09:30) timezones['ACST'] = timezone('Australia/Darwin') # Australian Central Standard Time (UTC+09:30)
timezones['ACT'] = gettz('Brazil/Acre') # Acre Time (UTC05) timezones['ACT'] = timezone('Brazil/Acre') # Acre Time (UTC05)
timezones['ADT'] = gettz('America/Halifax') # Atlantic Daylight Time (UTC03) timezones['ADT'] = timezone('America/Halifax') # Atlantic Daylight Time (UTC03)
timezones['AEDT'] = gettz('Australia/Sydney') # Australian Eastern Daylight Savings Time (UTC+11) timezones['AEDT'] = timezone('Australia/Sydney') # Australian Eastern Daylight Savings Time (UTC+11)
timezones['AEST'] = gettz('Australia/Sydney') # Australian Eastern Standard Time (UTC+10) timezones['AEST'] = timezone('Australia/Sydney') # Australian Eastern Standard Time (UTC+10)
timezones['AFT'] = gettz('Asia/Kabul') # Afghanistan Time (UTC+04:30) timezones['AFT'] = timezone('Asia/Kabul') # Afghanistan Time (UTC+04:30)
timezones['AKDT'] = gettz('America/Juneau') # Alaska Daylight Time (UTC08) timezones['AKDT'] = timezone('America/Juneau') # Alaska Daylight Time (UTC08)
timezones['AKST'] = gettz('America/Juneau') # Alaska Standard Time (UTC09) timezones['AKST'] = timezone('America/Juneau') # Alaska Standard Time (UTC09)
timezones['AMST'] = gettz('America/Manaus') # Amazon Summer Time (Brazil)[1] (UTC03) timezones['AMST'] = timezone('America/Manaus') # Amazon Summer Time (Brazil)[1] (UTC03)
timezones['AMT'] = gettz('America/Manaus') # Amazon Time (Brazil)[2] (UTC04) timezones['AMT'] = timezone('America/Manaus') # Amazon Time (Brazil)[2] (UTC04)
timezones['ART'] = gettz('America/Cordoba') # Argentina Time (UTC03) timezones['ART'] = timezone('America/Cordoba') # Argentina Time (UTC03)
timezones['AST'] = gettz('Asia/Riyadh') # Arabia Standard Time (UTC+03) timezones['AST'] = timezone('Asia/Riyadh') # Arabia Standard Time (UTC+03)
timezones['AWST'] = gettz('Australia/Perth') # Australian Western Standard Time (UTC+08) timezones['AWST'] = timezone('Australia/Perth') # Australian Western Standard Time (UTC+08)
timezones['AZOST'] = gettz('Atlantic/Azores') # Azores Summer Time (UTC±00) timezones['AZOST'] = timezone('Atlantic/Azores') # Azores Summer Time (UTC±00)
timezones['AZOT'] = gettz('Atlantic/Azores') # Azores Standard Time (UTC01) timezones['AZOT'] = timezone('Atlantic/Azores') # Azores Standard Time (UTC01)
timezones['AZT'] = gettz('Asia/Baku') # Azerbaijan Time (UTC+04) timezones['AZT'] = timezone('Asia/Baku') # Azerbaijan Time (UTC+04)
timezones['BDT'] = gettz('Asia/Brunei') # Brunei Time (UTC+08) timezones['BDT'] = timezone('Asia/Brunei') # Brunei Time (UTC+08)
timezones['BIOT'] = gettz('Etc/GMT+6') # British Indian Ocean Time (UTC+06) timezones['BIOT'] = timezone('Etc/GMT+6') # British Indian Ocean Time (UTC+06)
timezones['BIT'] = gettz('Pacific/Funafuti') # Baker Island Time (UTC12) timezones['BIT'] = timezone('Pacific/Funafuti') # Baker Island Time (UTC12)
timezones['BOT'] = gettz('America/La_Paz') # Bolivia Time (UTC04) timezones['BOT'] = timezone('America/La_Paz') # Bolivia Time (UTC04)
timezones['BRST'] = gettz('America/Sao_Paulo') # Brasilia Summer Time (UTC02) timezones['BRST'] = timezone('America/Sao_Paulo') # Brasilia Summer Time (UTC02)
timezones['BRT'] = gettz('America/Sao_Paulo') # Brasilia Time (UTC03) timezones['BRT'] = timezone('America/Sao_Paulo') # Brasilia Time (UTC03)
timezones['BST'] = gettz('Asia/Dhaka') # Bangladesh Standard Time (UTC+06) timezones['BST'] = timezone('Asia/Dhaka') # Bangladesh Standard Time (UTC+06)
timezones['BTT'] = gettz('Asia/Thimphu') # Bhutan Time (UTC+06) timezones['BTT'] = timezone('Asia/Thimphu') # Bhutan Time (UTC+06)
timezones['CAT'] = gettz('Africa/Harare') # Central Africa Time (UTC+02) timezones['CAT'] = timezone('Africa/Harare') # Central Africa Time (UTC+02)
timezones['CCT'] = gettz('Indian/Cocos') # Cocos Islands Time (UTC+06:30) timezones['CCT'] = timezone('Indian/Cocos') # Cocos Islands Time (UTC+06:30)
timezones['CDT'] = gettz('America/Chicago') # Central Daylight Time (North America) (UTC05) timezones['CDT'] = timezone('America/Chicago') # Central Daylight Time (North America) (UTC05)
timezones['CEST'] = gettz('Europe/Berlin') # Central European Summer Time (Cf. HAEC) (UTC+02) timezones['CEST'] = timezone('Europe/Berlin') # Central European Summer Time (Cf. HAEC) (UTC+02)
timezones['CET'] = gettz('Europe/Berlin') # Central European Time (UTC+01) timezones['CET'] = timezone('Europe/Berlin') # Central European Time (UTC+01)
timezones['CHADT'] = gettz('Pacific/Chatham') # Chatham Daylight Time (UTC+13:45) timezones['CHADT'] = timezone('Pacific/Chatham') # Chatham Daylight Time (UTC+13:45)
timezones['CHAST'] = gettz('Pacific/Chatham') # Chatham Standard Time (UTC+12:45) timezones['CHAST'] = timezone('Pacific/Chatham') # Chatham Standard Time (UTC+12:45)
timezones['CHOST'] = gettz('Asia/Choibalsan') # Choibalsan Summer Time (UTC+09) timezones['CHOST'] = timezone('Asia/Choibalsan') # Choibalsan Summer Time (UTC+09)
timezones['CHOT'] = gettz('Asia/Choibalsan') # Choibalsan Standard Time (UTC+08) timezones['CHOT'] = timezone('Asia/Choibalsan') # Choibalsan Standard Time (UTC+08)
timezones['CHST'] = gettz('Pacific/Guam') # Chamorro Standard Time (UTC+10) timezones['CHST'] = timezone('Pacific/Guam') # Chamorro Standard Time (UTC+10)
timezones['CHUT'] = gettz('Pacific/Chuuk') # Chuuk Time (UTC+10) timezones['CHUT'] = timezone('Pacific/Chuuk') # Chuuk Time (UTC+10)
timezones['CIST'] = gettz('Etc/GMT-8') # Clipperton Island Standard Time (UTC08) timezones['CIST'] = timezone('Etc/GMT-8') # Clipperton Island Standard Time (UTC08)
timezones['CIT'] = gettz('Asia/Makassar') # Central Indonesia Time (UTC+08) timezones['CIT'] = timezone('Asia/Makassar') # Central Indonesia Time (UTC+08)
timezones['CKT'] = gettz('Pacific/Rarotonga') # Cook Island Time (UTC10) timezones['CKT'] = timezone('Pacific/Rarotonga') # Cook Island Time (UTC10)
timezones['CLST'] = gettz('America/Santiago') # Chile Summer Time (UTC03) timezones['CLST'] = timezone('America/Santiago') # Chile Summer Time (UTC03)
timezones['CLT'] = gettz('America/Santiago') # Chile Standard Time (UTC04) timezones['CLT'] = timezone('America/Santiago') # Chile Standard Time (UTC04)
timezones['COST'] = gettz('America/Bogota') # Colombia Summer Time (UTC04) timezones['COST'] = timezone('America/Bogota') # Colombia Summer Time (UTC04)
timezones['COT'] = gettz('America/Bogota') # Colombia Time (UTC05) timezones['COT'] = timezone('America/Bogota') # Colombia Time (UTC05)
timezones['CST'] = gettz('America/Chicago') # Central Standard Time (North America) (UTC06) timezones['CST'] = timezone('America/Chicago') # Central Standard Time (North America) (UTC06)
timezones['CT'] = gettz('Asia/Chongqing') # China time (UTC+08) timezones['CT'] = timezone('Asia/Chongqing') # China time (UTC+08)
timezones['CVT'] = gettz('Atlantic/Cape_Verde') # Cape Verde Time (UTC01) timezones['CVT'] = timezone('Atlantic/Cape_Verde') # Cape Verde Time (UTC01)
timezones['CXT'] = gettz('Indian/Christmas') # Christmas Island Time (UTC+07) timezones['CXT'] = timezone('Indian/Christmas') # Christmas Island Time (UTC+07)
timezones['DAVT'] = gettz('Antarctica/Davis') # Davis Time (UTC+07) timezones['DAVT'] = timezone('Antarctica/Davis') # Davis Time (UTC+07)
timezones['DDUT'] = gettz('Antarctica/DumontDUrville') # Dumont d'Urville Time (UTC+10) timezones['DDUT'] = timezone('Antarctica/DumontDUrville') # Dumont d'Urville Time (UTC+10)
timezones['DFT'] = gettz('Europe/Berlin') # AIX equivalent of Central European Time (UTC+01) timezones['DFT'] = timezone('Europe/Berlin') # AIX equivalent of Central European Time (UTC+01)
timezones['EASST'] = gettz('Chile/EasterIsland') # Easter Island Summer Time (UTC05) timezones['EASST'] = timezone('Chile/EasterIsland') # Easter Island Summer Time (UTC05)
timezones['EAST'] = gettz('Chile/EasterIsland') # Easter Island Standard Time (UTC06) timezones['EAST'] = timezone('Chile/EasterIsland') # Easter Island Standard Time (UTC06)
timezones['EAT'] = gettz('Africa/Mogadishu') # East Africa Time (UTC+03) timezones['EAT'] = timezone('Africa/Mogadishu') # East Africa Time (UTC+03)
timezones['ECT'] = gettz('America/Guayaquil') # Ecuador Time (UTC05) timezones['ECT'] = timezone('America/Guayaquil') # Ecuador Time (UTC05)
timezones['EDT'] = gettz('America/New_York') # Eastern Daylight Time (North America) (UTC04) timezones['EDT'] = timezone('America/New_York') # Eastern Daylight Time (North America) (UTC04)
timezones['EEST'] = gettz('Europe/Bucharest') # Eastern European Summer Time (UTC+03) timezones['EEST'] = timezone('Europe/Bucharest') # Eastern European Summer Time (UTC+03)
timezones['EET'] = gettz('Europe/Bucharest') # Eastern European Time (UTC+02) timezones['EET'] = timezone('Europe/Bucharest') # Eastern European Time (UTC+02)
timezones['EGST'] = gettz('America/Scoresbysund') # Eastern Greenland Summer Time (UTC±00) timezones['EGST'] = timezone('America/Scoresbysund') # Eastern Greenland Summer Time (UTC±00)
timezones['EGT'] = gettz('America/Scoresbysund') # Eastern Greenland Time (UTC01) timezones['EGT'] = timezone('America/Scoresbysund') # Eastern Greenland Time (UTC01)
timezones['EIT'] = gettz('Asia/Jayapura') # Eastern Indonesian Time (UTC+09) timezones['EIT'] = timezone('Asia/Jayapura') # Eastern Indonesian Time (UTC+09)
timezones['EST'] = gettz('America/New_York') # Eastern Standard Time (North America) (UTC05) timezones['EST'] = timezone('America/New_York') # Eastern Standard Time (North America) (UTC05)
timezones['FET'] = gettz('Europe/Minsk') # Further-eastern European Time (UTC+03) timezones['FET'] = timezone('Europe/Minsk') # Further-eastern European Time (UTC+03)
timezones['FJT'] = gettz('Pacific/Fiji') # Fiji Time (UTC+12) timezones['FJT'] = timezone('Pacific/Fiji') # Fiji Time (UTC+12)
timezones['FKST'] = gettz('Atlantic/Stanley') # Falkland Islands Summer Time (UTC03) timezones['FKST'] = timezone('Atlantic/Stanley') # Falkland Islands Summer Time (UTC03)
timezones['FKT'] = gettz('Atlantic/Stanley') # Falkland Islands Time (UTC04) timezones['FKT'] = timezone('Atlantic/Stanley') # Falkland Islands Time (UTC04)
timezones['FNT'] = gettz('Brazil/DeNoronha') # Fernando de Noronha Time (UTC02) timezones['FNT'] = timezone('Brazil/DeNoronha') # Fernando de Noronha Time (UTC02)
timezones['GALT'] = gettz('Pacific/Galapagos') # Galapagos Time (UTC06) timezones['GALT'] = timezone('Pacific/Galapagos') # Galapagos Time (UTC06)
timezones['GAMT'] = gettz('Pacific/Gambier') # Gambier Islands (UTC09) timezones['GAMT'] = timezone('Pacific/Gambier') # Gambier Islands (UTC09)
timezones['GET'] = gettz('Asia/Tbilisi') # Georgia Standard Time (UTC+04) timezones['GET'] = timezone('Asia/Tbilisi') # Georgia Standard Time (UTC+04)
timezones['GFT'] = gettz('America/Cayenne') # French Guiana Time (UTC03) timezones['GFT'] = timezone('America/Cayenne') # French Guiana Time (UTC03)
timezones['GILT'] = gettz('Pacific/Tarawa') # Gilbert Island Time (UTC+12) timezones['GILT'] = timezone('Pacific/Tarawa') # Gilbert Island Time (UTC+12)
timezones['GIT'] = gettz('Pacific/Gambier') # Gambier Island Time (UTC09) timezones['GIT'] = timezone('Pacific/Gambier') # Gambier Island Time (UTC09)
timezones['GMT'] = gettz('GMT') # Greenwich Mean Time (UTC±00) timezones['GMT'] = timezone('GMT') # Greenwich Mean Time (UTC±00)
timezones['GST'] = gettz('Asia/Muscat') # Gulf Standard Time (UTC+04) timezones['GST'] = timezone('Asia/Muscat') # Gulf Standard Time (UTC+04)
timezones['GYT'] = gettz('America/Guyana') # Guyana Time (UTC04) timezones['GYT'] = timezone('America/Guyana') # Guyana Time (UTC04)
timezones['HADT'] = gettz('Pacific/Honolulu') # Hawaii-Aleutian Daylight Time (UTC09) timezones['HADT'] = timezone('Pacific/Honolulu') # Hawaii-Aleutian Daylight Time (UTC09)
timezones['HAEC'] = gettz('Europe/Paris') # Heure Avancée d'Europe Centrale (CEST) (UTC+02) timezones['HAEC'] = timezone('Europe/Paris') # Heure Avancée d'Europe Centrale (CEST) (UTC+02)
timezones['HAST'] = gettz('Pacific/Honolulu') # Hawaii-Aleutian Standard Time (UTC10) timezones['HAST'] = timezone('Pacific/Honolulu') # Hawaii-Aleutian Standard Time (UTC10)
timezones['HKT'] = gettz('Asia/Hong_Kong') # Hong Kong Time (UTC+08) timezones['HKT'] = timezone('Asia/Hong_Kong') # Hong Kong Time (UTC+08)
timezones['HMT'] = gettz('Indian/Kerguelen') # Heard and McDonald Islands Time (UTC+05) timezones['HMT'] = timezone('Indian/Kerguelen') # Heard and McDonald Islands Time (UTC+05)
timezones['HOVST'] = gettz('Asia/Hovd') # Khovd Summer Time (UTC+08) timezones['HOVST'] = timezone('Asia/Hovd') # Khovd Summer Time (UTC+08)
timezones['HOVT'] = gettz('Asia/Hovd') # Khovd Standard Time (UTC+07) timezones['HOVT'] = timezone('Asia/Hovd') # Khovd Standard Time (UTC+07)
timezones['ICT'] = gettz('Asia/Ho_Chi_Minh') # Indochina Time (UTC+07) timezones['ICT'] = timezone('Asia/Ho_Chi_Minh') # Indochina Time (UTC+07)
timezones['IDT'] = gettz('Asia/Jerusalem') # Israel Daylight Time (UTC+03) timezones['IDT'] = timezone('Asia/Jerusalem') # Israel Daylight Time (UTC+03)
timezones['IOT'] = gettz('Etc/GMT+3') # Indian Ocean Time (UTC+03) timezones['IOT'] = timezone('Etc/GMT+3') # Indian Ocean Time (UTC+03)
timezones['IRDT'] = gettz('Asia/Tehran') # Iran Daylight Time (UTC+04:30) timezones['IRDT'] = timezone('Asia/Tehran') # Iran Daylight Time (UTC+04:30)
timezones['IRKT'] = gettz('Asia/Irkutsk') # Irkutsk Time (UTC+08) timezones['IRKT'] = timezone('Asia/Irkutsk') # Irkutsk Time (UTC+08)
timezones['IRST'] = gettz('Asia/Tehran') # Iran Standard Time (UTC+03:30) timezones['IRST'] = timezone('Asia/Tehran') # Iran Standard Time (UTC+03:30)
timezones['IST'] = gettz('Asia/Kolkata') # Indian Standard Time (UTC+05:30) timezones['IST'] = timezone('Asia/Kolkata') # Indian Standard Time (UTC+05:30)
timezones['JST'] = gettz('Asia/Tokyo') # Japan Standard Time (UTC+09) timezones['JST'] = timezone('Asia/Tokyo') # Japan Standard Time (UTC+09)
timezones['KGT'] = gettz('Asia/Bishkek') # Kyrgyzstan time (UTC+06) timezones['KGT'] = timezone('Asia/Bishkek') # Kyrgyzstan time (UTC+06)
timezones['KOST'] = gettz('Pacific/Kosrae') # Kosrae Time (UTC+11) timezones['KOST'] = timezone('Pacific/Kosrae') # Kosrae Time (UTC+11)
timezones['KRAT'] = gettz('Asia/Krasnoyarsk') # Krasnoyarsk Time (UTC+07) timezones['KRAT'] = timezone('Asia/Krasnoyarsk') # Krasnoyarsk Time (UTC+07)
timezones['KST'] = gettz('Asia/Seoul') # Korea Standard Time (UTC+09) timezones['KST'] = timezone('Asia/Seoul') # Korea Standard Time (UTC+09)
timezones['LHST'] = gettz('Australia/Lord_Howe') # Lord Howe Standard Time (UTC+10:30) timezones['LHST'] = timezone('Australia/Lord_Howe') # Lord Howe Standard Time (UTC+10:30)
timezones['LINT'] = gettz('Pacific/Kiritimati') # Line Islands Time (UTC+14) timezones['LINT'] = timezone('Pacific/Kiritimati') # Line Islands Time (UTC+14)
timezones['MAGT'] = gettz('Asia/Magadan') # Magadan Time (UTC+12) timezones['MAGT'] = timezone('Asia/Magadan') # Magadan Time (UTC+12)
timezones['MART'] = gettz('Pacific/Marquesas') # Marquesas Islands Time (UTC09:30) timezones['MART'] = timezone('Pacific/Marquesas') # Marquesas Islands Time (UTC09:30)
timezones['MAWT'] = gettz('Antarctica/Mawson') # Mawson Station Time (UTC+05) timezones['MAWT'] = timezone('Antarctica/Mawson') # Mawson Station Time (UTC+05)
timezones['MDT'] = gettz('America/Denver') # Mountain Daylight Time (North America) (UTC06) timezones['MDT'] = timezone('America/Denver') # Mountain Daylight Time (North America) (UTC06)
timezones['MEST'] = gettz('Europe/Paris') # Middle European Summer Time Same zone as CEST (UTC+02) timezones['MEST'] = timezone('Europe/Paris') # Middle European Summer Time Same zone as CEST (UTC+02)
timezones['MET'] = gettz('Europe/Berlin') # Middle European Time Same zone as CET (UTC+01) timezones['MET'] = timezone('Europe/Berlin') # Middle European Time Same zone as CET (UTC+01)
timezones['MHT'] = gettz('Pacific/Kwajalein') # Marshall Islands (UTC+12) timezones['MHT'] = timezone('Pacific/Kwajalein') # Marshall Islands (UTC+12)
timezones['MIST'] = gettz('Antarctica/Macquarie') # Macquarie Island Station Time (UTC+11) timezones['MIST'] = timezone('Antarctica/Macquarie') # Macquarie Island Station Time (UTC+11)
timezones['MIT'] = gettz('Pacific/Marquesas') # Marquesas Islands Time (UTC09:30) timezones['MIT'] = timezone('Pacific/Marquesas') # Marquesas Islands Time (UTC09:30)
timezones['MMT'] = gettz('Asia/Rangoon') # Myanmar Standard Time (UTC+06:30) timezones['MMT'] = timezone('Asia/Rangoon') # Myanmar Standard Time (UTC+06:30)
timezones['MSK'] = gettz('Europe/Moscow') # Moscow Time (UTC+03) timezones['MSK'] = timezone('Europe/Moscow') # Moscow Time (UTC+03)
timezones['MST'] = gettz('America/Denver') # Mountain Standard Time (North America) (UTC07) timezones['MST'] = timezone('America/Denver') # Mountain Standard Time (North America) (UTC07)
timezones['MUT'] = gettz('Indian/Mauritius') # Mauritius Time (UTC+04) timezones['MUT'] = timezone('Indian/Mauritius') # Mauritius Time (UTC+04)
timezones['MVT'] = gettz('Indian/Maldives') # Maldives Time (UTC+05) timezones['MVT'] = timezone('Indian/Maldives') # Maldives Time (UTC+05)
timezones['MYT'] = gettz('Asia/Kuching') # Malaysia Time (UTC+08) timezones['MYT'] = timezone('Asia/Kuching') # Malaysia Time (UTC+08)
timezones['NCT'] = gettz('Pacific/Noumea') # New Caledonia Time (UTC+11) timezones['NCT'] = timezone('Pacific/Noumea') # New Caledonia Time (UTC+11)
timezones['NDT'] = gettz('Canada/Newfoundland') # Newfoundland Daylight Time (UTC02:30) timezones['NDT'] = timezone('Canada/Newfoundland') # Newfoundland Daylight Time (UTC02:30)
timezones['NFT'] = gettz('Pacific/Norfolk') # Norfolk Time (UTC+11) timezones['NFT'] = timezone('Pacific/Norfolk') # Norfolk Time (UTC+11)
timezones['NPT'] = gettz('Asia/Kathmandu') # Nepal Time (UTC+05:45) timezones['NPT'] = timezone('Asia/Kathmandu') # Nepal Time (UTC+05:45)
timezones['NST'] = gettz('Canada/Newfoundland') # Newfoundland Standard Time (UTC03:30) timezones['NST'] = timezone('Canada/Newfoundland') # Newfoundland Standard Time (UTC03:30)
timezones['NT'] = gettz('Canada/Newfoundland') # Newfoundland Time (UTC03:30) timezones['NT'] = timezone('Canada/Newfoundland') # Newfoundland Time (UTC03:30)
timezones['NUT'] = gettz('Pacific/Niue') # Niue Time (UTC11) timezones['NUT'] = timezone('Pacific/Niue') # Niue Time (UTC11)
timezones['NZDT'] = gettz('Pacific/Auckland') # New Zealand Daylight Time (UTC+13) timezones['NZDT'] = timezone('Pacific/Auckland') # New Zealand Daylight Time (UTC+13)
timezones['NZST'] = gettz('Pacific/Auckland') # New Zealand Standard Time (UTC+12) timezones['NZST'] = timezone('Pacific/Auckland') # New Zealand Standard Time (UTC+12)
timezones['OMST'] = gettz('Asia/Omsk') # Omsk Time (UTC+06) timezones['OMST'] = timezone('Asia/Omsk') # Omsk Time (UTC+06)
timezones['ORAT'] = gettz('Asia/Oral') # Oral Time (UTC+05) timezones['ORAT'] = timezone('Asia/Oral') # Oral Time (UTC+05)
timezones['PDT'] = gettz('America/Los_Angeles') # Pacific Daylight Time (North America) (UTC07) timezones['PDT'] = timezone('America/Los_Angeles') # Pacific Daylight Time (North America) (UTC07)
timezones['PET'] = gettz('America/Lima') # Peru Time (UTC05) timezones['PET'] = timezone('America/Lima') # Peru Time (UTC05)
timezones['PETT'] = gettz('Asia/Kamchatka') # Kamchatka Time (UTC+12) timezones['PETT'] = timezone('Asia/Kamchatka') # Kamchatka Time (UTC+12)
timezones['PGT'] = gettz('Pacific/Port_Moresby') # Papua New Guinea Time (UTC+10) timezones['PGT'] = timezone('Pacific/Port_Moresby') # Papua New Guinea Time (UTC+10)
timezones['PHOT'] = gettz('Pacific/Enderbury') # Phoenix Island Time (UTC+13) timezones['PHOT'] = timezone('Pacific/Enderbury') # Phoenix Island Time (UTC+13)
timezones['PKT'] = gettz('Asia/Karachi') # Pakistan Standard Time (UTC+05) timezones['PKT'] = timezone('Asia/Karachi') # Pakistan Standard Time (UTC+05)
timezones['PMDT'] = gettz('America/Miquelon') # Saint Pierre and Miquelon Daylight time (UTC02) timezones['PMDT'] = timezone('America/Miquelon') # Saint Pierre and Miquelon Daylight time (UTC02)
timezones['PMST'] = gettz('America/Miquelon') # Saint Pierre and Miquelon Standard Time (UTC03) timezones['PMST'] = timezone('America/Miquelon') # Saint Pierre and Miquelon Standard Time (UTC03)
timezones['PONT'] = gettz('Pacific/Pohnpei') # Pohnpei Standard Time (UTC+11) timezones['PONT'] = timezone('Pacific/Pohnpei') # Pohnpei Standard Time (UTC+11)
timezones['PST'] = gettz('America/Los_Angeles') # Pacific Standard Time (North America) (UTC08) timezones['PST'] = timezone('America/Los_Angeles') # Pacific Standard Time (North America) (UTC08)
timezones['PYST'] = gettz('America/Asuncion') # Paraguay Summer Time (South America)[7] (UTC03) timezones['PYST'] = timezone('America/Asuncion') # Paraguay Summer Time (South America)[7] (UTC03)
timezones['PYT'] = gettz('America/Asuncion') # Paraguay Time (South America)[8] (UTC04) timezones['PYT'] = timezone('America/Asuncion') # Paraguay Time (South America)[8] (UTC04)
timezones['RET'] = gettz('Indian/Reunion') # Réunion Time (UTC+04) timezones['RET'] = timezone('Indian/Reunion') # Réunion Time (UTC+04)
timezones['ROTT'] = gettz('Antarctica/Rothera') # Rothera Research Station Time (UTC03) timezones['ROTT'] = timezone('Antarctica/Rothera') # Rothera Research Station Time (UTC03)
timezones['SAKT'] = gettz('Asia/Vladivostok') # Sakhalin Island time (UTC+11) timezones['SAKT'] = timezone('Asia/Vladivostok') # Sakhalin Island time (UTC+11)
timezones['SAMT'] = gettz('Europe/Samara') # Samara Time (UTC+04) timezones['SAMT'] = timezone('Europe/Samara') # Samara Time (UTC+04)
timezones['SAST'] = gettz('Africa/Johannesburg') # South African Standard Time (UTC+02) timezones['SAST'] = timezone('Africa/Johannesburg') # South African Standard Time (UTC+02)
timezones['SBT'] = gettz('Pacific/Guadalcanal') # Solomon Islands Time (UTC+11) timezones['SBT'] = timezone('Pacific/Guadalcanal') # Solomon Islands Time (UTC+11)
timezones['SCT'] = gettz('Indian/Mahe') # Seychelles Time (UTC+04) timezones['SCT'] = timezone('Indian/Mahe') # Seychelles Time (UTC+04)
timezones['SGT'] = gettz('Asia/Singapore') # Singapore Time (UTC+08) timezones['SGT'] = timezone('Asia/Singapore') # Singapore Time (UTC+08)
timezones['SLST'] = gettz('Asia/Colombo') # Sri Lanka Standard Time (UTC+05:30) timezones['SLST'] = timezone('Asia/Colombo') # Sri Lanka Standard Time (UTC+05:30)
timezones['SRET'] = gettz('Asia/Srednekolymsk') # Srednekolymsk Time (UTC+11) timezones['SRET'] = timezone('Asia/Srednekolymsk') # Srednekolymsk Time (UTC+11)
timezones['SRT'] = gettz('America/Paramaribo') # Suriname Time (UTC03) timezones['SRT'] = timezone('America/Paramaribo') # Suriname Time (UTC03)
timezones['SST'] = gettz('Asia/Singapore') # Singapore Standard Time (UTC+08) timezones['SST'] = timezone('Asia/Singapore') # Singapore Standard Time (UTC+08)
timezones['SYOT'] = gettz('Antarctica/Syowa') # Showa Station Time (UTC+03) timezones['SYOT'] = timezone('Antarctica/Syowa') # Showa Station Time (UTC+03)
timezones['TAHT'] = gettz('Pacific/Tahiti') # Tahiti Time (UTC10) timezones['TAHT'] = timezone('Pacific/Tahiti') # Tahiti Time (UTC10)
timezones['TFT'] = gettz('Indian/Kerguelen') # Indian/Kerguelen (UTC+05) timezones['TFT'] = timezone('Indian/Kerguelen') # Indian/Kerguelen (UTC+05)
timezones['THA'] = gettz('Asia/Bangkok') # Thailand Standard Time (UTC+07) timezones['THA'] = timezone('Asia/Bangkok') # Thailand Standard Time (UTC+07)
timezones['TJT'] = gettz('Asia/Dushanbe') # Tajikistan Time (UTC+05) timezones['TJT'] = timezone('Asia/Dushanbe') # Tajikistan Time (UTC+05)
timezones['TKT'] = gettz('Pacific/Fakaofo') # Tokelau Time (UTC+13) timezones['TKT'] = timezone('Pacific/Fakaofo') # Tokelau Time (UTC+13)
timezones['TLT'] = gettz('Asia/Dili') # Timor Leste Time (UTC+09) timezones['TLT'] = timezone('Asia/Dili') # Timor Leste Time (UTC+09)
timezones['TMT'] = gettz('Asia/Ashgabat') # Turkmenistan Time (UTC+05) timezones['TMT'] = timezone('Asia/Ashgabat') # Turkmenistan Time (UTC+05)
timezones['TOT'] = gettz('Pacific/Tongatapu') # Tonga Time (UTC+13) timezones['TOT'] = timezone('Pacific/Tongatapu') # Tonga Time (UTC+13)
timezones['TVT'] = gettz('Pacific/Funafuti') # Tuvalu Time (UTC+12) timezones['TVT'] = timezone('Pacific/Funafuti') # Tuvalu Time (UTC+12)
timezones['ULAST'] = gettz('Asia/Ulan_Bator') # Ulaanbaatar Summer Time (UTC+09) timezones['ULAST'] = timezone('Asia/Ulan_Bator') # Ulaanbaatar Summer Time (UTC+09)
timezones['ULAT'] = gettz('Asia/Ulan_Bator') # Ulaanbaatar Standard Time (UTC+08) timezones['ULAT'] = timezone('Asia/Ulan_Bator') # Ulaanbaatar Standard Time (UTC+08)
timezones['USZ1'] = gettz('Europe/Kaliningrad') # Kaliningrad Time (UTC+02) timezones['USZ1'] = timezone('Europe/Kaliningrad') # Kaliningrad Time (UTC+02)
timezones['UTC'] = gettz('UTC') # Coordinated Universal Time (UTC±00) timezones['UTC'] = timezone('UTC') # Coordinated Universal Time (UTC±00)
timezones['UYST'] = gettz('America/Montevideo') # Uruguay Summer Time (UTC02) timezones['UYST'] = timezone('America/Montevideo') # Uruguay Summer Time (UTC02)
timezones['UYT'] = gettz('America/Montevideo') # Uruguay Standard Time (UTC03) timezones['UYT'] = timezone('America/Montevideo') # Uruguay Standard Time (UTC03)
timezones['UZT'] = gettz('Asia/Tashkent') # Uzbekistan Time (UTC+05) timezones['UZT'] = timezone('Asia/Tashkent') # Uzbekistan Time (UTC+05)
timezones['VET'] = gettz('America/Caracas') # Venezuelan Standard Time (UTC04) timezones['VET'] = timezone('America/Caracas') # Venezuelan Standard Time (UTC04)
timezones['VLAT'] = gettz('Asia/Vladivostok') # Vladivostok Time (UTC+10) timezones['VLAT'] = timezone('Asia/Vladivostok') # Vladivostok Time (UTC+10)
timezones['VOLT'] = gettz('Europe/Volgograd') # Volgograd Time (UTC+04) timezones['VOLT'] = timezone('Europe/Volgograd') # Volgograd Time (UTC+04)
timezones['VOST'] = gettz('Antarctica/Vostok') # Vostok Station Time (UTC+06) timezones['VOST'] = timezone('Antarctica/Vostok') # Vostok Station Time (UTC+06)
timezones['VUT'] = gettz('Pacific/Efate') # Vanuatu Time (UTC+11) timezones['VUT'] = timezone('Pacific/Efate') # Vanuatu Time (UTC+11)
timezones['WAKT'] = gettz('Pacific/Wake') # Wake Island Time (UTC+12) timezones['WAKT'] = timezone('Pacific/Wake') # Wake Island Time (UTC+12)
timezones['WAST'] = gettz('Africa/Lagos') # West Africa Summer Time (UTC+02) timezones['WAST'] = timezone('Africa/Lagos') # West Africa Summer Time (UTC+02)
timezones['WAT'] = gettz('Africa/Lagos') # West Africa Time (UTC+01) timezones['WAT'] = timezone('Africa/Lagos') # West Africa Time (UTC+01)
timezones['WEST'] = gettz('Europe/London') # Western European Summer Time (UTC+01) timezones['WEST'] = timezone('Europe/London') # Western European Summer Time (UTC+01)
timezones['WET'] = gettz('Europe/London') # Western European Time (UTC±00) timezones['WET'] = timezone('Europe/London') # Western European Time (UTC±00)
timezones['WIT'] = gettz('Asia/Jakarta') # Western Indonesian Time (UTC+07) timezones['WIT'] = timezone('Asia/Jakarta') # Western Indonesian Time (UTC+07)
timezones['WST'] = gettz('Australia/Perth') # Western Standard Time (UTC+08) timezones['WST'] = timezone('Australia/Perth') # Western Standard Time (UTC+08)
timezones['YAKT'] = gettz('Asia/Yakutsk') # Yakutsk Time (UTC+09) timezones['YAKT'] = timezone('Asia/Yakutsk') # Yakutsk Time (UTC+09)
timezones['YEKT'] = gettz('Asia/Yekaterinburg') # Yekaterinburg Time (UTC+05) timezones['YEKT'] = timezone('Asia/Yekaterinburg') # Yekaterinburg Time (UTC+05)
return timezones return timezones
Loading…
Cancel
Save