【发布时间】:2021-06-02 10:39:27
【问题描述】:
背景: 我有一个旧的 Siemens cpu,它将以 date_and_time 格式向我发送总共 8 个字节。这种格式的构造使得前 4 个字节包含时间,最后 4 个字节包含自 1992 年 1 月 1 日以来的日期。
问题:我开始提取最后4个日期来计算日期,使用
long long int dt = 0x60592102FC29000;
char a, b, c, d;
a = (dt & 0xFF);
b = ((dt >> 8) & 0xFF);
c = ((dt >> 16) & 0xFF);
d = ((dt >> 24) & 0xFF);
long int date = int((unsigned char)a << 24 |
(unsigned char)b << 16 |
(unsigned char)c << 8 |
(unsigned char)d);
但是在这部分之后我被卡住了,因为我想不出任何好的方法来计算一天而不循环所有天。
示例:
0x60592102FC29000 等于 2021-06-04 09:55:40.000
0x7A0DC6021C07000 等于 1996-12-24 12:55:34.010
参考资料:
T#0d_0h_0m_0s_0ms 到 T#49d_17h_2m_47s_295ms 值日、小时、分钟、最多两位数 秒,最多三位毫秒 用 T#0d_0h_0m_0s_0ms 初始化
D#1992-01-01 到 D#2200-12-31 考虑闰年,年份有四位数, 月和日各为两位数 用 D#0001-01-01 初始化
Link to siemens way of calculating
我的最终解决方案受以下帖子启发:
//1996-12-24 12:55:34.010
long long int dt = 0x7A0DC6021C070000;
const int dateOffset = 8034;
time_t date_t = 0;
int date =
((dt & 0xFF) << 24) |
(((dt >> 8) & 0xFF) << 16) |
(((dt >> 16) & 0xFF) << 8) |
(((dt >> 24) & 0xFF));
int time =
((dt >> 32 & 0xFF) << 24) |
(((dt >> 40) & 0xFF) << 16) |
(((dt >> 48) & 0xFF) << 8) |
(((dt >> 56) & 0xFF));
tm _dt = *localtime(&date_t);
_dt.tm_mday += dateOffset + date;
_dt.tm_sec += time/1000;
mktime(&_dt);
【问题讨论】:
-
不,当然不需要“整天循环”。计算很简单:1)距离下月初的天数,2)明年同上,3)闰年同上。以这种方式,将天数添加到日期是有限数量的计算,仅涉及基本的日期数学。具体来说,这些计算的哪些部分不清楚?
-
我正在考虑尝试将我的 8 个字节转换为标准 time_t 格式以更好地使用这些功能,但这可能是一个不好的方法?我还需要能够处理循环年
-
这种方法听起来可能可行:将天数乘以 24 个日历日的秒数,并将其添加到纪元开始日中午的 time_t(以避免时区过渡问题),然后使用标准库例程来计算结果日期。对我来说,这似乎是一个已解决的问题。
标签: c++