2009-10-20 49 views
0

我只是試圖將一個CGEventTimestamp(這是一個大約表示系統啓動後納秒的無符號64位整數)轉換爲一個NSDate。我知道有一種方法可以將「系統啓動後的時間」轉換爲NSTimeInterval或相對於參考日期的日期,但我沒有找到它。CGEventTimestamp到NSDate

如何將CGEventTimestamp轉換爲NSDate將接受的內容?謝謝。

(忘了提,需要10.5友好,避免碳如果可能的話)

回答

3
// Determine time in NSTimeInterval seconds this event took place after system start 
GCEventTimestamp nanoseconds = GetIt(); 
NSTimeInterval seconds = (NSTimeInterval)nanoseconds/1000000000.0; 

// GetCurrentEventTime() gives you time in seconds since system start 
EventTime currentTimeInSeconds = GetCurrentEventTime(); 

// Given this you can figure out the date of system start, and then add 
// your event time 
NSDate* startTime = [NSDate dateWithTimeIntervalSinceNow:-currentTimeInSeconds]; 
NSDate* eventTime = [startTime dateByAddingTimeInterval:seconds]; 
+0

對於沒有提及此需求,我表示誠摯的歉意。10.5- [NSDate dateByAddingTimeInterval:]僅在10.6中提供。另外,我目前沒有與碳鏈接。我想我可以,但如果可以的話,我真的很想避免它。 – MyztikJenz 2009-10-20 22:21:34

+0

這個線程可能是有用的:http://www.cocoabuilder.com/archive/message/cocoa/2004/8/29/115976 – nall 2009-10-20 22:28:49

+0

至於dateByAddingTimeInterval,你可以使用[[[[NSDate alloc] initWithTimeInterval:-currentTimeInSeconds sinceDate:[NSDate date]] autorelease] – nall 2009-10-20 22:30:33

2

NALL讓我在正確的方向。我在NSDate上打了一個關注細節的類別,並且兼容10.5/10.6,並且不使用Carbon。感謝您的幫助,不要!

的NSDate-Additions.h

#import <Foundation/Foundation.h> 
@interface NSDate (NSDate_Additions) 

+(NSTimeInterval) timeIntervalSinceSystemStartup; 
-(NSTimeInterval) timeIntervalSinceSystemStartup; 
+(NSDate *) dateOfSystemStartup; 
+(NSDate *) dateWithCGEventTimestamp:(CGEventTimestamp)cgTimestamp; 

@end 

的NSDate-Additions.m

#import "NSDate-Additions.h" 
#include <assert.h> 
#include <CoreServices/CoreServices.h> 
#include <mach/mach.h> 
#include <mach/mach_time.h> 
#include <unistd.h> 

#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 
@interface NSProcessInfo (SnowLeopard) 
- (NSTimeInterval)systemUptime; 
@end 

@interface NSDate (SnowLeopard) 
- (id)dateByAddingTimeInterval:(NSTimeInterval)seconds; 
@end 
#endif 


// Boosted from Apple sample code 
uint64_t UpTimeInNanoseconds(void) 
{ 
    uint64_t  time; 
    uint64_t  timeNano; 
    static mach_timebase_info_data_t sTimebaseInfo; 

    time = mach_absolute_time(); 

    // Convert to nanoseconds. 

    // If this is the first time we've run, get the timebase. 
    // We can use denom == 0 to indicate that sTimebaseInfo is 
    // uninitialised because it makes no sense to have a zero 
    // denominator is a fraction. 

    if (sTimebaseInfo.denom == 0) { 
     (void) mach_timebase_info(&sTimebaseInfo); 
    } 

    // Do the maths. We hope that the multiplication doesn't 
    // overflow; the price you pay for working in fixed point. 

    timeNano = time * sTimebaseInfo.numer/sTimebaseInfo.denom; 

    return timeNano; 
} 


@implementation NSDate (NSDate_Additions) 

+(NSTimeInterval) timeIntervalSinceSystemStartup 
{ 
    NSTimeInterval interval; 
    long sysVersion; 

    Gestalt(gestaltSystemVersion, &sysVersion); 
    if(sysVersion >= 0x1060) 
     interval = [[NSProcessInfo processInfo] systemUptime]; 
    else 
     interval = UpTimeInNanoseconds()/1000000000.0; 

    return(interval); 
} 

-(NSTimeInterval) timeIntervalSinceSystemStartup 
{ 
    return([self timeIntervalSinceDate:[NSDate dateOfSystemStartup]]); 
} 

+(NSDate *) dateOfSystemStartup 
{ 
    return([NSDate dateWithTimeIntervalSinceNow:-([NSDate timeIntervalSinceSystemStartup])]); 
} 

+(NSDate *) dateWithCGEventTimestamp:(CGEventTimestamp)cgTimestamp 
{ 
    NSDate *ssuDate = nil; 
    NSDate *cgDate = nil; 
    long sysVersion; 

    ssuDate = [NSDate dateOfSystemStartup]; 

    Gestalt(gestaltSystemVersion, &sysVersion); 
    if(sysVersion >= 0x1060) 
     cgDate = [ssuDate dateByAddingTimeInterval:(cgTimestamp/1000000000.0)]; 
    else 
     cgDate = [ssuDate addTimeInterval:(cgTimestamp/1000000000.0)]; 

    return(cgDate); 
} 

@end 
+0

很高興你明白!根據我的理解,GetCurrentEventTime()只是mach_absolute_time()的一個包裝。 – nall 2009-10-21 17:18:19

0

這不是一個答案,因爲某些原因,我不能對你的信息添加評論以上...

我想知道如果我可以使用你粘貼在一個開源項目中的代碼我是contri (與此頁面的鏈接)。

乾杯!

+0

絕對可以隨意使用它,只要你認爲合適。考慮它有一個MIT許可證(除非Stack Overflow另有說明)。你在做什麼項目,Marcello? – MyztikJenz 2009-11-20 14:15:34

+0

謝謝!我正在貢獻jpen(http://jpen.sf.net/),並試圖將NSEvents中的時間戳轉換爲自時代以來的毫秒數。 不幸的是,timestamp參數是錯誤的,或者系統啓動測量需要很長時間,因爲計算的時間似乎最終會結束(比NSLog和System.currentTimeMillis晚2〜3ms,在事件發生後在java *中執行)被收到),並且隨着事件通過(在我停止計數之前已經達到20ms),情況變得更糟......所以我可能最終完全放棄這個功能。 – 2009-11-21 05:48:09

1

關於上面的代碼NSDate-Additions.m。行「timeNano = time * sTimebaseInfo.numer/sTimebaseInfo.denom;」將導致iPhone OS 2.2.1上的內存損壞。解決方法是使用如下所示的轉換:timeNano = time *(uint64_t)sTimebaseInfo.numer/sTimebaseInfo.denom;