`agenda.js` 如何计算 `every()` 操作的时区

How `agenda.js` calculates timezone for `every()` operation

我在我的 Node 项目中使用 agenda.js,支持 MongoDB 数据库,以处理我们需要 运行 的批处理。这运作良好。但是,我确实对时区有疑问。当我使用 every() 操作时,它似乎接受作业名称和时间表。所以我一直在像这样将工作播种到数据库中:

  for (let job of dbJobs) {
    await agenda.every(schedule, job.name);
  }

请注意,对于上述内容,schedule 是 cron 格式 -- 00 05 * * 1-5

这行得通。但是,据我所知,every() 不接受 repeatTimezone 的参数。那么在这些情况下计算时区有什么用呢?

澄清一下,当我在使用 every() 添加作业后查看数据库中的文档时,repeatTimezone 属性 存在,但其值设置为 null.

其他 agenda 操作,例如 repeatEvery()do 接受时区参数,例如:

job.repeatEvery('0 6 * * *', {
  timezone: 'America/New_York'
});

自从我使用 every() 以来,我一直通过首先使用 every() 播种数据库来管理它,然后 运行 宁 Mongo updateMany() 将 timzeone 显式添加到所有作业:

async function addTimezoneToJobs() {
  try {
    const db = await client.db(dbName);
    await db.collection('batch_processes').updateMany({}, {
      $set: {
        repeatTimezone: 'America/New_York'
      }
    });
  } catch (error) {
    console.log(error);
  }
}

但奇怪的是,即使我没有明确地将 repeatTimezone 属性 值添加到作业中,agenda 似乎也计算了相同的时间。

这里发生了什么我不明白的事情? 运行时间是如何用every()计算的,有没有办法传入时区?

仅供参考:我与需要在数据库中设置的时区不在同一个时区。

你的问题似乎分为两部分,我不确定我能否很好地解释它,但让我试试看

所以,你的第一个问题

However, from what I can tell, every() doesn't accept an argument for Timezone

从技术上讲,您也可以将 Timezone 选项添加到 every(),因为此方法的作用是在内部调用 job.repeatEvery,正如您已经知道的,您可以添加 timezone 到那个。为了支持我的回答,我找到了 2 个证据

  1. 来自 Documentation 因为 every 接受 4 个参数

every(interval, name, [data], [options])

options is an optional argument that will be passed to job.repeatEvery. In order to use this argument, data must also be specified.

所以你可以技术上通过timezone如果你也通过data

  1. 来自 SourceCode,在这里你可以看到他们在内部使用 job.repeatEvery(interval, options)

现在,关于你的第二个问题

what does it do to calculate the timezone in those cases?

嗯,他们有一个非常独特但必需的模块,名为 ComputeNextRunAt()

所以我查看了他们的源代码,发现这是为了根据 startingTime 和 Interval 计算下一个 运行 工作的时间。

您的代码之所以有效,是因为您在工作中曾经(最初)提到要遵循 America/New_York 时区,因此每个下一个工作间隔都是基于此计算的,这就是您不需要指定它的原因再次.

因此,如果最初您没有指定时区属性,您会得到 local Timezone 但现在您这样做了,它会根据该属性计算下一个时间间隔。