I'm trying to run a job ever day at 8:00 AM at timezone('Asia/Calcutta'), so i started using python scheduler. sample snippet
import scheduleimport timedef job(t):print "I'm working...", treturnschedule.every().day.at("08:00").do(job,'It is 08:00')while True:schedule.run_pending()time.sleep(30) # wait one minute
this snippets works very well if a execute in Indian servers, but if i run in COLAB or AWS (which are in different timezone), job start at 8:00 am based on that particular time zone. But i would like to make code to run every day 8:00 am on this timezone('Asia/Calcutta'), irrespective of the server time zone. i gone through different article from stackoverflow related to timezones, getting offset and changing 8:00 am to something like 8:00 + some offset 4:30 hrs. but did notwork.
looking for best way to run python code on anyserver/any timezone, but scheduler will trigger in timezone('Asia/Calcutta') this timezon.
is there any way to change datetime timezone on thread level or full python process level (only for that script/thread, not system level), so i want to change timezone once in python, and after that where every i call datetime.now(), it should give time as per new timzone,
eastern = timezone('Asia/Calcutta')# naive datetimenaive_dt = datetime.now()# localized datetimeloc_dt = datetime.now(eastern)print(naive_dt.strftime(fmt))print(loc_dt.strftime(fmt))
based on this (answer) not interested to change system files, looking pythonic way
Best Answer
If you are looking for a scheduler with timezone support in mind, you might be interested in the scheduler library. An example for a similar situation as you described can be found in the documentation. I modified it below to suit your question and additionally added a second Job with an independant timezone for better demonstration.
Disclosure: I'm one of the authors of the scheduler library
Question 1
Setup your server and job timezones and create a payload function.
import datetime as dtimport timefrom scheduler import Schedulerimport pytz TZ_SERVER = dt.timezone.utc # can be any valid timezoneTZ_IST = pytz.timezone('Asia/Calcutta') # IST - India Standard TimeTZ_CEST = pytz.timezone('Europe/Berlin') # CEST - Central European Summer Timedef task(tzinfo):current_time = dt.datetime.now(tzinfo)print(f"I'm working... {current_time!s}")
Create a Scheduler instance and schedule recurring daily jobs with specified times and timezones:
schedule = Scheduler(tzinfo=TZ_SERVER)trigger_ist = dt.time(hour=8, tzinfo=TZ_IST)schedule.daily(trigger_ist, task, args=(TZ_IST,))trigger_cest = dt.time(hour=8, tzinfo=TZ_CEST)job_cest = schedule.daily(trigger_cest, task, args=(TZ_CEST,))
Show a simple overview of the schedule.
print(schedule)
max_exec=inf, tzinfo=UTC, priority_function=linear_priority_function, #jobs=2type function due at tzinfo due in attempts weight-------- ---------------- ------------------- ------------ --------- ------------- ------DAILY task(..) 2021-07-20 08:00:00 IST 2:36:42 0/inf 1DAILY task(..) 2021-07-20 08:00:00 CEST 6:06:42 0/inf 1
Create your execution loop analogous to the schedule library:
while True:schedule.exec_jobs()time.sleep(60) # wait one minute
Once the payload function is called you should see something similar to below.
I'm working... 2021-07-20 08:00:33.173469+05:30
Question 2
I'm unsure if I understand your second question, but it is alway possible to cast one datetime.datetime
object with a timezone into another datetime.datetime
object with another timezone. E.g. you can do:
now_cest = dt.datetime.now(TZ_CEST)now_ist = now_cest.astimezone(TZ_IST)