Delphi 函数 EncodeDate/DecodeDate 似乎只能处理 1.1.0001 之后的日期。是否有一些可以处理 BC tDateTime 值的 EncodeDate/DecodeDate 实现?
1 回答
AFAIKTDateTime
是一种 Windows 基础类型,常见于 COM、Variants、DotNet 和 Delphi。负值可用于 1899 年之前的日期。
但这并不是那么简单 - 因为负值会带来一些麻烦,如本页所述:
整数部分是日期,小数部分是时间。约会时间。这很容易。当值为负时,事情会变得很奇怪。这是在 #12/30/1899# 之前或之前。
正如您所怀疑的那样,现代日期总是向前运行。对于负历史日期,时间实际上是倒退的!午夜 #1/1/1800# 等于 -36522,但中午 #1/1/1800# 为 -36522.5(小于午夜!),午夜前一秒为 -36522.9999884259(甚至更少)。午夜时分,时钟向前跳到 -36521,等于#1/2/1800#。小数部分仍然显示时间,整数部分是日期,但是每一秒都会减少时钟,而每一天都会增加它,不仅仅是 1,而是几乎 2。负时间真的违反直觉。
更糟糕的是,#12/30/1899# 的时间值在两个方面是模棱两可的。首先,没有日期的时间值等于 #12/30/1899# 上的时间。这意味着 0.5 是 #12/30/1899# 的中午或中午,具体取决于上下文。零是午夜 #12/30/1899# 或午夜 #12/30/1899#。另一个不明确之处是#12/30/1899# 的所有时间值都是双倍的。0.5 是中午 #12/30/1899#,但 -0.5 也是中午 #12/30/1899#。整数部分是日期,小数部分是时间。另一个惊喜在这里:#12/30/1899 11:59:59 PM# - #12/29/1899 11:59:59 PM# = 2.99997685185185。不是 1,这是您通常在 24 小时内所期望的。处理历史日期时要小心。
据我所知,EncodeDate/DecodeDate 的当前实现将起作用,但在使用负值或接近零TDateTime
值时您可能会遇到麻烦......
您最好使用自己的时间格式,例如 ISO-8601 或这样的简单记录:
TMyDateTime = packed record
Year: SmallInt;
Month: Byte;
Day: Byte;
end;
在计算持续时间或显示日期/时间时,您必须意识到“我们的时间”不是连续的。因此,使用该TDateTime=double
技巧的计算并不总是按预期工作。例如,我记得阿维拉的特蕾莎于 1582 年 10 月 4 日去世,当时天主教国家正在从儒略历转换到公历,这需要从日历中删除 10 月 5 日至 14 日。:)