bommina
bommina

Reputation: 317

python scheduler schedule job in specific time zone from any time zone

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.

  1. looking for the best way to run python code on any server/any timezone, but scheduler will trigger in timezone('Asia/Calcutta') this timezone.

  2. 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.

Upvotes: 1

Views: 3887

Answers (1)

F. Preiss
F. Preiss

Reputation: 46

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 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

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)

Upvotes: 3

Related Questions