python 调度程序从任何时区在特定时区调度作业

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

我正在尝试每天在时区 ('Asia/Calcutta') 的 8:00 上午 运行 做一份工作,所以我开始使用 python 调度程序。示例片段

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

如果在印度服务器中执行此代码段效果很好,但如果我 运行 在 COLAB 或 AWS(处于不同时区)中,作业开始于 8:00 是基于特定的时区。但我想在这个时区 ('Asia/Calcutta') 每天 8:00 编写代码 运行,而不考虑服务器时区。我浏览了来自 Whosebug 的与时区相关的不同文章,获取偏移量并将 8:00 am 更改为 8:00 + 一些偏移量 4:30 小时。但是没有用。

  1. 正在寻找 运行 python 在 anyserver/any 时区编码的最佳方法,但调度程序将在该时区的时区 ('Asia/Calcutta') 中触发。

  2. 有什么方法可以在线程级别或完整 python 进程级别(仅针对 script/thread,而不是系统级别)更改日期时间时区,所以我想更改timezone 在 python 中一次,之后我每次调用 datetime.now() 时,它应该根据新的 timzone 给出时间,

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

基于此 () 对更改系统文件不感兴趣,正在寻找 pythonic 方式

如果您正在寻找支持时区的调度程序,您可能会对 scheduler library. An example for a similar situation as you described can be found in the documentation 感兴趣。我在下面对其进行了修改以适合您的问题,并另外添加了第二个具有独立时区的作业以便更好地演示。

披露:我是调度程序库的作者之一

问题 1

设置您的服务器和作业时区并创建负载函数。

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}")

创建一个 Scheduler 实例并安排具有指定时间和时区的重复性每日作业:

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

显示时间表的简单概览。

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

创建类似于计划库的执行循环:

while True:
    schedule.exec_jobs()
    time.sleep(60)  # wait one minute

调用 payload 函数后,您应该会看到类似于下面的内容。

I'm working... 2021-07-20 08:00:33.173469+05:30

问题 2

我不确定我是否理解你的第二个问题,但总是可以将一个具有时区的 datetime.datetime 对象转换为另一个具有另一个时区的 datetime.datetime 对象。例如。你可以这样做:

now_cest = dt.datetime.now(TZ_CEST)
now_ist = now_cest.astimezone(TZ_IST)