Different result for [NSDate date] in several devices - ios

To start, I have to say that I set autoset in date&time settings and time zone is the same for each device. So I use [NSDate date] to get time stamp in milliseconds, then encode to NSData and send to another device. On receiver data is being decoded and subtract with new [NSDate date]. So that I get total time needed for send and receive message. That I was thought because when sender is iPhone 4 iOS6 and receiver is iPhone 5 iOS7 then receiver have earlier time stamp than sender. I don't know why? Maybe [NSData date] isn't the most reliable class for that kind of operations? I use GCDAsyncUdpSocket for sending/receiving UDP.
Code sender
NSData *data2 = [self createRandomNSData:8192];
NSMutableData *dataToSend =[NSMutableData data];
[dataToSend appendBytes:&tag length:sizeof(int)];
long long currentTimeStamp = (long long)([[NSDate date] timeIntervalSince1970]*1000.0);
[dataToSend appendBytes:&currentTimeStamp length:sizeof(long long)];
[dataToSend appendData:data2];
NSLog(#"%i || %lld || %lu",tag, currentTimeStamp,(unsigned long)[dataToSend length]);
[_udpSocket sendData:dataToSend toHost:#"230.0.0.1" port:_port withTimeout:-1 tag:tag];
tag++;
Code receiver
char* dataBytes = [data bytes];
int inTag;
long long inCurrentTimeStamp;
[data getBytes:&inTag length:sizeof(int)];
[data getBytes:&inCurrentTimeStamp range:NSMakeRange(sizeof(int), sizeof(long long))];
long long currentTimeStamp = (long long)([[NSDate date] timeIntervalSince1970]*1000.0);
long long timeStampDiff = currentTimeStamp - inCurrentTimeStamp;
self.delay = timeStampDiff;
NSLog(#"%i || %lld || %lu",inTag, timeStampDiff,(unsigned long)[data length]);

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy hh:mm:ss"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
NSString *strSystemTime = [dateFormatter stringFromDate:[NSDate date]];
I faced the same issue and resolved it by setting NSLocale. I hope this solution works for you too.

Don't use a long long of the NSDate's timeIntervalSince1970 * 1000. Use the timeIntervalSince1970 expressed as a double, directly. That will save all the resolution of the date.
Simply add bytes to your data that are the sizeof(double).
Log the double value and it's byte stream before sending, and the double value and it's byte stream on receipt on the remote device and compare them.
If both devices are phones on the same network, and you have them to set their clocks automatically (settings>general>date and time) then their clocks should be synchronized within a fraction of a second.

On receiver data is being decoded and subtract with new [NSDate date]
That's the problem. It has nothing to do with the iOS version installed on the device: in general, if your timestamps are produced by different computers, you cannot subtract them, and expect any kind of precision to come out of it, because the device clocks are not synchronized enough to measure network latency, because of clock skew.
Consider this simplistic example: let's say the clocks on computers Alice and Bob are 10 seconds apart: when Alice's clock shows 12:00:00, Bob's clock shows 12:00:10.
Alice sends Bob its timestamp, which says 14:23:06. It takes the package one second to reach Bob, now Bob sees 14:23:17 when the package arrives. If Bob simply subtracts Alice's timestamp from his own, he would conclude that the package took 11 seconds to reach it.
If Bob sends Alice his timestamp now - let's say it's 14:23:18, Alice would receive it one second later, which by Alice's clock would be 14:23:09. Now Alice would conclude that the package took -9 (yes, negative nine!) seconds to reach it, which makes no sense at all.
Fortunately, if it is fair to assume that the latency is the same on both legs of the round-trip, you can measure the latency by factoring out the clock skew. The idea is to obtain two pairs of timestamps constructed in such a way that the clock skew is a factor in both pairs, but the sign of the skew is opposite.
Consider the timestamps from the above example:
A1=14:23:06 B1=14:23:17
B2=14:23:18 A2=14:23:09
Each pair, A1-B1 and B2-A2, contain the skew, but in the first pair the skew is positive, while in the second pair it is negative. Hence, if you average the two time differences, you would end up with your roundtrip delay.
((B1-A1)+(A2-B2)) / 2 =
(11 + -9) / 2 =
2 / 2 = 1 second
This should be enough for you to implement a simple program for measuring the roundtrip latency in your system.

long intervalValue= (long)([[NSDate date] timeIntervalSince1970]);
NSString *intervalString =[NSString stringWithFormat:#"%ld",intervalValue];
int dif=13-[intervalString length];
for (int k=0; k<dif; k++) {
intervalString=[NSString stringWithFormat:#"%#0",intervalString];
}
unsigned long long convertedValue=[intervalString longLongValue]+0530;

Related

How to get int value of time stamp which includes milliseconds in objective c

NSNumber * uniqueId = [NSNumber numberWithInt:([[NSDate date] timeIntervalSince1970])];
Milliseconds is not included in the above code.If i used like below code ,it is printing negative values.
NSNumber * uniqueId1 = [NSNumber numberWithInt:([[NSDate date] timeIntervalSince1970] * 1000)];
Can we get time stamp with milliseconds as int????
#AnjaniG you can use one of them..
NSString *strTimeStamp = [NSString stringWithFormat:#"%f",[[NSDate date] timeIntervalSince1970] * 1000];
int timestamps = [strTimeStamp intValue];
NSLog(#"number int = %d",timestamps);
You should not use an Int, [[NSDate date] timeIntervalSince1970] * 1000 is bigger than INT_MAX. You should use long long to store the value.
NSNumber * uniqueId1 = [NSNumber numberWithLongLong:([[NSDate date] timeIntervalSince1970] * 1000)];
The problem is that you are casting a floating point to an integer.
As per the documentation, timeIntervalSince1970 returns an NSTimeInterval, which is a double, not an integer.
In your first code example, you're actually discarding the milliseconds by casting.
In your second code example, you are overflowing the integer. After multiplying the value by 1000, it is too large to fit in an integer.
In the end, you're just doing too much code and you shouldn't need to really worry about this.
NSTimeInterval interval = [NSDate date].timeIntervalSince1970;
NSNumber *timestamp = #(interval * 1000.);
Here, I use the proper documented type of NSTimeInterval. Then I multiply that by 1,000 to change seconds to milliseconds. Finally, I use Clang literal syntax to instruct the compiler to create the appropriate NSNumber.

Convert NSDate to Unix Time Stamp for use in Dictionary

While there are numerous examples on SO and the web of converting the current date to a unix timestamp, I can't seem to find one for any date.
This code produces error shown.
NSDate *date = self.datepicker.date;
time_t start = (time_t) [date timeIntervalSince1970];//collection element of time_t is not an objective-c object
Would appreciate any suggestions.
I believe that code will work and the error message relates to a different statement.
If you want to put that time_t into a dictionary then you'll need to wrap it in an NSNumber object. However you may as well keep it as an NSTimeInterval (double) and cast it when using it:
NSDate *date = self.datepicker.date;
NSTimeInterval start = [date timeIntervalSince1970]
dict[#"startTime"] = #(start);
However you can also cast it before adding it to the dictionary if you really want to.

How can I get the fileCreationDate to an accuracy of 6 decimal places when converted using timeIntervalSince1970?

How can I get the fileCreationDate for a file stored in the NSDocumentsDirectory to an accuracy of 6 decimal places when converted to an NSTimeInverval?
Some code:
//Not accurate enough:
NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:myPhotoPath error:nil];
NSDate *creationDateOfPhoto = [fileAttribs fileCreationDate];
NSTimeInterval creationDateAsTimeInterval = [creationDateOfPhoto timeIntervalSince1970];
NSLog(#"Creation Date of Photo As Time Interval Since 1970: %f", creationDateAsTimeInterval);
//With the desired accuracy:
NSDate* now = [NSDate date];
NSTimeInterval nowStampAsTimeInterval = [now timeIntervalSince1970];
NSLog(#"Now As Time Interval Since 1970: %f", nowStampAsTimeInterval);
A sample output from this code is:
Creation Date of Photo As Time Interval Since 1970: 1373022866.000000
Now As Time Interval Since 1970: 1373022884.294028
Is it possible or is it a limitation of storage in NSDocuments?
It's a OS level limitation. HFS+, the file system which is used by iOS, has a date resolution of one second - this is why all your file timestamps are whole seconds. Sub second precision isn't supported. Sorry!

Accurate time on iPhone

Is there an way to get a time very precisely in iPhone.? Currently i am trying with the ios NTp client Here . I am getting almost 600 milliseconds difference while comparing with different divices . Even i am not worrying about the accurate time like ntp , I want to show same time with milliseconds in different devices.
Check out this NTP client library for iOS: https://code.google.com/p/ios-ntp/
Source: 1
This is simple way to do this go through it :-
+ (NSDate *) GMTNow
{
NSDate *sourceDate = [NSDate date];
NSTimeZone* currentTimeZone = [NSTimeZone localTimeZone];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMT];
[sourceDate dateByAddingTimeInterval:currentGMTOffset];
return sourceDate;
}

Trying to do some simple calculations in iOS project?

I want to know how to do some simple equations in my iOS app, if anyone could point me in the right direction that would be wonderful!
I need to know how to convert an NSNumber that represents minutes to an NSString which represents hours and minutes (example: 100 = 1 hour and 40 minutes)
I also want to know if its possible to convert something like 2013-02-08T10:50:00.000 to 10:50AM
Thanks for any tips you guys might have.
For the conversion :
NSNumber *yourNumber = [NSNumber numberWithInt100];
NSInteger hour = [yourNumber intValue] / 60;
NSInteger minutes = [yourNumber intValue] % 60;
NSString *time_stamp = [NSString stringWithFormat:#"%d hour and %d minutes",hour,minutes];
As the comments suggested you can use NSDateFormatter to format your NSDate.

Resources