可以存储时间戳的最小字节数是多少?

Jus*_*ner 11 c timestamp

我想在C中创建自己的时间戳数据结构.

DAY(0 - 31),HOUR(0 - 23),MINUTE(0 - 59)

可能的最小数据结构是什么?

Dan*_*ant 17

好吧,你可以将它全部打包成一个unsigned short(那是2个字节,5个位表示Day,5位表示小时,6位表示分钟)...并使用一些移位和屏蔽来获取值.

unsigned short timestamp = <some value>; // Bits: DDDDDHHHHHMMMMMM

int day = (timestamp >> 11) & 0x1F;
int hour = (timestamp >> 6) & 0x1F;
int min = (timestamp) & 0x3F;

unsigned short dup_timestamp = (short)((day << 11) | (hour << 6) | min); 
Run Code Online (Sandbox Code Playgroud)

或使用宏

#define DAY(x)    (((x) >> 11) & 0x1F)
#define HOUR(x)   (((x) >> 6)  & 0x1F)
#define MINUTE(x) ((x)         & 0x3F)
#define TIMESTAMP(d, h, m) ((((d) & 0x1F) << 11) | (((h) & 0x1F) << 6) | ((m) & 0x3F)
Run Code Online (Sandbox Code Playgroud)

(你在当前版本的问题中没有提到月/年,所以我省略了它们).

[ 编辑:使用unsigned short- 未签名short.]

  • @ mpez0:只有你喜欢缓慢,臃肿的代码. (5认同)
  • @mpez0:班次和面具是便携式的;对于位域,包含位域的结构的大小取决于实现,位的顺序也是如此。@Jonathan:取决于平台;对于某些嵌入式处理器和编译器,编译后的代码是相同的。 (3认同)

Ken*_*Ken 7

你的意思是0-23和分钟0-59?我听说过闰秒但不是闰秒或小时.

(log (* 31 60 24) 2)
=> 15.446
Run Code Online (Sandbox Code Playgroud)

因此,您可以将这些值拟合为16位或2个字节.这是一个好主意是一个完全不同的问题.


dir*_*tly 5

  • 月份:范围1 - 12 => 4位
  • 日期:范围1 - 31 => 5位
  • 小时:范围0 - 24 => 5位
  • 分钟:范围0 - 60 => 6位

  • 总计:20位

您可以使用位域并使用编译器/平台特定的pragma来保持紧密:

typedef struct packed_time_t {
    unsigned int month  : 4;
    unsigned int date   : 5;
    unsigned int hour   : 5;
    unsigned int minute : 6;
} packed_time_t; 
Run Code Online (Sandbox Code Playgroud)

但你真的需要这个吗?标准时间功能不足够吗?位域根据架构,填充等而有所不同......不是便携式构造.


Chr*_*utz 5

为什么不直接使用 Ctime()函数的(4 字节?)输出NULL作为参数。这只是 Unix 纪元时间(即自 1970 年 1 月 1 日以来的秒数)。就像乔的回答一样,它为您提供比任何试图将数月、数天和数年打包成小块的答案更大的成长空间。这是标准的。time_t在标准 C(至少在 Unix 上)中,将变量转换为实际时间是微不足道的,并且大多数情况下,如果您有一个打算保存 3 字节变量的数据结构,则无论如何它都可能被四舍五入为 4 字节。

我知道您正在尝试针对大小进行大量优化,但是 4 个字节实在是太小了。即使您截断了最高字节,您仍然可以从中获得 194 天的不同时间。

您可以time(NULL)通过在存储之前花费时间并将其除以 60,将其截断为一分钟并存储它来获得更多收益。如上所示,其中 3 个字节为您提供 388 个月,2 个字节您可以存储 45 天。

我会选择 4 字节版本,仅仅是因为我不认为 2、3 和 4 字节之间的区别对于任何正在运行的程序是否重要或至关重要(除非它是引导加载程序)。它更容易获得和处理,并且最终可能会为您省去很多麻烦。

编辑:我发布的代码不起作用。我已经睡了 3 个小时,最终我会弄清楚如何正确地进行处理。在此之前,您可以自己实现这一点。