0

0

Python中自定义二进制时间戳到日期时间转换教程

碧海醫心

碧海醫心

发布时间:2025-10-21 12:26:12

|

207人浏览过

|

来源于php中文网

原创

Python中自定义二进制时间戳到日期时间转换教程

本文详细介绍了如何使用python将特定格式的自定义二进制数据转换为日期时间戳。通过对二进制字节序列的模式分析、字节反转、位移操作以及经验性常数校准,结合pandas库处理时区和日期时间对象,最终实现精确的时间戳解码。教程涵盖了从数据探索到代码实现和验证的完整过程。

识别自定义二进制时间戳模式

在处理非标准二进制数据时,首要任务是识别数据中哪些部分代表时间信息,以及它们是如何编码的。对于给定的二进制序列,例如 30 65 1a eb e3 f2 96 c5 41,我们观察到第一个字节 (0x30) 和最后一个字节 (0x41) 在所有示例中保持不变,这暗示它们可能是分隔符或固定标识符,而非时间数据的一部分。

进一步的观察发现,在日期时间相近的样本中,某些字节的变化具有规律性。例如,在以下三个示例中:

  • 30 65 1a eb e3 f2 96 c5 41 -> 2023年12月16日 15:03
  • 30 c6 36 85 70 8a 97 c5 41 -> 2023年12月17日 12:37
  • 30 23 84 b1 a8 b5 97 c5 41 -> 2023年12月17日 18:45

可以注意到倒数第二个字节 (c5) 始终不变,而倒数第三个字节在12月16日是 96,在12月17日是 97。这种模式提示我们,时间信息可能编码在中间的字节序列中,并且字节顺序可能需要反转处理。

解码核心时间值

经过实验和分析,发现将中间的字节序列(去除首尾固定字节)反转并拼接成一个十六进制字符串,然后转换为整数,可以得到一个与时间变化相关的数值。进一步观察时间差异与这些整数值之间的关系,发现它们之间存在一个接近 8_388_608(即 2 ** 23)的倍数关系。这表明原始时间值可能经过了左移23位编码,因此需要通过右移23位 (>> 23) 来还原。

立即学习Python免费学习笔记(深入)”;

这个核心解码逻辑可以抽象为一个Python函数:

def extract_raw_epoch_seconds(hex_string):
    """
    从十六进制字符串中提取原始的纪元秒数。
    hex_string: 包含以空格分隔的十六进制字节的字符串。
    """
    # 移除首尾字节,反转中间字节顺序,拼接成一个十六进制字符串
    relevant_bytes = hex_string.split()[1:-1][::-1]
    combined_hex = ''.join(relevant_bytes)

    # 将十六进制字符串转换为整数,然后右移23位
    raw_integer = int(combined_hex, 16)
    epoch_seconds_shifted = raw_integer >> 23

    return epoch_seconds_shifted

确定时间基准与时区校准

仅仅通过位移操作得到的数值通常不是标准的Unix纪元秒(Epoch seconds)。它需要一个额外的常数偏移量来校准到正确的日期时间。通过比对已知日期时间与解码结果,可以经验性地确定这个偏移量。在本例中,经过多次尝试,确定了一个近似的偏移量为 -4927272860。

此外,考虑到日期可能受到夏令时(Daylight Saving Time, DST)的影响,尤其是在欧洲地区,处理时区变得至关重要。使用pandas库的Timestamp对象可以方便地处理时区信息。例如,对于欧洲地区,可以选择'Europe/Zurich'作为时区。

Timely
Timely

一款AI时间跟踪管理工具!

下载

完整实现与验证

结合上述分析,我们可以构建一个完整的Python函数,将二进制十六进制字符串转换为带有正确时区的pandas.Timestamp对象。

首先,准备示例数据,并使用pandas.Timestamp将其转换为带有指定时区的标准时间对象,以便后续比较。

import pandas as pd

# 定义时区
tz = 'Europe/Zurich'

# 示例数据:十六进制字符串 -> 对应的日期时间
examples = {
    '30 65 1a eb e3 f2 96 c5 41': '16 December 2023 at 15:03',
    '30 c6 36 85 70 8a 97 c5 41': '17 December 2023 at 12:37',
    '30 4a 26 1b 6b 29 74 c4 41': '1 October 2022 at 12:49',
    '30 23 84 b1 a8 b5 97 c5 41': '17 December 2023 at 18:45',
    '30 3f 91 e7 96 b5 97 c5 41': '17 December 2023 at 18:45:30', # 注意此处的秒数
    '30 a6 d6 2f d1 b5 97 c5 41': '17 December 2023 at 18:46',
    '30 e8 16 9c b9 b5 97 c5 41': '17 December 2023 at 18:47',
}

# 将字符串时间转换为带时区的pandas Timestamp对象,并按时间排序
examples = dict(sorted([
    (k, pd.Timestamp(v, tz=tz)) for k, v in examples.items()
], key=lambda item: item[1]))

print("处理后的示例数据:")
for k, v in examples.items():
    print(f"  {k}: {v}")

接下来,定义用于转换的核心函数:

# 定义核心解码函数
def f(k):
    """
    解码二进制十六进制字符串为校准后的纪元秒数。
    k: 以空格分隔的十六进制字节字符串。
    """
    # 提取并反转相关字节,转换为整数,然后右移23位
    raw_val = int(''.join(k.split()[1:-1][::-1]), 16) >> 23
    # 应用经验性常数偏移
    return raw_val - 4927272860

# 定义将解码值转换为pandas Timestamp的函数
def to_time(k, tz):
    """
    将解码后的纪元秒转换为指定时区的pandas Timestamp对象。
    k: 以空格分隔的十六进制字节字符串。
    tz: 时区字符串。
    """
    # pandas Timestamp的构造函数接受纳秒级的整数,所以需要乘以1e9
    return pd.Timestamp(f(k) * 1e9, tz=tz)

# 定义时间格式化字符串
fmt = '%F %T %Z'

# 对所有示例进行转换和验证
test_results = [
    (
        f'{v:{fmt}}',  # 给定的原始时间
        f'{to_time(k, tz=tz):{fmt}}', # 从二进制数据估计的时间
        (to_time(k, tz=tz) - v).total_seconds(), # 估计时间与原始时间的差值(秒)
    )
    for k, v in examples.items()
]

print("\n转换结果与验证:")
for original_time, estimated_time, diff_seconds in test_results:
    print(f"  原始时间: {original_time}")
    print(f"  估计时间: {estimated_time}")
    print(f"  差值 (秒): {diff_seconds:.1f}\n")

示例输出(部分):

转换结果与验证:
  原始时间: 2022-10-01 12:49:00 CEST
  估计时间: 2022-10-01 12:49:30 CEST
  差值 (秒): 30.0

  原始时间: 2023-12-16 15:03:00 CET
  估计时间: 2023-12-16 15:03:23 CET
  差值 (秒): 23.0

  原始时间: 2023-12-17 12:37:00 CET
  估计时间: 2023-12-17 12:36:37 CET
  差值 (秒): -23.0
...

从验证结果可以看出,估计时间与原始时间之间存在数十秒的微小差异。这可能是由于原始数据编码的精度限制,或是在确定偏移量时为了简化模型而选择的近似值。

注意事项与总结

  1. 数据探索的重要性: 解码自定义二进制格式的关键在于细致地观察数据模式,识别固定部分、变化部分以及它们之间的关联。
  2. 经验性常数: 像 -4927272860 这样的偏移量是根据有限的样本数据经验性确定的。如果有更多的样本数据,特别是时间跨度更大、精度更高的样本,可以进一步优化这个常数,甚至可能发现更复杂的计算公式。
  3. 位操作的理解: >> 23 这样的位移操作是理解数据编码方式的关键。它通常表示原始数据在存储时进行了某种倍数的缩放。
  4. 时区与夏令时: 在处理全球范围或跨越夏令时边界的时间数据时,正确设置和处理时区是必不可少的,pandas库提供了强大的支持。
  5. 误差分析: 即使找到了看似合理的转换方法,也需要对转换结果进行误差分析,了解其精度和潜在的局限性。

通过以上步骤,我们成功地将特定的自定义二进制时间戳数据转换为可用的日期时间对象。这种方法体现了在处理非标准数据格式时,结合模式识别、位操作和经验性校准的通用策略。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

724

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

628

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

744

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1236

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

575

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

702

2023.08.11

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

150

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号