【问题标题】:Convert time_t to little endian?将 time_t 转换为小端?
【发布时间】:2014-10-10 22:46:04
【问题描述】:

我正在将NSDate 转换为 Unix 时间。问题是,我需要将其转换为小端,以便可以通过蓝牙发送;但我不知道如何将time_t 转换为小端。

我目前所拥有的:

time_t t = [date timeIntervalSince1970];

NSMutableData * date = [[NSMutableData alloc] init];
[data appendBytes:&t length:sizeof(t)];

我得到了什么:

0x10603854 // Fri, 15 Sep 1978 21:02:12 GMT

我需要什么:

0x54386010 // Fri, 10 Oct 2014 22:39:12 GMT

【问题讨论】:

  • 这不是一个普通的老 C 问题吗?
  • (在我看来你已经有了 little-endian。)

标签: objective-c endianness


【解决方案1】:

确保特定值的字节顺序的最简单方法是使用NSSwapHostXYZToLittleNSSwapHostXYZToBig(其中XYZ 是类型)。有关这些功能的更多信息,请访问at this Foundation Functions reference page

我认为对于 OS X 和 iOS,time_tlong,所以如果你想保证值是 little-endian,你想使用 NSSwapHostLongToLittle。要转换回来,请使用NSSwapLittleLongToHost。同样,如果要转换为大端,可以使用NSSwapHostLongToBig,要转换回来,可以使用NSSwapBigLongToHost

如果您已经在 little-endian 架构上执行代码,这些函数将变为无操作。

time_t t = NSSwapHostLongToLittle([date timeIntervalSince1970]);
NSMutableData *date = [[NSMutableData alloc] init];
[data appendBytes:&t length:sizeof(t)];

【讨论】:

  • 这更干净,事实上,我的问题是倒过来的,应该是 Big,所以 NSSwapHostLongToBig 为我返回了正确的格式。
  • 在 iOS 和 Mac OS X 上,time_tint64_t,在 64 位平台上是 long,在 32 位平台上是 long long
  • @CuriousRabbit:我不确定这是不是真的,使用-arch i386 编译时打印sizeof(time_t) 会得到4,而不是8,表明它可能仍然只是long 或可能只是int
  • 是的,我错了。两者都是long。即,32 位架构上的 32 位和 64 位架构上的 64 位。谢谢你的纠正。我不确定我的错误假设来自哪里,但我不会忘记它。
【解决方案2】:

如果您通过蓝牙进行通信,那么可能另一端的设备具有一些固定要求,例如“4 字节,小端,自 1970 年以来的秒数”。您需要根据该设备编写代码。如果您的代码在 64 位系统上运行,则 time_t 不太可能是 32 位数字,但您正在与之交谈的设备不知道这一点,并且仍然需要 32 位。

您应该查看存储了多少字节序数,然后编写将四个字节以正确顺序放入您的 NSData 的代码。

【讨论】:

    【解决方案3】:

    不是最优雅的方式。

    NSMutableData *time_ = [[NSMutableData alloc] init];
    time_t t = [date timeIntervalSince1970];
    [time_ appendBytes:&t length:4];
    
    unsigned char *bytePtr = (unsigned char *)[time_ bytes];
    NSString* _time = [NSString stringWithFormat:@"%02X%02X%02X%02X", bytePtr[3], bytePtr[2], bytePtr[1], bytePtr[0]];
    
    for (i = 0; i < 4; i++)
    {
        if (_time.length > i*2)
        {
            byte_chars[0] = [_time characterAtIndex:i*2];
            byte_chars[1] = [_time characterAtIndex:i*2+1];
            whole_byte = strtol(byte_chars, NULL, 16);
            [data appendBytes:&whole_byte length:1];
        }
    }
    
    NSLog(@"_time_data %@", _time);
    

    输出:

    2014-10-13 16:54:59.766 wrightscs[20810:2929687] _time_data

    时间戳转换:

    十六进制时间:543c4a31

    格林威治标准时间:2014 年 10 月 13 日星期一 21:54:57 GMT

    您的时区:CDT 2014 年 10 月 13 日下午 4:54:57

    十进制时间戳/纪元:1413237297

    http://www.epochconverter.com/epoch/unix-hex-timestamp.php

    【讨论】:

    • 虽然这种方法对我有用并且我会继续使用,但@dreamlax 的答案要干净得多。
    猜你喜欢
    • 2012-03-18
    • 2013-03-22
    • 2015-03-22
    • 1970-01-01
    • 2011-03-14
    • 2013-10-24
    • 2013-06-23
    • 2015-05-06
    相关资源
    最近更新 更多