为啥 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】:
TimeSpan
和 DateTime
使用相同的 Ticks
进行操作,例如将 TimeSpan
添加到 DateTime
微不足道。
更精确是好的。主要用于TimeSpan
,但以上原因将其转移到DateTime
。
例如StopWatch
测量短时间间隔,通常短于一毫秒。它可以返回一个TimeSpan
。
在我的一个项目中,我使用TimeSpan
来处理音频样本。 100ns 已经足够短了,毫秒是不够的。
即使使用毫秒刻度,您也需要一个 Int64 来表示 DateTime
。但是你浪费了大部分范围,因为 0 到 9999 之外的年份并没有真正有用。所以他们选择了尽可能小的刻度,同时允许DateTime
代表 9999 年。
大约有 261.5 个 100ns 的滴答声。由于DateTime
需要两个位用于时区相关标记,因此 100ns 滴答是适合 Int64 的最小十次方间隔。
因此,使用较长的刻度会降低精度,而不会获得任何收益。使用较短的刻度不适合 64 位。 => 100ns 是给定约束的最佳值。
【讨论】:
好答案。是的,如果只使用 32 位,例如int
或 uint
,即使没有使用两位来表示“时间”信息,您也只能表示少于 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