多个设备中[NSDate date]的结果不同

时间:2013-12-06 14:07:26

标签: ios iphone udp nsdate gcdasyncsocket

首先,我必须说我在日期和时间设置中设置了自动设置,并且每个设备的时区都相同。所以我使用[NSDate date]以毫秒为单位获取时间戳,然后编码为NSData并发送到另一台设备。接收器数据正在被解码并用新的[NSDate date]减去。这样我就可以获得发送和接收消息所需的总时间。我被认为是因为当发送者是iPhone 4 iOS6而接收者是iPhone 5 iOS7时接收者比发送者有更早的时间戳。我不知道为什么?也许[NSData date]不是那种操作最可靠的类?我使用GCDAsyncUdpSocket发送/接收UDP。

代码发件人

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++;

代码接收器

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]);

4 个答案:

答案 0 :(得分:6)

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]];

我遇到了同样的问题,并通过设置 NSLocale 解决了这个问题。我希望这个解决方案也适合你。

答案 1 :(得分:1)

不要使用长期的NSDate的timeIntervalSince1970 * 1000.使用timeIntervalSince1970表示为double,直接。这将保存日期的所有分辨率。

只需在数据中添加sizeof(double)的字节。

在发送之前记录double值及其字节流,并在远程设备上收到double值及其字节流并进行比较。

如果两个设备都是同一网络上的电话,并且您可以让它们自动设置时钟(设置>一般>日期和时间),那么它们的时钟应该在几分之一秒内同步。

答案 2 :(得分:1)

  

正在解码接收器数据并使用新的[NSDate date]

进行减法

这就是问题所在。它与设备上安装的iOS版本无关:通常,如果您的时间戳由不同的计算机生成,则无法减去它们,并且期望从中获得任何精度,因为设备时钟不同步足以衡量网络延迟,因为clock skew

考虑这个简单的例子:让我们说计算机Alice和Bob上的时钟相隔10秒:当Alice的时钟显示为12:00:00时,Bob的时钟显示为12:00:10。

Alice向Bob发送了时间戳,即14:23:06。它需要一秒钟到达鲍勃,现在鲍勃看到包裹到达时14:23:17。如果Bob简单地从他自己的时间戳中减去Alice的时间戳,他会得出结论,该程序包需要11秒才能到达它。

如果鲍勃现在给爱丽丝发送他的时间戳 - 让我们说它是14:23:18,爱丽丝会在一秒后收到它,爱丽丝的时钟将是14:23:09。现在爱丽丝会得出结论,包裹花了-9(是的,负九!)秒来到达它,这根本就没有意义。

幸运的是,如果假设往返的两条腿的延迟相同是公平的,您可以通过分解时钟偏差来测量延迟。我们的想法是获得两对时间戳,这两个时间戳的构造方式使得时钟偏差是两对中的一个因子,但是偏斜的符号是相反的。

考虑上例中的时间戳:

A1=14:23:06 B1=14:23:17
B2=14:23:18 A2=14:23:09

每对A1-B1和B2-A2都包含歪斜,但在第一对中,歪斜为正,而在第二对中,歪斜为负。 因此,如果你平均两个时差,你最终会得到往返延迟

((B1-A1)+(A2-B2)) / 2 =
(11 + -9) / 2         =
2 / 2                 = 1 second

这应该足以让您实现一个简单的程序来测量系统中的往返延迟。

答案 3 :(得分:0)

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;