【问题标题】:Delphi tclientdataset .cds datetime binary timeformat unpackDelphi tclientdataset .cds 日期时间二进制时间格式解包
【发布时间】:2015-06-15 15:14:15
【问题描述】:

我正在尝试解析 .cds delphi 数据库文件。简单的 int 值和字符串很容易解析。但我唯一无法理解的是 DateTime 格式。 我发现 6 个字节会影响 DateTime 值

我正在使用 python 和以下代码:

data = '\x00\x00' + '\xBC\xCE\x6F\xEC\xE7\xCC'
data_long = struct.unpack('Q', data)[0]

但是 struct.unpack 没有 6 字节类型的值,所以我添加了 \x00 \x00 来制作 8 字节长的值('Q' 选项)

这是一个小示例 .cds 文件,其中一行 https://yadi.sk/d/PkZKy50YgCmqE

DateTimeIssl 值 = "16.04.2015 9:25:47"

我找到了 6 个十六进制值,但无法正确解压。 谁能告诉我如何阅读它,或者给我一个关于 .cds 文件结构的文档的链接?

更新: 好的!感谢 Deltics 指导我如何阅读 TDateTime。我在互联网上找到了一些测试值,并编写了将其转换为 Python 日期时间对象的解码函数。

data = '\x2E\xD8\x82\x2D\xCE\x47\xE3\x40'

data_double = struct.unpack('d', data)[0]
double_split = str(data_double).split('.')

SECONDS_IN_DAY = 60*60*24
time_from_starting_date = timedelta(days=int(double_split[0]), seconds=int(SECONDS_IN_DAY * (float(double_split[1]) * pow(0.1, len(double_split[1])))))

starting_date = datetime(1899, 12, 30)
result_date = starting_date + time_from_starting_date

print time_from_starting_date
print result_date

对于 2E D8 82 2D CE 47 E3 40,它将是 08.02.2008 10:38:00。 工作正常。

但我仍然无法在上面链接的文件中找到字段 DateTimeIssl 的有效 8 字节。也许有不同的日期时间格式?

【问题讨论】:

    标签: delphi parsing datetime tclientdataset


    【解决方案1】:

    Delphi 日期/时间 (TDateTime) 是双精度浮点数。这是一个 8 字节的值。您不需要添加任何打包或空字节。如果您必须这样做,那么您没有正确识别文件中的双精度值。

    查看您链接到的示例 CDS,可以合理地解释为日期/时间的每个值(例如 DateRoshd、DateTimeIssl)后跟 8 个字节的数据。

    读取 double 值后,该值的整数部分表示日期为自 1899 年 12 月 30 日以来的天数。小数部分是该日期的一天中的时间。

    例如

    1.0 = 31 Dec 1899, 00:00 (midnight)
    2.5 =  1 Jan 1900, 12:00 (midday)
    

    More information on the Delphi TDateTime data type can be found here.

    【讨论】:

    • 非常感谢!您能否给我提交 DateTimeIssl 的确切 8 字节十六进制值?在您的帮助下,我成功解压了在 Internet 上找到的其他 TDateTime 值。但无法从我的文件中解压缩值。我更新了我的帖子以获取更多信息
    【解决方案2】:

    回应自己。也许对某人来说它会有用。 在二进制格式中,TClientDataSet DateTime 包含 INTEGER 自 02.01.0001 以来的毫秒值,但存储为 8 字节 DOUBLE 因此,您必须读取 8 个字节,将其解压缩为双精度,然后将值转换为整数。这是对我有用的 Python 代码:

    data = '\x00\xBC\xCE\x6F\xEC\xE7\xCC\x42'  # Time: 2015-04-16 09:25:47
    data_double = struct.unpack('d', data)[0]
    
    time_from_starting_date = timedelta(days=-2, milliseconds=long(data_double))
    starting_date = datetime(0001, 01, 02)
    result_date = starting_date + time_from_starting_date
    
    print "Time:", result_date
    

    【讨论】:

      猜你喜欢
      • 2016-06-12
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      相关资源
      最近更新 更多