I'm trying to run a job ever day at 8:00 AM at timezone('Asia/Calcutta'), so I started using python schedule. Here's a sample snippet:
import schedule
import time
def job(t):
print "I'm working...", t
return
schedule.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 timezones), the job start at 8:00 am based on that particular time zone. 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 have gone through different articles from Stack Overflow related to timezones, getting offset and changing 8:00 am to something like 8:00 + some offset 4:30 hrs, but that did not work.
looking for the best way to run python code on any server/any timezone, but scheduler will trigger in timezone('Asia/Calcutta') this timezone.
is there a 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 wherever I call datetime.now(), it should give time as per new timezone,
eastern = timezone('Asia/Calcutta')
# naive datetime
naive_dt = datetime.now()
# localized datetime
loc_dt = datetime.now(eastern)
print(naive_dt.strftime(fmt))
print(loc_dt.strftime(fmt))
Based on this (answer) I am not interested to change system files, I'm looking for a pythonic way.
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
Setup your server and job timezones and create a payload function.
import datetime as dt
import time
from scheduler import Scheduler
import pytz
TZ_SERVER = dt.timezone.utc # can be any valid timezone
TZ_IST = pytz.timezone('Asia/Calcutta') # IST - India Standard Time
TZ_CEST = pytz.timezone('Europe/Berlin') # CEST - Central European Summer Time
def 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=2
type function due at tzinfo due in attempts weight
-------- ---------------- ------------------- ------------ --------- ------------- ------
DAILY task(..) 2021-07-20 08:00:00 IST 2:36:42 0/inf 1
DAILY 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
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)