首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >西门子的日期和时间

西门子的日期和时间
EN

Stack Overflow用户
提问于 2021-06-02 10:39:27
回答 2查看 152关注 0票数 2

背景:我有一个旧的西门子cpu,它将发送给我总共8个字节作为date_and_time格式。这种格式的构造使得4个第一个字节包含时间,最后4个字节包含1992年1月1日以来的日期。

问题:我开始提取最后4个日期来计算一天

代码语言:javascript
复制
    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);

但是在这部分之后,我被困住了,因为我想不出任何好的方法来计算一天,而不用整天循环槽。

示例:

0x60592102FC 29000等于2021-06-04 :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。

连接西门子的计算方法

西门子手册,第107页

我的最后一个解决方案来自下面的帖子:

代码语言:javascript
复制
    //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);
EN

回答 2

Stack Overflow用户

发布于 2021-06-02 11:18:13

我认为你应该帮你自己一个忙,用一个年代图书馆。日期问题是众所周知的困难和容易处理错误。使用计时库,您的问题归结为一些简单的东西,例如

代码语言:javascript
复制
date_time dt=date_time(1992, 1, 1) + days(value);

其中value是西门子CPU返回的值。

boost::在较旧的cpus (包括嵌入式系统)上应该可以使用时间同步或boost::date_time。C++标准有std::chrono,但是您需要的功能只能在C++20中使用。

下面是一个使用boost::date_time的示例:

代码语言:javascript
复制
#include "boost/date_time/gregorian/gregorian.hpp"

date start(1992,Jan,1);

date yourdate=start + days(value);
票数 3
EN

Stack Overflow用户

发布于 2021-06-02 11:18:54

使用霍华德·辛纳特的日期库c++20等效可以简化以下操作:

代码语言:javascript
复制
#include "date.h"
#include <chrono>
#include <iostream>

using namespace date;
using namespace date::literals;

int main()
{
    date::sys_days epoch = 1992_y / 1 / 1;
    uint64_t date_time = 0x60592102'FC290000;
    date::days days(
        (( date_time & 0xFF ) << 24) |
        (( (date_time >> 8) & 0xFF) << 16) |
        (( (date_time >> 16) & 0xFF) << 8) |
        (( (date_time >> 24) & 0xFF)));
    std::chrono::milliseconds time(
        ((date_time >> 32 & 0xFF) << 24) |
        (((date_time >> 40) & 0xFF) << 16) |
        (((date_time >> 48) & 0xFF) << 8) |
        (((date_time >> 56) & 0xFF)));
    std::chrono::system_clock::time_point result = epoch + days + time;
    std::cout << result << "\n";
}

注意,您的示例值似乎不正确(缺少一个尾随的0)。此代码打印:

代码语言:javascript
复制
2021-06-05 09:55:40.0000000

哪一天比你的样品值晚一天,我不确定你的样品是错的还是第一天是一月一日?您所链接的规范非常不明确。如果样本是正确的,那么通过添加以下内容就很容易修复:

代码语言:javascript
复制
epoch -= date::days(1);

使用c++20的相同代码:

代码语言:javascript
复制
#include <chrono>
#include <iostream>
#include <format>

using namespace std::chrono;
using namespace std::literals;

int main()
{
    sys_days epoch = 1992y / 1 / 1;
    uint64_t date_time = 0x60592102'FC290000;
    days days(
        ((date_time & 0xFF) << 24) |
        (((date_time >> 8) & 0xFF) << 16) |
        (((date_time >> 16) & 0xFF) << 8) |
        (((date_time >> 24) & 0xFF)));
    milliseconds time(
        ((date_time >> 32 & 0xFF) << 24) |
        (((date_time >> 40) & 0xFF) << 16) |
        (((date_time >> 48) & 0xFF) << 8) |
        (((date_time >> 56) & 0xFF)));
    system_clock::time_point result = epoch + days + time;
    std::cout << std::format("{:%F %T %Z}", result) << "\n";
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67803545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档