2009-03-27 16 views
8

イベントに日付スタンプを記録するCocoaアプリケーションがあります。私はシステム時間がいつリセットされ、どのくらいであるかを知る必要がありますが、私はそのようなことが起こったと私に知らせるどこの通知もうまくいかないようです。この変更は、NTPが時計をリセットするか、ユーザーがリセットしたために発生する可能性があります(システム環境設定などから)。受け取るために登録することができるNSNotificationがあればそれは素晴らしいことですが、私はいかなる提案にも開放しています。Cocoaアプリケーションのシステム時間の変更を通知するにはどうすればよいですか?

+1

からシステムの日付変更変更イベントを知っている場合NTP同期によって、またはタイムゾーンを変更したり、システム環境設定で時間を手動で設定したりしますか? –

+0

はい、そうです。私はあまりにも明白ではなかったことは申し訳なく思っています。私はうまくいけば、今これをより明確にした。 –

答えて

13

Appleがで追加しました。NSSystemClockDidChangeNotification、Snow Leopard(10.6)のNSDateの一部です。 Leopard(10.5)以前ではこれを行う方法がないようです。 Apple NSDate docs

システムクロックが変更されたときはいつでも投稿されます。これは、settimeofday()の呼び出し、またはユーザーがDate and Time Preferenceパネルで値を変更することによって開始できます。通知オブジェクトはnullです。この通知にuserInfoディクショナリは含まれていません。

これは、「どのくらいの時間」が変更されたかを示すものではありません。 NSSateClientDidChangeNotificationが発生した後、それを変数に保存し、NSDateを使用して新しい日付を取得し、2つを一緒に比較することができます(たとえば、NSTimerで5秒ごとに)[NSDate date] timeIntervalSinceDate:違いを得る方法。

精度はミリ秒ではなく、秒ではありませんが、かなり近いです。

編集:this postを参照してください。 UpTime() Cコマンドを使用して、CPUチックでシステム稼働時間を取得できます(後で秒単位に変換できます)。これを使用して、システムの再起動やスリープがないと仮定して、どれくらいの時間が経過したかを把握できます。これは、システムクロックがユーザーまたはネットワークタイムプロトコルによって変更された場合でも機能します。

1

時間が絶えず動いています。現在の時刻が変更されるたびに通知がCPUの浸透している通知のストリームになります。

あなたがしなければならないことは、イベントハンドラで現在の時刻を取得することです。イベントハンドラは、日付を記入しているイベントを受け取る時刻です。現在時刻は[NSDate date]になります。

+8

さて、OPはクロックの通常の進歩ではなく、時間の珍しい変化を意味することは明らかですね:) – phlebotinum

0

私は、時間を変えることができるさまざまな仕組みのために、それを行う方法はないと思います。しかし、それほど高価ではありません(あまりにも高価ですか?まだ分かりませんか?)、NSTimerを1秒に1回設定して時間をチェックし、前の値と比較してください。約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); 

} 

関連する問題