【问题标题】:How can I get notified of a system time change in my Cocoa application?如何在我的 Cocoa 应用程序中获得系统时间更改的通知?
【发布时间】:2009-03-27 15:55:40
【问题描述】:

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

【问题讨论】:

  • 你的意思是什么时候时钟改变,例如通过 NTP 同步,或更改时区或在系统偏好设置中手动设置时间?
  • 是的,这就是我的意思。很抱歉,我一开始不是很清楚。我希望现在能更清楚地说明这一点。

标签: cocoa nsnotifications


【解决方案1】:

Apple 在 Snow Leopard (10.6) 中添加了 NSSystemClockDidChangeNotification,这是 NSDate 的一部分。在 Leopard (10.5) 或更早版本中似乎没有办法做到这一点。根据Apple NSDate docs

在系统时钟更改时发布。这可以通过调用 settimeofday() 或用户更改 Date and Time Preference 面板中的值来启动。通知对象为空。此通知不包含 userInfo 字典。

这似乎并不能告诉您“多少”时间发生了变化。您可以通过定期(例如,在 NSTimer 中每 5 秒)使用 [NSDate date] 捕获系统时间,将其保存到变量中,然后在 NSSystemClockDidChangeNotification 触发后,获取新日期并比较两者一起使用 NSDate 的 timeIntervalSinceDate: 方法来获得差异。

不精确到毫秒甚至秒,但非常接近。

编辑:this post。您可以使用UpTime() C 命令以 CPU tic 获取系统正常运行时间(稍后您可以将其转换为秒)。您可以使用它来计算更改了多少时间(假设没有系统重新启动或睡眠)。即使系统时钟被用户或网络时间协议更改,这仍然有效。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      时间在不停地流动。每次当前时间更改时都会发出通知,这将是一个持续的、占用 CPU 的通知流。

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

      【讨论】:

      • 嗯,很明显 OP 意味着时间的不寻常变化而不是时钟的定期提前:)
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        相关资源
        最近更新 更多