【问题标题】:Timer not detecting when input matches DateTime.Now计时器未检测到输入何时匹配 DateTime.Now
【发布时间】:2014-10-03 21:00:06
【问题描述】:

我的表单上有一个计时器,间隔为 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) { ... }

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

【问题讨论】:

  • DateTime.Now 包括小数秒。因此,在这种情况下,== 不能直接与它一起使用以获得有用的结果。
  • 您需要将 DateTime 舍入为秒,然后进行比较,不要使用==,而是使用>。那么即使你不四舍五入它也会起作用
  • 成功了!谢谢大家!

标签: c# datetime timer


【解决方案1】:

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

要做你想做的事,你必须只取返回的 DateTime (h,m, s) 的“更高级别”值。

【讨论】:

  • 我刚刚更改了代码以检查 h/m/s,它运行良好!谢谢!
  • 我会接受的。只需稍等...编辑:接受!再次感谢!
  • 这并不适用于所有情况。由于夏令时调整、手动设置时钟或机器处于睡眠状态,或者由于机器性能不佳而可能超过一秒钟未触发检查等,可能会跳过时间.
【解决方案2】:

你也可以使用

DateTime.Now.ToShortTimeString() 相等性检查方法

【讨论】:

    【解决方案3】:

    无论粒度如何,您都不能完全依赖于在目标时间触发的计时器(如其他答案所建议的那样)。 (此外,比较舍入时间可能会导致事件提前触发,如果它还不是舍入值)。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2021-02-27
      相关资源
      最近更新 更多