Reputation: 998
I have a timestamp that represents the the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (according to http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx). This value is generated by a server written in C#, but I need to convert this to a date in Objective-C on iOS.
For example, the timestamp 634794644225861250 is supposed to give a date of August 2, 2012.
Upvotes: 2
Views: 3654
Reputation: 1853
Add a category for NSDate:
@implementation NSDate (CLRTicks)
+ (NSDate *)dateWithCLRTicks:(int64_t)ticks {
return [NSDate dateWithCLRTicks:ticks withTimeIntervalAddition:0.0];
}
+ (NSDate *)dateWithCLRTicks:(int64_t)ticks withTimeIntervalAddition:(NSTimeInterval)timeIntervalAddition {
const double GMTOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
const int64_t CLROffset = 621355968000000000;
double timeStamp = ((double)(ticks - CLROffset) / 10000000.0) - GMTOffset + timeIntervalAddition;
return [NSDate dateWithTimeIntervalSince1970:timeStamp];
}
@end
Upvotes: 1
Reputation: 5316
On iOS you cannot use dateWithString but you can still do it easily. This solution should work on both iOS and Mac. (note: I'm typing it here, not tested)
@interface NSDate (CLRTicks)
+(NSDate*)dateWithCLRTicks:(long)ticks;
@end
@implementation NSDate (CLRTicks)
+(NSDate*)dateWithCLRTicks:(long)ticks
{
return [NSDate dateWithTimeIntervalSince1970: (ticks-621355968000000000L)/10000000.0]
}
@end
It is basically the same solution Nicholas posted, except in a better form. You should probably make it even better by defining the constants symbolically.
Upvotes: 1
Reputation: 74277
This C# code might help you:
// The Unix epoch is 1970-01-01 00:00:00.000
DateTime UNIX_EPOCH = new DateTime( 1970 , 1 , 1 ) ;
// The Unix epoch represented in CLR ticks.
// This is also available as UNIX_EPOCH.Ticks
const long UNIX_EPOCH_IN_CLR_TICKS = 621355968000000000 ;
// A CLR tick is 1/10000000 second (100ns).
// Available as Timespan.TicksPerSecond
const long CLR_TICKS_PER_SECOND = 10000000 ;
DateTime now = DateTime.Now ; // current moment in time
long ticks_now = now.Ticks ; // get its number of tics
long ticks = ticks_now - UNIX_EPOCH_IN_CLR_TICKS ; // compute the current moment in time as the number of ticks since the Unix epoch began.
long time_t = ticks / CLR_TICKS_PER_SECOND ; // convert that to a time_t, the number of seconds since the Unix Epoch
DateTime computed = EPOCH.AddSeconds( time_t ) ; // and convert back to a date time value
// 'computed' is the the current time with 1-second precision.
Once you have your time_t
value, the number of seconds since the Unix epoch began, you should be able to get an NSDATE in Objective-C thusly:
NSDate* myNSDate = [NSDate dateWithTimeIntervalSince1970:<my_time_t_value_here> ] ;
Upvotes: 5
Reputation: 5316
Did not do all the computations, but your leap year computation is incomplete.
You get a leap year every 4 years. But you skip one every 100 years. And you do not skip it every 400, which is why 2000 was a leap year but 1900 was not.
For example:
2012 is a leap year (divisible by 4 but not 100) 2100 is not a leap year (divisible by 100 but not 400) 2400 is a leap year (divisible 400)
In cocoa you can use NSDate.
NSDate* reference = [NSDate dateWithString:@"0001-01-01 00:00:00 +0000"];
NSDate* myDate = [NSDate dateWithTimeInterval: (ticks/10000000.0)
sinceDate: reference];
Upvotes: 0