从纪元以来的几秒钟的星期几

时间:2016-04-01 12:58:40

标签: c time

我试图计算自纪元时间戳以来秒数的星期几。从time.h我可以使用gmtime(),但这会使程序增加1.3kB,可能是因为gmtime()也会计算日期。

所以,我想知道使用类似的东西会出现什么问题:

(timestamp / (24*3600)) % 7

我唯一能想到的是闰秒,这样像00:00:02这样的东西可能被归类为错误的一天。

修改 这是针对嵌入式编程的,1.3kB是64kB程序/固件的重要组成部分。此外,我不希望在此之后对时区或日期做任何事情。

2 个答案:

答案 0 :(得分:1)

自从1970年1月1日是星期四以来,您已经关闭了4,并且根据%对负面操作数的行为,您可能会计算出该纪元之前的日期的错误结果。 (最简单的解决方法是检查结果是否为负数,如果是,则添加7.)但除此之外,您的算法是正确的;它与glibc internal function __offtime使用的相同,gmtime最终会调用。 (您无法自己调用它,因为它是内部实现细节)。

没有必要担心闰秒; Unix时间忽略了它们。

我建议将代码封装在(可能是内联的)函数中,并将gmtime实现作为#if 0块的注释,以便在开始需要计算时可以轻松切换到它几个月/几年。

答案 1 :(得分:1)

  

使用类似:(?)

之类的错误
(timestamp / (24*3600)) % 7

上述情况没有太大问题,除非您没有指定纪元开始的星期几(例如星期四),也没有指定星期开始的星期几(例如星期一)。请参阅8601,以便在一周的第一天进行更深入的讨论。还要注意像24*3600这样的计算,这会导致16位int/unsigned导致问题。

示例:让我们说这个时代从星期三开始(星期一:0。星期四:3)。这会同时处理2个问题:时代的星期几和星期的第一天,因为只需要对正差异进行编码。

#define EPOCH_DOW 3
#define SECS_PER_DAY 86400 
dow = ((timestamp / SECS_PER_DAY) + EPOCH_DOW) % 7;

如果timestamp是签名类型,请附加以下内容以确保[0...6]范围内的结果。

dow = (dow + 7) % 7;
// or 
if (dow < 0) dow += 7;  

我怀疑你的应用程序中使用了leap seconds。如果它们是,则任务更复杂,因为代码不仅需要处理更复杂的计算,而且如何接收下一个计划的闰秒的更新 - 它们不规则地发生。 / p>