如何在Cocoa应用程序中收到系统时间更改的通知?

时间:2009-03-27 15:55:40

标签: cocoa nsnotifications

我有一个Cocoa应用程序,它记录事件的日期戳。我需要知道系统时间何时重置以及重置多少,但我似乎无法在任何告知我发生过这种情况的通知。这种变化可能发生,因为NTP重置时钟或因为用户重置(例如从系统偏好设置)。如果只有NSNotification我可以注册接收,那将是很好的,但我愿意接受任何建议。

4 个答案:

答案 0 :(得分:15)

Apple在雪豹(10.6)中添加了NSSystemClockDidChangeNotification,NSDate的一部分。似乎没有办法在Leopard(10.5)或更早版本中执行此操作。根据{{​​3}}:

  

每当系统时钟发生变化时都会发布。这可以通过调用settimeofday()或用户更改“日期和时间首选项”面板中的值来启动。通知对象为null。此通知不包含userInfo字典。

这似乎并没有告诉你“多少”时间已经改变。您可以定期(例如,NSTimer中的每5秒)使用[NSDate date]捕获系统时间,将其保存到变量中,然后在NSSystemClockDidChangeNotification触发后,抓住新日期并使用NSDate的 timeIntervalSinceDate: 方法将两者结合起来以获得差异。

不是毫秒甚至是第二准确,但非常接近。

编辑:请参阅Apple NSDate docs。您可以使用UpTime() C命令来获取CPU tics中的系统正常运行时间(稍后可以将其转换为秒)。您可以使用它来计算出更改的时间(假设没有系统重启或休眠)。即使系统时钟被用户或网络时间协议更改,这也可以工作。

答案 1 :(得分:10)

如果有人正在寻找解决方案,请知道系统日期更改事件从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);

}

答案 2 :(得分:1)

时间不断变化。每次当前时间改变时的通知都是一个恒定的,CPU浸泡的通知流。

您需要做的是获取事件处理程序中的当前时间 - 接收您正在进行日期戳记的事件的时间。您可以致电[NSDate date]获取当前时间。

答案 3 :(得分:0)

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