定时器未检测到输入何时与DateTime.Now匹配

时间:2013-12-21 05:20:34

标签: c# datetime timer

我的表格上有一个计时器,间隔为1000(1秒)。我允许用户通过三个组合框输入时间。然后,他们输入的时间将转换为DateTime格式。最后,如果输入时间等于DateTime.Now,则计时器会检查每个滴答。问题是它无法正常工作。

假设我将闹钟设置为晚上8:59:50的晚上9:00:00。我点击开始并等待十秒钟以使闹钟响起,但它永远不会。在调试代码时,两个数字都是相同的,这意味着它应该触发,但事实并非如此。

这是我的代码:

private void tmrAlarm_Tick(object sender, EventArgs e) {
    DateTime alarmTime = Convert.ToDateTime(statusAlarm.Text); // say statusAlarm.Text is 9:00:00 PM

    if(alarmTime == DateTime.Now) {
        MessageBox.Show("bzzt");
    }
}

有没有更好的方法来实现这一点(例如,计算秒数而不是检查它是否是正确的时间)?我应该使用秒表吗?

最后,是不是因为计时器在一秒钟而不是一开始就开始了?就像我在1.05秒而不是第二秒启动计时器一样。

修改

我将代码更改为:

if(alarmTime.Hour == DateTime.Now.Hour &&
   alarmTime.Minute == DateTime.Now.Minute &&
   alarmTime.Second == DateTime.Now.Second) { ... }

看起来有点笨重,但效果很好!

3 个答案:

答案 0 :(得分:2)

问题是,DateTime.Now返回一个非常精确的值,小数秒。因此,您很可能永远不会达到满足==条件的程度。

要执行您想要的操作,您必须只获取返回的DateTime(h,m,s)的“更高级别”值。

答案 1 :(得分:0)

您也可以使用

用于检查相等性的

DateTime.Now.ToShortTimeString()方法

答案 2 :(得分:0)

无论粒度如何,您都不能依赖于在恰好目标时间触发的计时器(如其他答案所示)。 (另外,比较舍入时间可能会导致事件提前触发,如果它不是圆值)。

如果你转到一秒钟,如果由于另一个进程占用处理器时间而导致机器运行非常缓慢,则可能会错过。 如果你转到更大的间隔(甚至几小时或几天),如果机器当时处于睡眠/休眠模式,或者由于夏令时调整实际上可以跳过该时间,它仍然可能会丢失。

测试是否达到事件时间的正确方法是检查当前时间是否大于或等于目标时间。 您必须禁用事件被触发的计时器或标志,以便它不会再次触发它。

您可能不想触发错过的事件(例如,如果机器在目标时间关闭,则下次打开时可能会或可能不会执行此操作)。在这种情况下,您必须测试目标时间(包括)和目标时间之间的当前时间加上某个时间间隔(您仍希望触发事件的目标时间之后的最长时间间隔)。 / p>