为啥 DateTime 基于 Ticks 而不是毫秒?

Posted

技术标签:

【中文标题】为啥 DateTime 基于 Ticks 而不是毫秒?【英文标题】:Why is DateTime based on Ticks rather than Milliseconds?为什么 DateTime 基于 Ticks 而不是毫秒? 【发布时间】:2013-01-03 03:28:58 【问题描述】:

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

【问题讨论】:

为什么要将DateTime 的精度限制为毫秒(一系列缺点,例如,您要么为TimeSpan 使用不同的单位,要么不能让StopWatch 返回TimeSpan s) 什么时候可以有 100ns 的精度而没有缺点? 我试图了解 Ticks 背后的实际原因。 刻度只是表示 9999 年时不会导致 Int64 溢出的最小十次方。 “Clunks”历史悠久。 (Ref.) 【参考方案1】: TimeSpanDateTime 使用相同的 Ticks 进行操作,例如将 TimeSpan 添加到 DateTime 微不足道。

更精确是好的。主要用于TimeSpan,但以上原因将其转移到DateTime

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

即使使用毫秒刻度,您也需要一个 Int64 来表示 DateTime。但是你浪费了大部分范围,因为 0 到 9999 之外的年份并没有真正有用。所以他们选择了尽可能小的刻度,同时允许DateTime 代表 9999 年。

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

因此,使用较长的刻度会降低精度,而不会获得任何收益。使用较短的刻度不适合 64 位。 => 100ns 是给定约束的最佳值。

【讨论】:

好答案。是的,如果只使用 32 位,例如 intuint,即使没有使用两位来表示“时间”信息,您也只能表示少于 50 天(@987654336 @) 毫秒分辨率。如果你想为此使用一个 32 位整数,你可以使用 seconds 作为你的“tick”大小,而不是毫秒,这实际上是在所谓的“Unix time”中完成的。他们仍然会遇到问题,因为他们只使用 32 位。 很多年前,我曾经在面试时问过这个问题。令人惊讶的是,有多少最近的大学毕业生不知道最小的刻度尺寸是多少,以至于一万年的跨度适合一个 64 位整数。 0 年或 9999 年有什么特别之处?我真的不知道 DateTime 对象如何适用于当前日历制定之前的任何一年(从 1750 年 1 月 1 日到 1760 年 1 月 1 日,美洲殖民地有多少天?),也我认为在 2499 年 12 月 31 日之后仍然会使用该类型吗?尝试使用 DateTime 来存储 1-1-0001 或 12-31-9999 等标记值,因为实际日期似乎很危险,因为它们有多种方式可以翻译成线性日期。【参考方案2】:

来自MSDN

一个滴答表示一百纳秒或一千万分之一 一秒钟。一毫秒内有 10,000 个滴答声。

一个刻度表示本地时间的总刻度数,即 0001 年 1 月 1 日午夜。但刻度也是 TimeSpan 的最小单位。由于刻度是Int64,所以如果使用毫秒而不是刻度,可能会丢失信息。

也可以是默认的CLS 实现。

【讨论】:

用“因为它是这样”来回答“为什么”是没有用的。【参考方案3】:

用于更高的时间分辨率,即使您大部分时间都不需要它。

【讨论】:

【参考方案4】:

仅供参考:

1 毫秒 = 10 000 个滴答声

1 秒 = 10 000 000 个滴答声

使用两个刻度的差异(增量)可以获得更精细的精度(稍后将它们转换为毫秒或秒)

在 C# DateTime 上下文中,刻度从 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 亿滴答。

【讨论】:

【参考方案5】:

tick 是系统时钟的工作方式。

【讨论】:

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

以上是关于为啥 DateTime 基于 Ticks 而不是毫秒?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这段代码的执行速度比预期的要快?

为啥 pandas 在调用 pd.to_datetime() 时返回时间戳而不是 datetime 对象?

在查询中将 DateTime.Ticks 转换为 MySQL DateTime

MySQL 脚本将 DateTime.Ticks 值转换为 SQL Date

在 DataGridView 中显示之前将时间戳(Datetime.ticks)从数据库转换为 Datetime 值

使用 DateTime.Now.Ticks 生成唯一的数字 ID