我在努力实现一件微不足道的事情:我需要存储构建时间的整数32位unix时间戳,但我找到的所有宏(__DATE__
,__TIME__
,__TIMESTAMP__
)都扩展为字符串,而不是整数。
看起来,我们只是没有它(这对我来说很奇怪)。我真的希望有整数,而不是字符串。
有哪些最佳实践可以实现这一目标?
- 统一采购司:**
作为旁注:我做嵌入式的东西,所以我没有足够的资源(比如说,128KB的闪存),因此解析字符串真的是个坏主意。
我为什么需要它:我只需要有每个测试版版本号唯一。首先,十六进制文件将命名为my-firmware-v2-33-BETA-1397315745.hex
,其次,当我需要在设备的屏幕上显示当前版本,我可能要回显它在各种格式。
9条答案
按热度按时间w8rqjzmb1#
所以,今天晚上我玩得很开心,用宏创建了一个头文件来生成UNIX时间戳,没有任何外部程序或特殊的编译器特性!只需包含头文件并使用
__TIME_UNIX__
宏。实际上代码非常简单:
1.字符串中的数字字符转换为数字,
str[i]-'0'
为 * loreb * 建议值,并根据其位置进行加权。1.月份字符串的处理类似于 * chux * answer;逐个检查字符,并用
? :
算子将其作为一个组来评估。1.计算最近几个月的天数是使用交换表达式
? :
完成的。1.闰年计算很简单,因为在UNIX时间框架内每4年插入一个闰日
1.最后,所有单个值都用各自的秒数加权,得到UNIX时间。注意,
SEC_PER_DAY
必须减去一次,因为JAN 01 1970, 00:00:00
必须是0
。代码已在ATMEL Studio 7(Visual Studio 2015)中使用默认编译器和设置(avr-gcc、-O1优化)进行了测试,并通过检查生成的. lss文件确认了结果。
将下面的代码复制粘贴到一个头文件中,并将其包含在任何需要的地方。
初始版本没有考虑100和400年模对2月天数的影响,这在2001年和2101年之间应该不是问题,但这里有一个更通用的宏:
mpbci0fu2#
您可以在每次构建时生成一个
timestamp.h
文件作为预构建步骤,并将该文件包含在您的源代码中。我不知道您使用的是什么构建工具(嵌入式世界非常广泛),但迄今为止我看到的每一个构建工具都允许用户定义自定义预构建和构建后步骤(Freescale CodeWarrior、AVR Studio、MSVS...)。例如,在Windows上的AVR Studio中,我使用了此预构建步骤(请注意,
$(SolutionDir)
是特定于AVR stuio的,它基于MSVS,您可以替换为您需要的任何文件系统路径):在项目的一个C文件中,我通常会包含这个生成的文件(您到该文件的路径可能不同...):
生成的文件如下所示:
因此,当我单击“构建项目”时,工作室首先运行我的命令,生成新的
timestamp.h
,然后将其用作任何其他C文件中的include。请注意,上面的例子使用Cygwin(
C:\cygwin\bin\date +%s
)来获取时间戳。如果您不想使用Cygwin,您将不得不找到一些其他的方法来让Windows为您生成时间戳。您可以编写自己的命令行实用程序(它应该是大约10行代码的C:-)或搜索互联网的一些其他方法。bbmckpt73#
为什么不在命令行中定义它呢?
62lalag44#
这只是一个更紧密,更轻的版本开发的@nqtronix的版本以上。享受!
注意:此宏忽略世纪,因此仅在2000-01- 01,00:00:00和2099-12- 31,23:59:59之间有效。
sg3maiej5#
看看下面的暴行:
在我的计算机上gcc -O能够将其优化为一个常数值;要获得完整的
time_t
,您需要一个__DATE__
的兄弟宏,并查看生成的程序集。如果有人问起,就说这不是我写的;)
编辑:为了清楚起见,您可能应该按照Roman Hocke的答案编写一个简短的C程序来为您生成值(当然,如果您正在进行交叉编译,您应该小心一点...)
w6mmgewl6#
编辑:根据@ Lu Vnh Phúc的评论,似乎关键的想法需要解释:* 所有 * 计算都在 * 编译 * 时完成。参见下面生成的OP代码。
下面的代码不是生成
time_t
,而是在编译器的时区中生成struct tm
。如果需要,调用mktime()
将返回time_t
。在其他应用程序中,不是返回
struct tm
,而是每个字段赋值简单地打印值以显示版本。下面的冗长代码在PIC编译器中生成的指令很少,因为它优化了很多。类似的方法可以使用
__TIMESTAMP__
。列名
uajslkp67#
我发现如果某个月的某一天小于10,则必须添加一个特殊检查,否则将返回一个负数
flseospp8#
因为您使用的是C++,所以我认为您可以使用constexpr函数在编译时解析
__DATE__ __TIME__
字符串。如:
我尝试使用GCC和-O3标志,结果如下:
PictureGodBolt
gcuhipw99#
对我来说,使用@Potion答案https://stackoverflow.com/a/58314096/5949219,除了DAY_OF_MONTH没有减1,所以它变成: