How to convert NSTimeInterval to int? - iphone

How do I convert NSTimeInterval into an Integer value?
My TimeInterval holds the value 83.01837. I need to convert it into 83. I have googled but couldn't find any help.

Direct assignment:
NSTimeInterval interval = 1002343.5432542;
NSInteger time = interval;
//time is now equal to 1002343
NSTimeInterval is a double, so if you assign it directly to a NSInteger (or int, if you wish) it'll work. This will cut off the time to the nearest second.
If you wish to round to the nearest second (rather than have it cut off) you can use round before you make the assignment:
NSTimeInterval interval = 1002343.5432542;
NSInteger time = round(interval);
//time is now equal to 1002344

According to the documentation, NSTimeInterval is just a double:
typedef double NSTimeInterval;
You can cast this to an int:
seconds = (int) myTimeInterval;
Watch out for overflows, though!

In Swift 3.0
let timestamp = round(NSDate().timeIntervalSince1970)

I suspect that NSTimeInterval values from NSDate would overflow an NSInteger. You'd likely want a long long. (64 bit integer.) Those can store honking-big integer values (-2^63 to 2^63 -1)
long long integerSeconds = round([NSDate timeIntervalSinceReferenceDate]);
EDIT:
It looks like an NSInteger CAN store an NSTimeInterval, at least for the next couple of decades. The current date's timeIntervalSinceReferenceDate is about 519,600,000, or about 2^28. On a 32 bit device, and NSInteger can hold a value from -2^31 to 2^31-1. (2^31 is 2,147,483,648

Swift 4, Swift 5
I simply cast to Int64:
Int64(Date().timeIntervalSince1970)

I had a need to store an NSDate in a Swift Number. I used the following cast which is working great.
Double(startDateTime.timeIntervalSince1970)

Related

Time as a value to compare against my value

How can I display time as a number value for an if statement?
I'm trying to write an if statement where a set time is compared against my computed time for an event to occur. I just don't know how to write that time as a value. how can I write a time like 10am as a set time value for example.
Any help is much appreciated.
You can use the NSDate class and the timeIntervalSinceDate: method to compare the two times. You need to set up the two NSDate objects with the different times (and the same date) and then call that method to compare the two.
The easiest way to do this is probably to convert the time to a UNIX timestamp (unsigned integer representing the number of seconds which have elapsed since january 1st 1970)
convert both times to this format and compare.
time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970];
To compare two dates use:
- (NSComparisonResult)compare:(NSDate *)anotherDate
Here is the definition of NSComparisonResult:
enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};
typedef NSInteger NSComparisonResult;

Different results for the same function

Can someone clarify to me please why past2 is NOT negative when this code is run? Even though past is.
Thanks.
NSTimeInterval p1 = (arc4random()%600000);
NSTimeInterval past = -p1;
NSTimeInterval past2 = -(arc4random()%600000);
arc4random() returns an unsigned int (u_int32_t), so trying to make it negative is coercing the result to unsigned as well, which is why you're getting a very large positive number instead of a negative number.
If you want to get a negative random result in one call, try:
NSTimeInterval past2 = - (int) (arc4random()%600000);
joe

Check if NSTimeInterval equals 0

//Gets the time right now
NSDate *now = [NSDate date];
//Stores the difference in seconds between when the test was started and now.
NSTimeInterval interval = [self.expires timeIntervalSinceDate:now];
if (interval == 0) {
...
}
Any reason why the condition wont be true?
Thanks.
Since NSTimeInterval is only a double, you might have floating point rounding error. Try using something like
if (abs(interval) < EPS) {
where EPS is a small enough constant.
Or, if you want to know seconds and not milliseconds, you can truncate that double to int.
But judging from your code, I think you might want to check if timeline has already expired, not that it expires at this exact moment. Probability of the later is very small. This should do the trick.
if (interval < 0) {

Convert a string of numbers to a NSTimeInterval

I know I must be over-complicating this because it NSTimeInterval is just a double, but I just can't seem to get this done properly since I have had very little exposure to objective c. the scenario is as follows:
The data im pulling into the app contains two values, startTime and endTime, which are the epoch times in milliseconds. The variables that I want to hold these values are
NSTimeInterval *start;
NSTimeInterval *end;
I decided to store them as NSTimeIntervals but im thinking that maybe i ought to store them as doubles because theres no need for NSTimeIntervals since comparisons can just be done with a primitive. Either way, I'd like to know what I'm missing in the following step, where I try to convert from string to NSTimeInterval:
tempString = [truckArray objectAtIndex:2];
tempDouble = [tempString doubleValue];
Now it's safely stored as a double, but I can't get the value into an NSTimeInterval. How should this be accomplished? Thanks
You don't have to cast, you can just write this:
NSTimeInterval timeInterval = [[truckArray objectAtIndex:2] doubleValue];
The cast is needless, and extra casts just make your source code harder to update and change in the future because you've told the compiler not to type-check your casted expressions.
The variables that I want to hold these values are NSTimeInterval *start; NSTimeInterval *end;
Careful, NSTimeInverval is a typedef for a primitive C type, it is not an Objective-C object. I don't think you actually need pointers to these types in this scenario, so you should declare them like this:
NSTimeInverval start;
NSTimeInterval end;
You could be getting errors because in C, you cannot convert floating-point types to pointer-types.

Incorrect value for sum of two NSIntegers

I'm sure I'm missing something and the answer is very simple, but I can't seem to understand why this is happening. I'm trying to make an average of dates:
NSInteger runningSum =0;
NSInteger count=0;
for (EventoData *event in self.events) {
NSDate *dateFromString = [[NSDate alloc] init];
if (event.date != nil) {
dateFromString = [dateFormatter dateFromString:event.date];
runningSum += (NSInteger)[dateFromString timeIntervalSince1970];
count += 1;
}
}
if (count>0) {
NSLog(#"average is: %#",[NSDate dateWithTimeIntervalSince1970:(NSInteger)((CGFloat)runningAverage/count)]);
}
Everything seems to work OK, except for runningSum += (NSInteger)[dateFromString timeIntervalSince1970], which gives an incorrect result. If I put a breakpoint when taking the average of two equal dates (2009-10-10, for example, which is a timeInterval of 1255125600), runningSum is -1784716096, instead of the expected 2510251200.
I've tried using NSNumber and I get the same result. Can anybody point me in the right direction?
Thanks!
Antonio
Is there some reason you are fudging about with NSInteger?
[NSDate timeIntervalSince1970] returns an NSTimeInterval, which is basically a double. Clean up the code and see if that helps.
NSInteger can hold values up to the INT_MAX limit that equals 2147483647 - so your value overflows the integer types limit - remember that timeInterval is a double type.
You can try to use double type in all your calculations or use -timeIntervalSinceReferenceDate method - it returns interval since 1 January 2001 and you might avoid overflow as well.
If your events object is an array or other type that allows to get its size then you can add time interval values already divided by count - that also may help to avoid overflow:
NSTimeInterval runningSum = 0;
NSInteger count = [self.events count];
for (...){
...
runningSum += [dateFromString timeIntervalSince1970]/count;
}
NSInteger is a 32 bit signed integer on iPhone and is therefore limited to values between −2147483648 and +2147483647.
You may get the desired result by using NSUInteger which is an unsigned 32 bit integer able to contain values between 0 and +4294967295.
You should however pay attention to the number of runs through the loop so you don't wrap the values.