如何将unix时间戳转换为NSData对象?

时间:2017-04-07 15:22:14

标签: ios objective-c bluetooth nsdata

我使用Core Bluetooth写入外设。我想将当前的unix时间戳发送到传感器,我试图这样做:

// Write timestamp to paired peripheral
NSDate*           measureTime = [NSDate date];
NSDateFormatter*  usDateFormatter = [NSDateFormatter new];
NSLocale*         enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

[usDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.000'Z'"];
[usDateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[usDateFormatter setLocale:enUSPOSIXLocale];  // Should force 24hr time regardless of settings value

NSString *dateString = [usDateFormatter stringFromDate:measureTime];
NSDate* startTime = [usDateFormatter dateFromString:dateString];

uint32_t timestamp = [startTime timeIntervalSince1970];
NSData *timestampData = [NSData dataWithBytes:&timestamp length:sizeof(timestamp)]; // <- Troublemaker
[pairedPeripheral writeValue:timestampData forCharacteristic:currentCharacteristic type:CBCharacteristicWriteWithResponse];

问题在于:

我的32位时间戳返回正确的值,但是当我将其转换为NSData时,外设将其读取为24小时时钟值,如下所示:&#34; 16:42:96&#34;

我在哪里犯错误?

修改

我修改了代码以摆脱NSDateFormatter,因为有人提到它是不必要的。我似乎仍然得到相同的结果:

// Write timestamp to paired peripheral
NSDate*           measureTime = [NSDate date];
uint64_t timestamp = [measureTime timeIntervalSince1970];
NSData *timestampData = [NSData dataWithBytes:&timestamp length:sizeof(timestamp)]; // <- Troublemaker
[pairedPeripheral writeValue:timestampData forCharacteristic:currentCharacteristic type:CBCharacteristicWriteWithResponse]; 

2 个答案:

答案 0 :(得分:1)

你很困惑。你发送到外围设备的是自1970年以来的整数秒。这是发送Unix时间戳的合理方式,但它不是24小时格式的时间,它是一个整数。

您需要更改代码以使用uint64_t或uint32_t,因为Unix时间戳的数字远大于32位整数。 (我建议使用uint64_t。)

(参见@ DonMag关于样本时间戳值的评论,如1491580283)

如果外围设备收到该时间,您如何显示该时间是一个单独的问题,以及您应该问的问题。

请注意,如果外围设备与iOS设备具有不同的“endian-ness”,则可能会遇到将int作为二进制数据发送的问题。您可能希望将时间戳整数转换为字符串并发送它以避免字节序问题。

答案 1 :(得分:0)

除非您计划向外围设备发送字符串表示,否则无需使用NSDateFormatter

来自Apple Developer docs

  

NSDate对象封装单个时间点,与任何特定的日历系统或时区无关。日期对象是不可变的,表示相对于绝对参考日期(2001年1月1日00:00:00 UTC)的不变时间间隔。

考虑到这一点,您可以按原样使用measureTime,并获得相同的结果:

uint32_t timestamp = [measureTime timeIntervalSince1970];

如果不知道外围设备的细节,就不可能说它为何显示24小时值。

如果我冒险猜测,我希望首先需要修改另一个特征/值,以便将其切换为不同的格式(如果可能的话)。