CGEventTimestamp to NSDate
I'm simply trying to convert a CGEventTimestamp (which is an unsigned 64-bit integer roughly representing nanoseconds since system startup) into an NSDate. I know there's a way to convert "time since system startup" into either an NSTimeInterval or a date relative to a reference da开发者_如何学Gote, but I'm not finding it.
How do I convert a CGEventTimestamp into something NSDate will accept? Thanks.
(forgot to mention, needs to be 10.5 friendly and avoid Carbon if at all possible)
// 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];
nall got me in the right direction. I slapped together a category on NSDate that takes care of the details and is both 10.5/10.6 friendly and uses no Carbon. Thanks for the help, nall!
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
Regarding the code NSDate-Additions.m above. The line "timeNano = time * sTimebaseInfo.numer / sTimebaseInfo.denom;" will cause memory corruption on iPhone OS 2.2.1. A fix is to use a cast like: timeNano = time * (uint64_t)sTimebaseInfo.numer / sTimebaseInfo.denom;
This is not an answer, for some reason I cannot add a comment on your post above...
I was wondering if I could use the code you pasted in an open-source project I'm contributing to (with a link to this page).
Cheers!
精彩评论