12

Delphi 函数 EncodeDate/DecodeDate 似乎只能处理 1.1.0001 之后的日期。是否有一些可以处理 BC tDateTime 值的 EncodeDate/DecodeDate 实现?

4

1 回答 1

10

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 日。:)

于 2011-07-28T10:01:26.787 回答