首页
学习
活动
专区
圈层
工具
发布

时差
EN

Code Review用户
提问于 2016-06-22 09:04:02
回答 4查看 184关注 0票数 4

我用的是DateTime C#。我有一个带有属性小时的XML文件,即:

代码语言:javascript
复制
<MyXML>
     <LastTimeTaskRun>11:50</LastTimeTaskRun>
</MyXML>

我的任务是每5分钟运行一次。我想知道当前的时间和时间是否从xml大到5分钟。我想做的是:

代码语言:javascript
复制
int hour, min;
DateTime dateTimeXML = DateTime.Now, dateTimeNow;
string [] lastSuccessTime = LastSuccessTime.Split(':');

Int32.TryParse(lastSuccessTime[0], out hour);
Int32.TryParse(lastSuccessTime[1], out min);

dateTimeXML = dateTimeXML.Date + new TimeSpan(hour, min, 0);
dateTimeNow = DateTime.Now;

bool isBigThen5Min = (dateTimeNow - dateTimeXML).TotalMinutes > 5;

代码工作得很好,但我想知道做这件事的最佳方法(性能)是什么。

EN

回答 4

Code Review用户

发布于 2016-06-22 16:30:07

除了在计时器上遵循赫斯拉赫的建议外,请参阅罗布关于穿越日期的评论。然后将这种想法扩展到任何夏令转换。你可能会说你永远不会在半夜运行这个应用程序,但在将来,这个应用程序可能是一个服务或一个预定的任务,在午夜或凌晨2点左右运行。

对于内部计时,人们应该总是更喜欢DateTime.UtcNow而不是DateTime.Now,原因有两个:(1)它更快,(2)它不容易发生DST转换。

您可能会考虑使用XML的时间,但是如果您传递了一个符合ISO 8601标准字符串,您会更安全,并且使用更好的实践。使用.NET很容易使用往返“O”格式说明器往返“O”格式说明器。强烈建议您仔细阅读往返的链接。

这简化了您的编码,同时使应用程序不容易出错。假设变量LastSuccessTime是从XML读取的时间字符串,则不再需要采取大量步骤来解析其中的部分。您的XML看起来应该是:

代码语言:javascript
复制
<MyXML>
     <LastTimeTaskRun>2016-06-21T23:59:00Z</LastTimeTaskRun>
</MyXML>

LastSuccessTime将包含"2016-06-21T23:59:00Z“。

现在您可以使用如下代码:

代码语言:javascript
复制
var lastSuccessUtc = DateTime.Parse(LastSuccessTime, null, DateTimeStyles.RoundtripKind).ToUniversalTime();

var isBigThen5Min = (DateTime.UtcNow - lastSuccessUtc).TotalMinutes > 5;

最后一行包含一个神奇的数字,所以您应该考虑为它设置一个常量。您还可以通过不同的方式获得相同的效果(例如,不一定是一个更好的实践):

代码语言:javascript
复制
const int thresholdInMinutes = 5;
var isBigThen5Min = (DateTime.UtcNow - lastSuccessUtc) > TimeSpan.FromMinutes(tresholdInMinutes);

这个答案将适用于不同日期的午夜和DST转换。此外,它缩短了代码。更短更简单更容易跟踪和维护。

票数 4
EN

Code Review用户

发布于 2016-06-22 09:42:29

对于解析时间,您可以使用ParseExact方法:

代码语言:javascript
复制
var lastTimeTaskRun = DateTime.ParseExact("11:23", "HH:mm", CultureInfo.InvariantCulture);

要计算现在和最后一次可以直接减去的差额:

代码语言:javascript
复制
var isGreaterThen5Min = (DateTime.Now - lastTimeTaskRun).TotalMinutes > 5;

将5定义为const也是一个好主意:

代码语言:javascript
复制
const int maxIntervalInMinutes = 5;
var isGreaterThenMaxInterval = 
    (DateTime.Now - lastTimeTaskRun).TotalMinutes > maxIntervalInMinutes;

您应该与变量名保持一致。xml元素名为LastTimeTaskRun,但属性是LastSuccessTime。挑一个,到处都用。否则,你将需要解释和思考这一切都是为了什么。

票数 2
EN

Code Review用户

发布于 2016-06-23 10:41:56

高于其他答案。

  1. 您是否考虑过将时间存储在项目设置项目设置中--它们易于朗读朗读、支持类型(即可以存储DateTime对象)--并且通常更容易处理。
  2. 为了提高可读性,您可能应该每行编写一个var声明: DateTime dateTimeXML = DateTime.Now;DateTime dateTimeNow;这就是MS 建议。这就立即暴露出在可能的情况下,在声明变量的同时违反了初始化变量的好原则。所以,与DateTime dateTimeNow;dateTimeNow =DateTime.Now不同,最好编写var dateTimeNow = DateTime.Now;这些考虑也可能很有趣。
  3. 至于isBigThen5Min变量的名称,我几乎喜欢@t3chb0t 's建议,只将thEn改为thAn: isGreaterThanMaxInterval。

此外,在编程过程中,您似乎还没有真正处理过日期和时间问题,所以下面是一些有趣的阅读来获得灵感:错误的程序员相信时间 :)

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/132719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档