2009-03-27 4 views
8

Ho un'applicazione Cocoa che registra i datestamp sugli eventi. Ho bisogno di sapere quando il tempo di sistema è resettato e da quanto, ma non riesco a sembrare una notifica da nessuna parte che mi dice che è successo qualcosa del genere. Questo cambiamento potrebbe accadere perché NTP resetta l'orologio o perché l'utente si resetta (ad esempio dalle Preferenze di Sistema). Sarebbe bello se ci fosse solo una NSNotification che potrei registrare per ricevere, ma sono aperto a qualsiasi suggerimento.Come posso ricevere una notifica di un cambio orario del sistema nella mia applicazione Cocoa?

+1

vuoi dire quando cambia orologio, per esempio tramite una sincronizzazione NTP o modificando il fuso orario o impostando manualmente l'ora in Preferenze di Sistema? –

+0

Sì, questo è ciò che intendo. Mi dispiace di non essere stato molto chiaro all'inizio. Spero di aver reso questo più chiaro ora. –

risposta

13

Apple ha aggiunto in NSSystemClockDidChangeNotification, parte di NSDate, in Snow Leopard (10.6). Non sembra essere un modo per farlo in Leopard (10.5) o prima. Per il Apple NSDate docs:

Inviato ogni volta che si modifica l'orologio di sistema. Questo può essere avviato da una chiamata a settimeofday() o dall'utente che modifica i valori nel pannello Preferenza di data e ora. L'oggetto di notifica è null. Questa notifica non contiene un dizionario UserInfo.

Questo non sembra dirti "quanto" tempo è cambiato. È possibile calcolarlo periodicamente (ad esempio, ogni 5 secondi in un NSTimer) catturando l'ora del sistema con [Data NSDate], salvandolo in una variabile, quindi dopo l'attivazione di NSSystemClockDidChangeNotification, acquisisci la nuova data e confronta i due insieme utilizzando NSDate timeIntervalSinceDate: metodo per ottenere la differenza.

Non millisecondo o anche secondo accurato, ma piuttosto vicino.

MODIFICA: Vedere this post. È possibile utilizzare il comando C UpTime() per ottenere il tempo di funzionamento del sistema in tic CPU (che in seguito è possibile convertire in secondi). Si può usare questo per capire quanto tempo è cambiato (supponendo che non ci sia il riavvio del sistema o il sonno). Funziona anche se l'orologio di sistema viene modificato dall'utente o dal protocollo orario di rete.

1

Il tempo si sposta costantemente. Una notifica ogni volta che viene modificata l'ora corrente sarebbe un flusso costante di notifiche di ammorbidimento della CPU.

Quello che devi fare è ottenere l'ora corrente nel gestore di eventi, quella che riceve gli eventi che stai registrando. Ottieni l'ora corrente chiamando [NSDate date].

+8

Beh, non è ovvio che l'OP significhi un insolito cambio di orario e non il normale avanzamento dell'orologio :) – phlebotinum

0

Non penso che ci sia un unico modo per farlo a causa dei diversi meccanismi con cui il tempo potrebbe cambiare. Ma non sarebbe molto costoso (troppo costoso? Non lo so, lo hai già profilato? ;-) per impostare un NSTimer una volta al secondo per controllare l'ora e confrontarlo con il valore precedente. Se non è avanzato di circa un secondo, è successo qualcosa di interessante e puoi notificare il tuo oggetto di controllo.

10

Se alcuni su è alla ricerca di una soluzione sanno sistema evento data cambiamento cambiamento da 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); 

}