windows 如何检测系统时间是否更改?(来自.net)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4246882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:38:48  来源:igfitidea点击:

How do I detect if the system time is changed? (from .net)

.netwindowstime

提问by Ian Ringrose

I am using DateTime.UtcNow to measure time in my software and need to be able to tell if “action a” happens less more than 10 seconds after “action b”

我正在使用 DateTime.UtcNow 来测量我的软件中的时间,并且需要能够判断“动作 a”是否在“动作 b”之后发生的时间少于 10 秒

However what if the system time is change? So how I do I detect if the system time is changed?

但是如果系统时间改变了呢?那么我如何检测系统时间是否改变?

I don't wish to use a stopwatch as we need to run on servers with more then one CPU, see http://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

我不想使用秒表,因为我们需要在具有多个 CPU 的服务器上运行,请参阅http://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

I also need to cope with virtual machines being paused and restarted, so the “tick count” is unlikely to be useful to me.

我还需要应对虚拟机的暂停和重启,所以“滴答计数”对我来说不太可能有用。

回答by Philip Rieck

You can use the SystemEvents.TimeChangedevent to detect the time changed. However, this will only fire if you have a messagepump running - this is fine for windows client applications, but not so much for most server applications (like services, web apps, etc).

您可以使用该SystemEvents.TimeChanged事件来检测更改的时间。但是,这只会在您运行 messagepump 时触发 - 这对于 Windows 客户端应用程序来说很好,但对于大多数服务器应用程序(如服务、Web 应用程序等)而言则不然。

Otherwise you can use Environment.TickCount- it doesn't have excellent resolution, but if your "10" seconds can be "nearly 10 seconds" you're probably fine. A far as the VM limitation, note that TickCount rolls over when the machine has been up long enough, so you'll have to handle that, possibly with a DateTime.UtcNowsanity check either way.

否则你可以使用Environment.TickCount- 它没有很好的分辨率,但如果你的“10”秒可以是“接近 10 秒”,你可能没问题。就 VM 限制而言,请注意,当机器运行足够长的时间时,TickCount 会翻转,因此您必须处理它,可能通过DateTime.UtcNow任何一种方式进行健全性检查。

I'd use the combination of both - but note that there's no absolutely accurate way other than checking some external timeserver that is known accurate (which is going to have perf impact) that will work in the VM case anyway... make sure you determine what is "reliable enough" before you spend more time than the issue is worth.

我会使用两者的组合 - 但请注意,除了检查一些已知准确的外部时间服务器(这将产生性能影响)之外,没有绝对准确的方法,无论如何都可以在 VM 情况下工作......确保你在花费的时间超过问题的价值之前,确定什么是“足够可靠”。

回答by Jim Mischel

I would still suggest using StopWatch. If the problem described in Beware of QueryPerformanceCounterstill exists, you're only talking a difference of a few milliseconds. If you're worried about negative times (something I've never seen, and I use StopWatcha lot to time some pretty small intervals), then treat anything between -1 millisecond and -1,000 milliseconds as zero.

我仍然建议使用StopWatch. 如果注意 QueryPerformanceCounter 中描述的问题仍然存在,那么您只是在谈论几毫秒的差异。如果您担心负时间(我从未见过,并且我StopWatch经常使用一些非常小的时间间隔),那么将 -1 毫秒和 -1,000 毫秒之间的任何时间视为零。

Using DateTime.Nowor DateTime.UtcNowfor any kind of timing is going to cause you trouble if somebody changes the date/time on the machine. You have to use something that's completely internal to the computer and can't be changed. StopWatchis the most reliable one I've found.

如果有人更改了机器上的日期/时间,使用DateTime.NowDateTime.UtcNow任何类型的时间都会给您带来麻烦。您必须使用完全在计算机内部且无法更改的东西。 StopWatch是我找到的最可靠的。

回答by Tim Lloyd

You can use the TimeChanged event of the SystemEvents class to detect changes to the system clock at runtime:

您可以使用 SystemEvents 类的 TimeChanged 事件来检测运行时系统时钟的变化:

http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged.aspx

http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged.aspx

This relies on your application having a message loop (I assume because the WM_TIMECHANGED message needs to be processed) so you will need a hidden form if it is a headless application e.g. windows service.

这依赖于您的应用程序具有消息循环(我假设是因为需要处理 WM_TIMECHANGED 消息),因此如果它是无头应用程序(例如 Windows 服务),您将需要一个隐藏的表单。

As for detecting changes to the system clock whilst your application is suspended because of being on a suspended virtual machine - well all bets are off really for a truly reliable solution. You could periodically record the last time you performed a check, and just ensure that time has not gone backwards. It is likely to take longer than ten seconds to suspend and resume a VM anyway.

至于在您的应用程序由于处于挂起的虚拟机上而被挂起时检测系统时钟的变化 - 好吧,对于真正可靠的解决方案来说,所有的赌注都是真的。您可以定期记录上次执行检查的时间,并确保时间没有倒退。无论如何,挂起和恢复 VM 可能需要超过 10 秒的时间。

回答by Martin Kosicky

I would compare system time difference with a monotic clock between 2 time intervals. If the difference is bigger than some tollerance than someone changed the date and time on your machine

我会将系统时差与 2 个时间间隔之间的单调时钟进行比较。如果差异大于某些容差,则有人更改了您机器上的日期和时间