簡體   English   中英

dbf 文件(dBase 7 格式)中的時間戳字段沒有意義

[英]Timestamp field in a dbf file (dBase 7 format) is not making sense

我已經查看了 [1] 和 [2] 並且完全感到困惑(並且由於 dbf 文件是版本 4 文件,因此 [1] 應該適用)。 一方面,為什么 [1] state 時間戳的日期部分是自公元前 4713 年 1 月 1 日以來的天數? 這非常令人費解。 其次,假設它是自公元前 4713 年以來的天數,我在獲得的價值方面遇到了一些麻煩。

首先,我的 dbf 文件有一個時間戳字段,它有一個 8 字節長的值。 實際日期為 2000/8/16 17:21:41。 在dbf文件中,8字節序列如下0x42ccb20e0340df00。

從 [1] 開始,它說前 4 個字節是日期,第二個 4 個字節是時間。 如果原始字節序列實際上是 little-endian (0x42ccb20e),那么它應該是 0x0eb2cc42,它的值是 246598722。所以日期是 0x0eb2cc42 (246598722),時間是 0x00df4003 (14630915)。

我必須在這里遺漏一些東西或計算錯誤。 246598722 相當於 675612 年(假設 1 年 = 365 天,因為添加閏年會讓我感到困惑......而且不應該真的有那么多)。

從 [2] 開始,我不應該使用 01/01/4173bc 作為基礎,而是使用 12/31/1899(嗯,1/1/1900)。 但是,我擁有的日期值甚至不在 [2] 顯示的范圍內。

現在,如果我取實際值 (2000/8/16) 並使用 [1] 和 [2],我會得到以下結果:

方法 [1]:2450501 天:(2000 - -4713) * 365 + (8 * 30) + 16 方法 [2]:36756 天:[100 * 365 + 8 * 30 + 16] (超過天數)

dbf 文件沒有損壞(否則,如果我查看 dBase 中的時間戳,它會出錯並顯示一些瘋狂的東西)。

我曾考慮過使用大端序,但由於值更大,這更沒有意義。 我什至想到了它實際上是自任一日期以來經過的秒數的可能性,但這使得這些值更沒有意義。 即 246598722 = 經過的秒數(從 2000/8/16 開始倒數)將使基准年為 1812。(計算:246898722 / (3600 * 365) = 187.8985,因此 2000 - 187.8985 = 1812.1015)

有人可以指出我在哪里做錯了嗎?

謝謝!

[1] - https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm [2] - 轉換 dBase 時間戳

感謝[3],我終於找到了答案。

基本上,時間戳8字節序列作為一個整體使用的,有以下注釋:

  1. 它存儲在大端。

  2. 不使用最后一個字節。

  3. 這是儒略日數。

所以在我的情況下,它是 0x42ccb20e0340df00 並截斷最后一個字節,我得到 0x42ccb20e0340df。

然后下面的 python 代碼得到正確的信息:

import datetime

base = 0x42cc418ba99a00
frm_date = int('42ccb20e0340df', 16)
final_ts = (frm_date - base) / 500
final_date = datetime.datetime.utcfromtimestamp(final_ts)

它輸出 2000-8-16 17:21:41 和幾毫秒,我只是忽略。

所以我猜理論是上面的代碼將“基准”日期從 1/1/1 移動到 1970/1/1,這有幫助,因為 utcfromtimestamp() 不適用於 1970/1/ 之前的任何值1.

我的困惑源於它不使用 4713BC 作為基准年,而是使用 1/1/1,盡管我仍在試圖弄清楚如何獲得 1970/1/1 的值 0x42cc418ba99a00。

[3] - https://stackoverflow.com/a/60424157/10860403

對於任何 dBASE 問題,我會向 dBASE 新聞組推薦 go,他們有一個非常有幫助和知識淵博的社區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM