How do I count time in iOS? - objective-c

I don't want to set up a timer that "fires" (and does something) after a certain amount of time has passed.
Therefore, I'm not interested in the NSTimer class and its methods.
All I'm interested in is counting the time that passes by while, for example, some while-loop is executing. I could use NSDate as follows I guess :
NSDate currentDate = [[NSDate alloc] init];
while(someConditionIsTrue)
{
// executing..
}
timeElapsed = [self timeIntervalSinceDate:currentDate];
NSLog(#"time elapsed was: %i", timeElapsed);
However, if I understand correctly, timeIntervalSinceDate: can only count seconds.
Is there a way I can count the time that is passing by in milliseconds?
In other words, what is the smallest unit I can count passing time in and how ?

Look at CFAbsoluteTimeGetCurrent()
CFAbsoluteTime before = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime after = CFAbsoluteTimeGetCurrent();

Your second approach is correct. Save the current date in an NSDate object and use timeIntervalSinceDate: to get the passed time since then. The result will be of type NSTimeInterval which is a floating point number. It specifies time differences in seconds, but since it's a floating point number it can store fractions of a second as well.
NSTimeInterval is always specified in seconds; it yields
sub-millisecond precision over a range of 10,000 years.

Related

Time elapsed when battery increased of 5%

I would like to know if there's a way to get the time elapsed when the battery increased of 5%. For example, how can I know how much time elapsed between 60% and 65% ? I think I could do this with NSTimer, but I'm not able to do this, can someone help me ?
Thanks a lot.
If you are doing this for a Mac, please check this question for how to get battery life in Mac;
If you are doing this for iOS, please check this question for how to get battery life in iOS.
Simply use your NSTimer to fire the function to get the battery life every x seconds and when it gets to 60%, capture a timestamp with NSDate, then when it gets to 65%, capture another timestamp and compare the two timestamps to get the time difference: SO question: how to get time between 2 NSDate objects.
Good luck.
EDIT:
All the methods to get the battery percentage are in either the first or second link based on your platform. If you want it to determine the time between now, and 5% up/down:
//both percent and date should be properties or instance variables (NSDate and float, respectively)
//You should probably also make the timer one as well, so you can stop it in any method with [tmr invalidate];
date = [NSDate date];
percent = [self getBatteryPercent];
NSTimer* tmr = [NSTimer scheduledTimerWithInterval:1 target:self selector:#selector(someMethod) userInfo:nil repeats:YES];
- (float)getBatteryPercent
{
//You'll have to get this code from one of those methods (first or second link)
}
- (void)someMethod
{
float newPercent = [self getBatteryPercent];
if(percent - newPercent == 5.0 || percent - newPercent == -5.0)
{
//Get the time between timestamps
NSDate* newDate = [NSDate date];
//See third link for how to get the time difference between date and newDate
}
}
The rest is up to you.

timeIntervalSinceDate in past?

I'm creating a NSDate in the past (1 hour in the past) and that looks to be setting correct, only thing is I want to then use that to determine if an even has happened or not. Because I set to be in the past, when I do the check it should definitely think the even has happened, but timeIntervalSinceDate seems to only give a positive result?
This is the code I'm using with timeIntervalSinceDate
NSDate *now = [NSDate date];
NSTimeInterval secondsSincePlantingInterval = [now timeIntervalSinceDate:plantingDate];
Which is giving 68 seconds, but it should be -68 seconds, or does it not return negative values?
This is perfectly normal, documented behavior
The documentation states :
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate
Return Value
The interval between the receiver and anotherDate. If the receiver is earlier than anotherDate, the return value is negative.
Since plantingDate is in the past, the receiver is not earlier than it. Therefore the value is positive.
Moreover ; this is plain english
[now timeIntervalSinceDate:plantingDate];
So, the time interval since the plantingDate up to now is positive.
It does return negative values, yes. But if plantingDate is in the past then I'd expect secondsSincePlantingInterval to be positive.
If you think about it, that line is reading:
Tell me the number of seconds now is since plantingDate.
Just like Tuesday 2nd is one day since Monday 1st, now is +ve seconds since plantingDate.
You want:
NSTimeInterval secondsSincePlantingInterval = [plantingDate timeIntervalSinceNow];

timestamp and subtract objective C

I need to find the specific time a tap happens and then the time since it has passed. I have the app counting taps, I just haven't figured out the time thing.
I tried:
timeStamp = [[NSDate date] timeIntervalSince1970];
but I'm new to obj c and clearly there is a syntax problem.
Thanks for anyhelp.
If you are trying to find the amount of time that has passed since an event, I would create an NSDate time stamp when that event occurrs:
NSDate *timestamp = [NSDate date];
Then, later on to check how long it has been since that timestamp you can call:
NSTimeInterval interval = [timestamp timeIntervalSinceNow];
NSTimeInterval is just a typedef. It is actually a double representing a number of seconds. In the above case interval will be the number of seconds since the timestamp. (Also note that it will be negative since your timestamp is in the past.)
The most obvious reason I see for a syntax error would be the declaration of timeStamp.
It should be:
NSTimeInterval timeStamp;

NSString to NSDate with float values

I'm developing an OS X desktop application which will track time for a car racing event.
The difference between pilots can be very small, so the collected data for each lap has a floating point value for the seconds:
bestLap = #"00:01:39.5930000"
But I need to compare each pilot's time and sort it. I'm trying to convert it to a NSDate object, using NSDateFormatter and I couldn't manage to make it work
Is it possible to convert a string like that to a NSDate? If so, how can I compare and sort an array containing NSDates
Thanks
An NSDate is used to represent a date, not a time interval.
Also, if the purpose is just to sort them, there is no need to convert the string into an NSDate or NSTimeInterval since they are already lexicographically ordered if a time interval is shorter than the other in your format.
That means, calling -sortUsingSelector: is enough.
[theMutableArrayOfLaps sortUsingSelector:#selector(compare:)];
As KennyTM says, lexicographic sorting is enough if all you need is ordering. If you really want to get a numeric value for comparison & reporting purposes, you can break the string up into components and convert to a double something like this:
NSArray* parts = [bestLap componentsSeparatedByString:#":"];
double bestLapInSeconds = [[parts objectAtIndex:0] doubleValue] * 3600 // hours
+ [[parts objectAtIndex:1] doubleValue] * 60 // minutes
+ [[parts objectAtIndex:2] doubleValue]; // seconds
(Note that this just blithely assumes that the original string conforms to an "H:M:S" format without any error checking. You should not normally do this in real life!)

Converting JSON date(ticks) to NSDate

Does anyone know how to convert a JSON date(ticks) to an NSDate in Objective-C? Can someone post some code?
I'm guessing here but your JSON value is the number of milliseconds since 1970, right? You can use NSDate's dateWithTimeIntervalSince1970: method to return an NSDate object with the correct time. Just make sure to convert the JSON milliseconds number to seconds before passing it to NSDate-- Cocoa uses NSTimeInterval in most places, which represents an interval in seconds.
It goes roughly like this:
// Input string is something like: "/Date(1292851800000+0100)/" where
// 1292851800000 is milliseconds since 1970 and +0100 is the timezone
NSString *inputString = [item objectForKey:#"DateTimeSession"];
// This will tell number of seconds to add according to your default timezone
// Note: if you don't care about timezone changes, just delete/comment it out
NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
// A range of NSMakeRange(6, 10) will generate "1292851800" from "/Date(1292851800000+0100)/"
// as in example above. We crop additional three zeros, because "dateWithTimeIntervalSince1970:"
// wants seconds, not milliseconds; since 1 second is equal to 1000 milliseconds, this will work.
// Note: if you don't care about timezone changes, just chop out "dateByAddingTimeInterval:offset" part
NSDate *date = [[NSDate dateWithTimeIntervalSince1970:
[[inputString substringWithRange:NSMakeRange(6, 10)] intValue]]
dateByAddingTimeInterval:offset];
(from https://gist.github.com/726910)
You'd have to detect the client's locale in order to be able to do that, and unless your client knows how to do that, there's probably not much point.
NSDate's descriptionWithLocale: would be the way you format it for another locale. And timeIntervalSince1970 will go back to the (seconds) since 1970, which you could multiply by 1000 to get ms to return to the client. It's all in the NSDate documentation.
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
According to this page: http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx ticks begin on Jan 1, 0001 so dateWithTimeIntervalSince1970: is not automatically setup to work with ticks. You can still use this method but should adjust for the difference.