11

我有一个记录事件日期戳的 Cocoa 应用程序。我需要知道系统时间何时重置以及重置多少,但我似乎无法在任何地方通知我这样的事情发生了。由于 NTP 重置时钟或用户重置(例如从系统偏好设置),可能会发生此更改。如果只有一个NSNotification我可以注册接收,那就太好了,但我愿意接受任何建议。

4

4 回答 4

18

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 抽动中的系统正常运行时间(稍后您可以将其转换为秒)。您可以使用它来计算更改了多少时间(假设没有系统重新启动或睡眠)。即使系统时钟由用户或网络时间协议更改,这仍然有效。

于 2009-10-26T02:39:28.807 回答
11

如果有人正在寻找解决方案,请从 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);

}

于 2010-07-29T14:08:12.793 回答
1

时间不断地移动。每次当前时间更改时的通知将是一个持续的、占用 CPU 的通知流。

您需要做的是在您的事件处理程序中获取当前时间——接收您正在添加日期戳的事件的处理程序。您可以通过调用获取当前时间[NSDate date]

于 2009-03-27T16:24:09.290 回答
0

我认为没有单一的方法可以做到这一点,因为时间可能会改变不同的机制。但它不会很贵(太贵了?不知道,你有没有分析过它?;-) 设置NSTimer每秒一次来检查时间并将其与之前的值进行比较。如果它没有提前大约一秒钟,就会发生一些有趣的事情,您可以通知您的审计对象。

于 2009-03-27T20:27:19.423 回答