2009-10-20 62 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;