首页 > 解决方案 > 日期时间格式或编码

问题描述

我有 3 个带有日期/时间和电表相位状态的参数: 28.11.2019 4:18 - 所有相位都有电 28.11.2019 4:18 - 所有相位都没有电 28.11.2019 4:23 - 所有相位没有电源但是这些数据编码为十六进制,如下所示:

 FA 22 7C 27 07 FF E1
 49 22 7C 27 07 08 F3
 4E 22 7C 27 00 08 1D

而且我不知道它是怎么做到的?我的意思是也许有一些方法可以保留和转移日期/时间或什么?

34 [48 83 27] 07 C6 EA - 3.12.2019 09:01, </b>
38 [48 83 27] 00 E7 74 - 3.12.2019 09:01, </b>
89 [49 83 27] 07 10 38 - 3.12.2019 09:12, </b>
8E [49 83 27] 00 10 D6 - 3.12.2019 09:12, </b>
0E [4B 83 27] 07 21 EA - 3.12.2019 09:24, </b>
13 [4B 83 27] 00 42 74 - 3.12.2019 09:24,</b>
19 [4B 83 27] 07 63 2A - 3.12.2019 09:24,</b>
1D [4B 83 27] 00 63 A4 - 3.12.2019 09:24,</b>
21 [4B 83 27] 07 84 5A - 3.12.2019 09:25,</b>
25 [4B 83 27] 00 84 D4 - 3.12.2019 09:25,</b>

方括号 - 我猜是日期。第 4 个字节是相位状态。我的意思是第 4 个字节的低半字节(或半字节?)。0x7(0b0111) - 所有相位都有电源,0x0(0b0000) - 所有相位都没有电源。

标签: datetimedata-transfer

解决方案


TL;DR:每行的前 4 个字节是自 1980 年 1 月 1 日或 1 月 6 日的某个时期以来的时间单位的小端计数。

每个时间戳为 4 个字节。当我们查看倒数第三行和倒数第二行时,它们都4B 83 27在您放置的方括号内,但时间从 9:24 变为 9:25。时间显然被截断了,它们之间不需要超过一两秒,但它们并不相同。我找到的解决方案是在时间戳中包含方括号之前的字节。

时间戳是小端的。随着时间的推移,方括号之前的字节变化最快。下一个字节略有不同。剩余的两个字节在您给出的 24 分钟范围内保持不变。显而易见的解释是,34 48 83 27真的意味着0x27834834,即字节反转。

它进行了一些实验,但两个常见的时期适合:

  1. 1980 年 1 月 1 日。在这种情况下,用于计算自纪元以来时间的时间单位约为 1 900 440 700 纳秒。
  2. 同年1月6日。在这种情况下,单位必须小一些,大约为 1 899 789 030 纳秒。

1980 年 1 月 1 日和 1 月 6 日都是常用的时期。有关文档,请参阅底部的链接。

我已经搜索了一些关于单位大小的解释。例如,它可能是一秒钟或一天的一小部分吗?我没有找到任何合理的解释。我可能错过了一些东西。

我忽略了时区和 UTC 偏移的问题。纪元可能以 UTC 定义,例如,如果问题中给出的时间是在您当地的时区,这会给我的分析增加一点不准确性。

在代码中

要将十六进制数字转换为日期和时间,我们可以在 Java 中使用如下所示的简单方法。

private static LocalDateTime epoch = LocalDateTime.of(1980, Month.JANUARY, 6, 0, 0);
private static int nanosPerUnit = 1_899_789_030;

private static LocalDateTime convert(int n) {
    return epoch.plusNanos((long) n * (long) nanosPerUnit);
}

示范:

    int[] numbers = {
            0x27834834,
            0x27834838,
            0x27834989,
            0x2783498e,
            0x27834b0e,
            0x27834b13,
            0x27834b19,
            0x27834b1d,
            0x27834b21,
            0x27834b25
    };

    for (int n : numbers) {
        System.out.format("%x %s%n", n, convert(n));
    }

输出:

27834834 2019-12-03T09:01:20.396289720
27834838 2019-12-03T09:01:27.995445840
27834989 2019-12-03T09:12:08.224348950
2783498e 2019-12-03T09:12:17.723294100
27834b0e 2019-12-03T09:24:27.242281620
27834b13 2019-12-03T09:24:36.741226770
27834b19 2019-12-03T09:24:48.139960950
27834b1d 2019-12-03T09:24:55.739117070
27834b21 2019-12-03T09:25:03.338273190
27834b25 2019-12-03T09:25:10.937429310

日期和时间与问题中的一致。我让你插入 1 月 1 日和 1_900_440_700 纳秒,看看这也给出了与问题一致的结果。

链接


推荐阅读