运行 Quartz 作业时补偿时区偏移

2024-01-28

我有一个独特的问题,因为我的quartz作业调度程序实现是使用quartz.net代码库版本2.0.1构建的,最近发现在运行和执行作业时时区和utc偏移量被忽略。这是该版本quartz.net 中的一个继承错误,更新到版本 2.1.1 目前超出了范围,因此我编写了一种使用此算法计算偏移量的快速而肮脏的方法:

(服务器时间 - 客户端时间) - 目标时间 = New_TargetTime_With_Offset

这里的想法是,位于纽约的客户在下午 5:00 完成一项工作,并希望它在下午 2:00 运行。服务器(运行此应用程序和作业服务器的地方)当前时间为下午 2:00,因此我们使用客户端时间和服务器时间来获取偏移量,并将该偏移量应用于目标时间,即作业应运行的时间。

我的问题是,这感觉像是一种计算日期的迂回方式,但看起来它可以完成这项工作。有没有更好/更可靠的方法来进行这个日期数学?另外,这在边缘情况下似乎是有问题的,我错过了什么?

这是实现:

    /// <summary>
    /// Takes three dates and returns the adjusted hour value.
    /// All date data is ignored except for the hour. 
    /// </summary>
    /// <param name="serverTime"></param>
    /// <param name="clientTime"></param>
    /// <param name="targetTime"></param>
    /// <returns></returns>
    private static DateTime OutputDate(DateTime serverTime, DateTime clientTime, DateTime targetTime)
    {
        DateTime? output = null;
        TimeSpan? dateDiff;

        if (serverTime < clientTime)
        {
            dateDiff = (clientTime - serverTime);
        }
        else
        {
            dateDiff = (serverTime - clientTime);
        }

        output = (targetTime - dateDiff);

        return output.Value;
    }

以下是利用它的两个示例:

    /// <summary>
    /// -5 Offset (NYC)
    /// </summary>
    /// <returns></returns>
    private static Int32 ZoneTest001()
    {
        var targetTime = DateTime.Parse("6/12/2013 5:00PM");  // NYC (est) [The time the report should be received in NYC]
        var clientTime = DateTime.Parse("6/12/2013 5:00PM");   // NYC (est) [The time of the client when the report is created (now) ]
        var serverTime = DateTime.Parse("6/12/2013 2:00PM");  // SEA (pst) [The time of the app server when the report is created (now) ]

        //
        // NYC Wants to send a report at 5:00pm EST
        // The server time will be 2:00pm PST
        // The client time will be 5:00pm EST

        double outputHour = 0;   // should end up as 2:00pm PST

        //
        // 1) Get offset (diff between client & server time)
        // 2) Subtract offset from "targetTime"
        // 3) Set the report to be sent at the new hour value.

        outputHour = OutputDate(serverTime, clientTime, targetTime).Hour;

        return (int)outputHour;

    }

    /// <summary>
    /// +5 Offset (India)
    /// </summary>
    /// <returns></returns>
    private static Int32 ZoneTest002()
    {
        var targetTime = DateTime.Parse("6/12/2013 5:00PM"); // IND (ist)
        var clientTime = DateTime.Parse("6/12/2013 9:00AM");  // IND (ist)
        var serverTime = DateTime.Parse("6/12/2013 2:00PM"); // SEA (pst)

        //
        // INDIA Wants to send a report at 5:00pm IST
        // The server time will be 2:00pm PST
        // The client time will be 9:00am PST

        double outputHour = 0;   // should end up as 2:00pm PST
        outputHour = OutputDate(serverTime, clientTime, targetTime).Hour;

        return (int)outputHour;

    }

谢谢。


实际上你错过了很多。

  1. 时区偏移量不是恒定的。许多时区会切换夏令时(又称“夏令时”)的偏移量。因此,当您根据每个位置(服务器、客户端、目标)的“现在”计算偏移量时,这仅反映了current offset.

  2. 在任何有 DST 的时区,当时钟向前滚动时,都会缺少一个小时,并且重复的时钟向后滚动的小时。如果您正在处理当地时间,并且预定的事件属于不明确的时间段,则您无法确定运行该事件的实际时刻。为了消除歧义,您需要told对应的偏移量是多少,或者你需要以UTC来处理。

  3. 如果您要从一个时区转换到另一个时区,则需要处理时区,而不仅仅是它们的偏移量。在.Net中,您可以使用内置的Windows时区数据库和相应的TimeZoneInfo班级。或者,您可以使用更标准的 IANA 时区数据库,例如野田时间 http://www.nodatime.org.

  4. 当与DateTime类型,要非常小心.Kind属性设置为。许多函数在处理不同类型时有不同的行为。使用该方法会更安全、更有用DateTimeOffset改为键入。

  5. 您真的不应该依赖于代码运行的服务器的时区。服务器代码应该与时区无关。你唯一应该参与的地方DateTime.Now or TimeZoneInfo.Local或任何类似的功能在desktop or mobile应用程序。服务器代码应该仅取决于 UTC。

  6. 我真的不明白为什么你的内部有可为空的值OutputDate方法。没有理由这样做。此外,您实际上正在获取差异的绝对值 - 这会降低方向性。时区偏移确实是定向的,因此您当前的实现可能会得到无效的结果。

  7. 我查看了 Quartz.net API,他们似乎更喜欢您在 UTC 中安排活动时间。这是一件非常好的事情,因为 UTC 不存在歧义问题。来自Quartz.Net 教程 http://quartznet.sourceforge.net/tutorial/lesson_1.html, the trigger.StartTimeUtc显然是UTCDateTime。既然你说你不能使用最新版本,我还检查了他们较旧的1.0 API文档,它仍然是UTC。

    Update: 石英网2.5 https://www.quartz-scheduler.net/2017/02/18/quartznet-2.5-released.html更大可以更好地处理时区。看#317 https://github.com/quartznet/quartznet/pull/317了解详情。

让我们将所有这些放在一起作为您的示例用例。纽约市的一位客户希望在当地时区的下午 2:00 运行作业。服务器的时区无关紧要,他创建作业的时间也无关紧要。

// June 6, 2013 2:00 PM  Kind = Unspecified
DateTime dt = new DateTime(2013, 6, 13, 14, 0, 0);

// This is the correct Windows time zone for New York
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

// Get the time in UTC - The kind matters here.
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tz);

// Feed it to a quartz event trigger
trigger.StartTimeUtc = utc;

当我在第三步中将时间转换为 UTC 时,如果时间不明确,.Net 会假设您想要standard时间而不是daylight时间。如果您想更具体,则必须检查是否有歧义,然后询问用户他们想要两个当地时间中的哪一个。那么你就必须使用DateTimeOffset以区分它们。如果您认为您可能需要这个,请告诉我,我可以制作一个样本,但它有点复杂。

为了更好地衡量,如果您想使用 IANA 时区野田时间 http://www.nodatime.org,它看起来像这样:

LocalDateTime ldt = new LocalDateTime(2013, 6, 13, 14, 0);
DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
ZonedDateTime zdt = ldt.InZoneLeniently(tz);
trigger.StartTimeUtc = zdt.ToDateTimeUtc();

The InZoneLeniently方法将给出与上面代码相​​同的行为。但如果需要,您还可以指定其他选项。

哦,这并不重要,但印度是+5:30, not +5

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行 Quartz 作业时补偿时区偏移 的相关文章

  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 如何让 Swagger 插件在自托管服务堆栈中工作

    我已经用 github 上提供的示例重新提出了这个问题 并为任何想要自己运行代码的人提供了一个下拉框下载链接 Swagger 无法在自托管 ServiceStack 服务上工作 https stackoverflow com questio
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • Javascript转换时区问题

    我在转换当前时区的日期时间时遇到问题 我从服务器收到此日期字符串 格式为 2015 10 09T08 00 00 这是中部时间 但是当我使用 GMT 5 中的 new Date strDate 转换此日期时间时 它返回给我的信息如下 这是不
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 使用 C# 读取 Soap 消息

  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • System.IO.FileNotFoundException:找不到网络路径。在 Windows 7 上使用 DirectoryEntry 对象时出现异常

    我正在尝试使用 DirectoryEntry 对象连接到远程 Windows 7 计算机 这是我的代码 DirectoryEntry obDirEntry new DirectoryEntry WinNT hostName hostName

随机推荐

  • 我怎样才能在NodaTime中知道城市和它的时区之间的关系?

    目前我正在使用 NodaTime 从国家 地区获取时区 但问题是一个国家 地区是否有多个时区 我怎样才能知道该时区的城市列表 我需要知道这两个数据之间的映射 NodaTime 可以吗 正确的处理方法如下 查找每个位置的纬度和经度 如果这些是
  • 使用 MVCContrib 对 MVC 3 控制器和视图进行单元测试时将键和值添加到 RouteData

    好的 我正在使用 MVCContrib TestHelper 对我的控制器进行单元测试 效果很好 不过 像很多人一样 通过单元测试 我真正的意思是这里的集成测试 我想至少确保我的视图在给定提供的模型的情况下呈现没有错误 否则我可能会错过一整
  • SwiftUI NavigationView/Stack(如果可用)iOS 15/16

    关于从NavigationView to NavigationStack适用于 SwiftUI 4 和 iOS 16 我有 2 个应用程序在 App Store 上运行 针对 iOS 15 及更高版本 当然我正在使用NavigationVi
  • 获取 contenteditable DIV 中插入符的 HTML 位置

    我无法弄清楚如何在包含 HTML 标签的 DIV 容器中获取插入符位置 我正在使用这个 JavaScript 函数来做到这一点 function getCaretPosition if window getSelection window
  • 支持 src/ 和 test/ 的简单 ant 构建脚本?

    目前 我使用 IDE 进行所有构建和单元测试 现在我需要使用ant 我发现了一些简单的 ant build xml 脚本 但它们不支持单独的 Junit test 目录 我的项目结构如下 src com foo com bar test M
  • java中同一数组的元素比较

    我正在尝试比较同一数组的元素 这意味着我想将 0 元素与其他所有元素进行比较 将 1 元素与其他所有元素进行比较 依此类推 问题是它没有按预期工作 我所做的是我有两个从 0 到 array length 1 的 for 循环 然后我有一个
  • Netbeans 7.2 显示“无法解析标识符”,尽管构建成功

    我正在使用Netbeans IDE 7 2 with C C 插件 最新版本 1 18 1 1 和 如果我构建我的项目 一切都很好 但 IDE 会显示错误 例如 无法解析标识符 其他人也有这个错误 我该如何解决它 这是我对另一个问题的回答的
  • NEST (elasticsearch) 在多个字段中突出显示

    我已经使用 Nest 成功获得了结果和突出显示 但如果我包含两个字段来搜索突出显示 则它在构建 elasticsearch 查询时仅使用最后一个字段 例如下列 Query qry gt qry QueryString qs gt qs Qu
  • 将 SoapHeader 添加到 org.springframework.ws.WebServiceMessage

    如何将对象添加到肥皂头org springframework ws WebServiceMessage 这是我希望最终得到的结构
  • 有没有可以替代 parse_qs 来处理分号的方法?

    TL DR 哪些库 调用可用于处理包含与 parse qs 不同的分号的查询字符串 gt gt gt urlparse parse qs tagged python ruby gt gt gt tagged python 完整背景 我正在使
  • Grafana 在 url 中传递访问令牌

    我创建了一个 API 密钥来与第三方应用程序共享 grafana 面板 我想将它嵌入到 iframe 中 但它要求我登录 如何在 url 中发送访问令牌 我一直在关注 http self issued info docs draft iet
  • 使用Python OpenCV将QR码旋转到正确的位置

    我是Python的初学者 目前正在研究二维码检测和解码 我很难将检测到的二维码旋转到正确的位置 我已经用过minAreaRect 旋转我的二维码 但它不起作用 有没有解决方法或正确的方法来做到这一点 谢谢 ROI2 cv2 imread R
  • 列出 LDAP 中的根上下文

    我想列出或搜索 LDAP 树中的根上下文 我使用 Apache Directory Server 和 Java Hashtable
  • 使用未分配的局部变量“字典”

    尽管我在以下代码中分配了值 但仍收到错误 使用未分配的局部变量 字典 private static void UpdateJadProperties Uri jadUri Uri jarUri Uri notifierUri Diction
  • 如何在真实设备上调试(使用Eclipse/ADT)

    我正在尝试弄清楚如何直接在我的手机 HTC Desire 上调试应用程序 我已经安装了手机附带的 USB 驱动程序 并且使用 adb devices 时会列出手机 如何配置 eclipse ADT 在手机上启动而不是启动模拟器 虚拟设备 注
  • ASP.NET MVC 和 WCF

    我目前正在努力学习 MVC 但在我的 在某个时刻学习 列表中 我还学习了 WCF 我只是想知道 WCF 是否应该 可以在 MVC 应用程序中使用 背景是我想要一个桌面应用程序 NET 3 5 WPF 与我的 MVC 网站交互 我想知道在两者
  • 通过单个命令安装私有和公共 NPM 软件包

    我在 package json 文件中列出了一些 npm 包 有些是公共的 有些是私有的 我想通过使用在单个命令中安装两种类型的包npm install 如果 npm 注册表设置为全局 则私有包显示404 那么如何通过单个命令来实现这一点
  • jetty-maven-插件和 loadTimeWeaver

    似乎无法让我的 Spring Web 应用程序与 jetty maven 插件一起使用 我总是得到 org springframework beans factory BeanCreationException Error creating
  • 我不懂指针

    什么是指针 什么是取消引用 如果p是一个指针 有什么区别 p some value and p other value 什么是p some variable意思是 什么是NULL指针 当取消引用 NULL 指针时会发生什么 准备一叠黄色便利
  • 运行 Quartz 作业时补偿时区偏移

    我有一个独特的问题 因为我的quartz作业调度程序实现是使用quartz net代码库版本2 0 1构建的 最近发现在运行和执行作业时时区和utc偏移量被忽略 这是该版本quartz net 中的一个继承错误 更新到版本 2 1 1 目前