Delphi函数EncodeDate / DecodeDate似乎只能处理1.1.0001之后的日期。是否有一些可以处理B.C.的EncodeDate / DecodeDate实现。 tDateTime值?
答案 0 :(得分:10)
AFAIK TDateTime
是Windows基本类型,COM,Variants,DotNet和Delphi都是通用的。负值可用于1899年之前的日期。
但这不是那么简单 - 因为负值会带来一些麻烦,如stated by this page:
整数部分是日期,分数是时间。约会时间。 这很简单。当值为负时,事情变得奇怪。这是或 在#12/30/1899#。
之前对于现代日期,时间总是向前运行,正如您所怀疑的那样。 由于负历史日期,时间实际上倒退了! 午夜#1/1/1800#等于-36522,但中午#1/1/1800#是-36522.5(小于 午夜!)和午夜之前的一秒是-36522.9999884259(甚至 减)。午夜,时钟跳到-36521,这是 等于#1/2/1800#。小数部分仍显示时间和积分 part是日期,但是每个都在每个新的时间递减时钟 每天增加它,不仅仅增加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# - #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
技巧的计算并不总是按预期工作。例如,我记得Teresa of Avila died in 1582, on October 4th,就像天主教国家正在从朱利安历法转换到格里高利历,这要求将10月5日至14日从日历中删除。 :)