编辑于2009年11月4日
好的,距离我最初发布这个问题已经有一段时间了。在我看来,许多最初的回答者没有真正理解我的意思 - 常见的回答是"你说的没任何意义"之类的变体 - 所以我做了一些方便的图表来真正说明我的观点。
当我们谈论数字时,我们通常是指所谓的数轴上的点,这是小学生学习的内容:
1 + 0.5
,如果我们仅仅应用"数轴思维",就需要我们想出一种方法来解释这个式子:
但是,表达式
1 + 0.5
对我们来说是有意义的,因为当我们思考它时,我们真正想象的是这样的情况:
换句话说,数字或点1,加上向量0.5(vector),结果得到点1.5。
或者,我们可以这样想象:
也就是说,向量1加上向量0.5,得到向量1.5。
换句话说,在处理数字时,我们可以互换地对待点和向量。但是日期呢?毕竟,日期基本上也是数字。如果你不相信我,将这行与上面的数轴进行比较:
0001-Jan-02 00:00:00 + 0001-Jan-01 12:00:00
没有太多意义,正如许多回答者所指出的那样:
但是,如果我们在脑海中进行与每次加减数字时执行的相同的概念转换,我们可以轻松地将上述内容“重新思考”为以下形式:
最终,最好的答案来自Strilanc,他指出使用
DateTime
和TimeSpan
实际上是仿射空间的一种实现,这种实现具有方便的特性,即不需要参考点作为原点处理。所以感谢Strilanc。然而,我将采纳ChrisW的答案,因为他首先提出了向量和点的概念,这真正触及了问题的核心。
原始问题(供后人参考)
我当然不是编程万事通,但我知道PHP和.NET都有一个TimeSpan
类,除了DateTime
类(或.NET中的结构),我猜这在许多其他语言和框架中也是如此(尽管我主要是参考.NET结构写的)。这可能看起来是个奇怪的问题,但TimeSpan
不是多余的吗?
如果你认为答案很明显(“DateTime
是时间上的一个绝对点,而TimeSpan
是一段时间范围——就这么简单!”),请考虑以下:整数可以被概念化为绝对值(数轴上的点)或值之间的距离,我们不需要为这些不同的概念化定义两种不同的数据类型。我仍然可以毫无歧义地写出5 + 6。
只要有一个一致的零点参考,我认为没有理由需要一个TimeSpan
对象来执行DateTime
对象的算术运算,或者获取它们之间的距离。
我错过了什么?为什么不能将TimeSpan
结构的独特方法和属性简单地合并到DateTime
中?
(免责声明:我并不是很热衷于这个问题;我一直都在使用DateTime
和TimeSpan
对象,就像它们被设计的那样。我只是在问一个问题。)
编辑:为了阐述我的观点,这里提供一个过于简单的例子:
考虑方程式10 - 5 = 5。我们可以将其理解为“从10(值)开始,向左移动5个单位(跨度),最终到达5(值)”。
假设为了方便,我们将1900年1月1日定义为零点,并且我们仅以天数来定义TimeSpan
对象。
那么,以DateTime
术语讲,10 - 5 = 5可以被理解为1900年1月11日 - 1900年1月6日 = 1900年1月6日。这是正确的,因为根据我们的定义,1月11日就是“10”,1月6日就是“5”。我们之所以将10视为值,第一个5视为跨度,最后一个5又视为值,仅仅是为了帮助我们更好地理解概念。我的观点只是:唯一的区别在于你如何看待这个数字,而不是它实际上是什么。这就是为什么我们没有针对整数值和整数跨度分别设计结构的原因——一个普通的整数就足以涵盖所有情况。
我的意思清楚吗?