为什么DateTime基于Ticks而不是毫秒?

22
为什么DateTime的最小分辨率基于Ticks(100纳秒为单位),而不是毫秒?

1
为什么要将 DateTime 精度限制为毫秒级别(存在很多缺陷,例如你必须使用不同的单位表示 TimeSpan,或者无法使 StopWatch 返回 TimeSpan),而不是使用精度达到100纳秒却没有任何缺陷? - CodesInChaos
我正在尝试理解Ticks背后的实际原因。 - mas
20
Ticks指的是最小的十的幂,它不会在表示公元9999年时导致Int64溢出。 - CodesInChaos
"Clunks"有着悠久的历史。(参考.) - HABO
5个回答

47
  • TimeSpanDateTime使用相同的Ticks,因此像将TimeSpan添加到DateTime这样的操作变得微不足道。
  • 更高的精度很好。主要用于TimeSpan,但以上原因也适用于DateTime

    例如,StopWatch通常测量短时间间隔,通常小于一毫秒。它可以返回一个TimeSpan
    在我的一个项目中,我使用TimeSpan来处理音频样本。100纳秒对于此而言已经足够短了,毫秒则不行。

  • 即使使用毫秒滴答声,您仍需要一个Int64来表示DateTime。但是,由于超出0到9999年的年份实际上并不有用,因此您浪费了大部分范围。因此,他们选择了尽可能小的滴答声,同时允许DateTime表示9999年。

    大约有261.5个带有100ns的滴答声。由于DateTime需要两位用于与时区相关的标记,因此100纳秒的滴答声是适合Int64的最小十进制间隔。

因此,使用更长的滴答声会降低精度而无法获得任何好处。使用更短的滴答声则不适合64位。=> 100纳秒是在约束条件下给出的最佳值。


好的回答。是的,如果只使用32位,例如intuint,即使不使用两个位来表示“时间类型”信息,您也只能使用毫秒分辨率表示不到50天(TimeSpan.FromMilliseconds(uint.MaxValue))。如果要使用32位整数进行此操作,则应将_秒_用作“tick”大小,而不是毫秒,并且在所谓的“Unix时间”中实际上已经这样做了。但是,他们仍然会遇到问题,因为他们只使用了32位。 - Jeppe Stig Nielsen
2
我曾经在面试中问过这个问题,那是很多年前的事了。令人惊讶的是,有如此之多的应届大学毕业生无法计算出最小的刻度大小,以便一个跨度为一万年的时间可以适应于一个64位整数。 - Eric Lippert
3
0年和9999年有什么特别之处吗?我并不认为DateTime对象适用于当前日历制度之前的任何一年(例如1750年1月1日到1760年1月1日之间在美国殖民地有多少天?),也不认为该类型在2499年12月31日后仍将被使用。试图使用“DateTime”来存储类似于1-1-0001或12-31-9999这样的标记值作为实际日期似乎很危险,因为它们可以被转换成线性日期的各种方式。 - supercat

6

来自MSDN;

一个滴答代表一百纳秒或一千万分之一秒。一毫秒有10,000个滴答。

一个滴答表示本地时间中的滴答总数,即公元0001年1月1日午夜。但是,滴答也是TimeSpan的最小单位。由于滴答是Int64类型,因此如果使用毫秒而不是滴答,则可能会丢失信息。

还可以是默认的CLS实现。


8
用“因为它就是这样”来回答“为什么”不是很有用。 - CodesInChaos

5

仅供参考:

1毫秒 = 10,000个计时周期(ticks)

1秒 = 10,000,000个计时周期(ticks)

使用两个计时周期的差值(delta),可以获得更精确的精度(后将其转换为毫秒或秒)

在C# DateTime上下文中,计时周期(ticks)从 0 开始(即 DateTime.MinValue.Ticks),一直到DateTime.MaxValue.Ticks

new DateTime(0)                          //numbers between 0 and (864*10^9-1) produces same date 01/01/0001        
new DateTime(DateTime.MaxValue.Ticks)    //MaxValue tick generates 12/31/9999

系统时间刻度每天增加 8640 亿个刻度。


2
为了获得更高的时间分辨率,即使在大多数情况下您并不需要它。

-5

滴答声是系统时钟的工作基准。


2
你确定吗?我认为系统时钟只有10-30毫秒的精度。 - mas
@mas 这并不一定意味着它不使用100 ns滴答作为单位。 - svick
不,它不会。Windows操作系统在其SYSTEMTIME结构中仅返回毫秒精度的单位。根据此文章,它只精确到约10至15毫秒。同一篇文章继续介绍如何使用性能计数器获得亚毫秒分辨率。结果可以在C#中表示为DateTime或TimeSpan。 - Matt Johnson-Pint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接