我有一个记录事件日期戳的 Cocoa 应用程序。我需要知道系统时间何时重置以及重置多少,但我似乎无法在任何地方通知我这样的事情发生了。由于 NTP 重置时钟或用户重置(例如从系统偏好设置),可能会发生此更改。如果只有一个NSNotification
我可以注册接收,那就太好了,但我愿意接受任何建议。
4 回答
Apple在 Snow Leopard (10.6) 中添加了 NSDate 的一部分NSSystemClockDidChangeNotification 。在 Leopard (10.5) 或更早版本中似乎没有办法做到这一点。根据Apple NSDate 文档:
每当更改系统时钟时发布。这可以通过调用 settimeofday() 或用户更改 Date and Time Preference 面板中的值来启动。通知对象为空。此通知不包含 userInfo 字典。
这似乎并没有告诉你“多少”时间发生了变化。您可以通过定期(例如,在 a 中每 5 秒NSTimer
)捕获系统时间[NSDate date]
,将其保存到变量中,然后在NSSystemClockDidChangeNotification
触发后,获取新日期并使用 NSDate 的timeIntervalSinceDate:
方法将两者进行比较以获得差异来计算。
不是毫秒甚至秒精度,但非常接近。
编辑: 见这篇文章。您可以使用UpTime()
C 命令来获取 CPU 抽动中的系统正常运行时间(稍后您可以将其转换为秒)。您可以使用它来计算更改了多少时间(假设没有系统重新启动或睡眠)。即使系统时钟由用户或网络时间协议更改,这仍然有效。
如果有人正在寻找解决方案,请从 10.4 开始了解系统日期更改更改事件
OSStatus DateChangeEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData)
{
NSLog(@"Event received!\n");
return 0;
}
- (void)SystemTimeChangeHandler
{
EventTypeSpec eventType;
eventType.eventClass = kEventClassSystem;
eventType.eventKind = kEventSystemTimeDateChanged;
EventHandlerUPP eventHandlerUPP =
NewEventHandlerUPP(DateChangeEventHandler);
EventHandlerRef eventHandlerRef = NULL;
(void)InstallApplicationEventHandler(
eventHandlerUPP,
1,
&eventType,
self,
&eventHandlerRef);
}
时间不断地移动。每次当前时间更改时的通知将是一个持续的、占用 CPU 的通知流。
您需要做的是在您的事件处理程序中获取当前时间——接收您正在添加日期戳的事件的处理程序。您可以通过调用获取当前时间[NSDate date]
。
我认为没有单一的方法可以做到这一点,因为时间可能会改变不同的机制。但它不会很贵(太贵了?不知道,你有没有分析过它?;-) 设置NSTimer
每秒一次来检查时间并将其与之前的值进行比较。如果它没有提前大约一秒钟,就会发生一些有趣的事情,您可以通知您的审计对象。