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



我正在使用核心蓝牙写入外围设备。我想将当前的 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 小时制值,如下所示:"16:42:96">

我在哪里犯了错误?

编辑

我已经修改了代码以摆脱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]; 

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

您需要更改代码以使用uint64_t或uint32_t因为 Unix 时间戳比 32 位整数容纳的数字大得多。(我建议使用uint64_t。

(有关示例时间戳值,请参阅 @DonMag 的评论,如 1491580283(

一旦外围设备收到该时间,您如何显示该时间是一个单独的问题,也是您真正应该问的问题。

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

没有必要

使用 NSDateFormatter ,除非您打算向外围设备发送字符串表示形式。

来自 Apple Developer 文档:

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

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

uint32_t timestamp = [measureTime timeIntervalSince1970];

如果不了解外围设备的细节,就不可能说出为什么它显示 24 小时值。

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

最新更新