以毫秒为单位理解比特和时间

Understanding bits and time in milliseconds

我正在阅读 this 页面,其中说 41 位用于使用自定义纪元表示 41 年。

我无法理解以毫秒为单位的时间、位和年之间的关系。有人可以帮忙吗?

例如。在Java,System.currentTimeMillis() returns一个long,也就是64 bits。这是否意味着如果我必须每毫秒生成 1 个,它可以代表 64 年的唯一值?

在上面的例子中,41年后会发生什么?如果他们保持相同的方法,他们是否必须增加用于指定的位?

Eg. In Java, System.timeinmillis() returns a long, which is 64 bits. Does that mean it could represent 64 years worth of unique values if I had to generate 1 per millisecond?

不,远不止于此。不要忘记,您在存储中添加的每一位,都会存储两倍的值。

2^64 是 18,446,744,073,709,551,616。这就是 64 位整数数据类型中可以保存多少个不同的值。

所以以毫秒为精度,那就是:

  • 18,446,744,073,709,551,616 毫秒
  • 18,446,744,073,709,551 秒
  • 307,445,734,561,825 分钟
  • 5,124,095,576,030 小时
  • 213,503,982,334 天
  • 584,542,046 年

也称为“范围可能超出您的需要”:)

时间的标准纪元是 1970 年 1 月 1 日。

long v = LocalDate.now().getLong(ChronoField.EPOCH_DAY);
long millis = v*24*3600*1_000L; // total possible milliseconds
System.out.println(Long.toBinaryString(millis).length()); // length = 41

所以需要41位的long来表示从Epoch开始的毫秒数。这还剩下 23 位,这将是好几年(严重轻描淡写)。

没有。 41 位的 41 年并不意味着 64 位将产生 64 年。起初:这不是真的。 2^41/1000/60/60/24/365.24 的计算结果是将近 70 年,而不是 41 年。第二:如果 41 位是 41 年,那么 42 位就是 82 年,43 位就是 164 年。明白了吗?每个新位都会使结果加倍。因此 64 位足够使用数百万年。

这是一个奇怪的巧合,加上一种奇怪的书写方式。 41 位实际上是 69 岁,而不是 41 岁。本文档的作者搞砸了或过于简单化了,但请注意,纯属巧合,69 非常接近 41。

让我们深入了解一下我们所知道的:

他们明确指出这是某种 'milliseconds' 值。我们也知道它是 41 位,其余的,好吧,剩下的我们将不得不猜测。

让我们研究我们所知道的东西:41 位和 'milliseconds'。

41 位就像 41 个独立的电灯开关。想象以下游戏:

您可以进入一个房间。它有 1 个电灯开关,没有其他值得注意的地方。除了电灯开关外,你不能留下任何东西,不能刮擦墙壁,也不能以其他方式与这个房间互动。那么,你得走了。那我过段时间再进去。

我们可以交流多少信息?

用一个电灯开关,只有 1 位信息:你可以让灯开着或关着,这就是我所知道的。如果您需要与我交流的只是您观察到而我没有观察到的掷硬币的结果,那么我们只需要 1 位。我们事先做了一个安排:灯亮表示硬币落在反面,灯亮表示硬币落在正面。瞧,我们现在可以交流 1 次抛硬币了。

假设有 2 个电灯开关。您现在可以传达 4 种不同的东西。假设有人从一副牌中抽了一张牌,你看到了而我没有:如果我们安排 'code'.

,你可以将花色告诉我

把'light switch off'当成0,把'light switch on'当成1,那么我们就可以预先安排这样的代码:

00 - hearts
01 - clubs
10 - spades
11 - diamonds

所以,如果我进入房间,我看到左边的灯开关是向下的,右边的向下开关是向上的,我可以说:你画了一个梅花!那就对了。

您添加的每个电灯开关都会使您可以通信的状态数量翻倍。所以,1 个电灯开关可以区分 2 个东西(例如硬币翻转),2 个开关可以做 4 件事,3 个开关可以做 8 件事,4 个开关可以做 16 件事,等等。

这里我们有 41 个电灯开关。这有助于区分 2^41 或 2,199,023,255,552 个不同的唯一值。通过简单的数学运算。

我们也知道这是'milliseconds'之间的区别。让我们将其理解为:该机制能够以 1 毫秒的粒度存储时间。换句话说,它可以区分任何两个时间点,只要这两个时间点至少相差 1 毫秒。

让我们稍微研究一下毫秒:

  • 除以 1000 秒。
  • 分钟除以 60。
  • 小时数除以 60。
  • 天数除以 24。
  • 年除以 365.25。

所以让我们这样做吧。 2,199,023,255,552/1000/60/60/24/365.25 = 69.682842027.

换句话说,有了41个电灯开关,你可以以毫秒的粒度与我交流一个时刻,只要我们提前安排好,我们知道我们只是在特定的时间范围内交流,而且这个范围不能大于69半年。

做出这样安排的最简单方法是将某个时间点规定为'epoch' - 0值。

比如我们可以这样预先安排:

  • 让我们规定 UTC 时区,新的一年,因为 1999 年变成了 2000 年,那一瞬间,我们称之为 0。然后这个数字代表那么多毫秒之后。

所以,数字 60000 编码的时间是(在 UTC 时区),时间是 2000-01-01 00:01:00(UTC 区 2000 年午夜后 1 分钟) .

换句话说,我进入房间,发现除右数第二和第三个外,所有电灯开关都已关闭:0000...00110。我们事先安排它是通常的二进制计数机制,所以它是 6。因此,我知道你想告诉我这张照片是在 2000 年午夜后 6 秒拍摄的,UTC 时区。

我们的 41 位使我们到达 2069-07-01 左右(2069 年 7 月),然后我们用完 运行 位。如果你只是盲目地继续计数,那么,计算机会绕行,所以你会再次得到数字 0,我们会错误地将其解读为:Juuust at midnight, year 2000.

也就是说,69又有点年头了,41刚好是马粪。我不知道他们为什么写41。但是,41至少接近69,所以可能过于简单化了。

当他们达到 2041 时会发生什么,或者在他们自己的文档中修复错误,2069 年?好吧,一个简单的解决方案,例如再买 10 年是为了让 0 读作 2069 年八月,而不是 2000 年,这没关系,因为 Instagram 还没有出现。但这只会让你多活几年。

然后,要么非常非常老的 instagram 帖子突然看起来像是从 2080 年开始的(通过重新定义 69 位 window 向上,任何不在 window 看起来像一个,因此是完全错误的),或者他们改变了他们的 ID 系统,例如再添加几位。他们的每一位都增加 双倍 window 大小。即使是 1 位也足够再过 69 年。