4

I want to nslog the device motion timestamp property .

The device motion is in the class CMMotionManager.devicemotion.timestamp

Any ideas.

Abdul Samad
  • 5,748
  • 17
  • 56
  • 70

2 Answers2

11

Here the solution I put in place because the date is according to Apple documentation :

The time stamp is the amount of time in seconds since the phone booted.

I first save the originDate at the first mesure (if my NSDate is nil).

[self.motionManager startGyroUpdatesToQueue:self.queue withHandler:^(CMGyroData *gyroData, NSError *error) {
    if (self.originDate == nil) {
        self.originDate = [NSDate dateWithTimeIntervalSinceNow:-gyroData.timestamp];
    }   
}];

Then I can display when I want the real date like this :

[NSDate dateWithTimeInterval:mygyroData.timestamp sinceDate:self.originDate]

Don't forget to reset the originDate to nil if you need to restart some mesure.

Nicolas Lauquin
  • 1,517
  • 3
  • 14
  • 23
  • After trying many variations of @ben-mosher's approach, I think this approach is best. It's a bit more of a pain to implement, but it doesn't rely on internal implementation details of -[NSProcessInfo systemUptime] and is thus a more defensive solution. – William henderson Feb 29 '16 at 23:23
6

Edit: Please see Nicolas Lauquin's answer. Per the comments, the following solution is not correct but is retained here for history (and because I can't delete it since it is currently marked accepted).


The timestamp property is an NSTimeInterval, so you should be able to do:

NSLog(@"Motion at time: %@",
[NSDate dateWithTimeIntervalSinceReferenceDate:devicemotion.timestamp]);

NSTimeInterval is just a typedef'd double type, so you could use %f instead of %@ and log it directly.

Also, the docs don't indicate whether this timestamp is set against Apple's reference date or the standard *nix date, so you may need to use [NSDate dateWithTimeIntervalSince1970:] if the aforementioned method returns dates far in the future.

As @davidbitton has suggested the CMDeviceMotion's timestamp is relative to the last device boot, the correct NSDate could be derived by

NSDate *startupTime = [NSDate dateWithTimeIntervalSinceNow:
                          -1 * [[NSProcessInfo processInfo] systemUptime]];

NSDate *deviceMotionDate = [NSDate dateWithTimeInterval:devicemotion.timestamp 
                                              sinceDate:startupTime];

This should yield a roughly accurate NSDate object, assuming @davidbitton is correct. (reference: NSProcessInfo -systemUptime)

However, given how complicated this is, I would now suggest for simplicity that, given the nature of the timestamp property, that you log it in a format string as something like

"... event logged at %0.2f seconds since startup...", devicemotion.timestamp
Ben Mosher
  • 13,251
  • 7
  • 69
  • 80
  • 5
    This doesn't work because the timestamp for a device motion sample is an NSTimeInterval from when the device was last booted. It is NOT from either of the common epochs of 1/1/2001 or 1970. – davidbitton Jul 08 '12 at 22:56
  • @davidbitton + flaggers + downvoter: updated with a (convoluted?) way to derive an `NSDate` given that the `CMDeviceMotion.timestamp` property is based on uptime. – Ben Mosher Feb 03 '14 at 16:16
  • 1
    This does not work either. -[NSProcessInfo systemUptime] will not give you the correct value while the CPU is asleep. – William henderson Feb 29 '16 at 23:10
  • Wild. I don't think the CPU could be asleep when I wrote this. That's pretty cool. – Ben Mosher Mar 01 '16 at 20:47