【发布时间】:2013-06-09 08:42:08
【问题描述】:
我有一个独特的问题,我的石英作业调度程序实现是使用quartz.net 代码库ver 2.0.1 构建的,最近发现在运行和执行作业时忽略了时区和UTC 偏移量。这是这个版本的quartz.net 中的一个继承错误,现在更新到2.1.1 版本超出了范围,所以我写了一个快速而肮脏的方法来使用这个算法计算偏移量:
(ServerTime - ClientTime) - TargetTime = 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;
}
谢谢。
【问题讨论】:
-
你考虑过使用 DateTimeOffset 类型吗?
-
似乎使用 DateTimeOffset(DateTime, TimeSpan) 构造函数会稍微清理我的代码,但这仍然不能真正回答我原来的问题。
-
我遇到了一个非常相似的问题,并通过使用 Noda-Time 解决了它。 stackoverflow.com/questions/7553997/…
-
感谢该链接,Stephan - Noda-Time 似乎是补充石英并扩展 .net DateTime 对象缺少的功能的好方法。很棒的发现;相当的编程宝石。我要使用它:)
-
@StephenKennedy:另一条注释;因为我是 Jon Skeet 的忠实粉丝,在阅读了你的帖子和他对 noda-time 的认可之后,我不得不试一试,我现在正在这样做。很高兴我问了这个问题,并感谢像你这样的人,马特约翰逊和乔恩 - 干杯!
标签: c# datetime quartz-scheduler quartz.net timespan