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

Ufd*_*der 0 java epoch milliseconds

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

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

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

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

Jon*_*eet 5

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

不,远不止这些。不要忘记,对于您在存储中添加的每一位,您可以存储两倍的值。

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 年

也称为“可能比您需要的范围更大”:)


rzw*_*oot 5

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

让我们深入研究一下我们所知道的一些内容:

他们明确指出这是某种“毫秒”值。我们还知道它是 41 位,其余的,好吧,其余的我们将不得不猜测。

让我们研究我们所知道的东西:41 位和“毫秒”。

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

你可以进入一个房间。它有 1 个灯开关,没有其他值得注意的地方。除了电灯开关之外,你不能留下任何东西、在墙壁上刮擦或以其他方式与这个房间互动。然后,你就得走了。然后我稍后再进入。

我们能传达多少信息?

对于单个灯开关,只有 1 位信息:您可以将灯打开或关闭,这就是我所知道的。如果您需要与我交流的只是您观察到的硬币翻转的结果,而我没有观察到,那么 1 位就足够了。我们事先做好安排:灯亮起表示硬币落地为反面,灯亮亮表示硬币落地为正面。瞧,我们现在可以交流 1 次抛硬币了。

假设有 2 个灯开关。您现在可以交流 4 种不同的事情。假设有人从一副牌中抽了一张牌,你看到了,而我没有:如果我们安排一个“代码”,你可以将花色传达给我。

将“灯关闭”视为 0,将“灯打开”视为 1,那么我们可以预先安排此代码:

00 - hearts
01 - clubs
10 - spades
11 - diamonds
Run Code Online (Sandbox Code Playgroud)

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

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

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

我们还知道这是区分“毫秒”的。我们可以这样解读:该机制能够以 1 毫秒的粒度存储时间。换句话说,它可以区分任意 2 个时间点,只要这 2 个时间点至少相差 1 毫秒。

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

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

那么我们就这样做吧。2,199,023,255,552/1000/60/60/24/365.25 = 69.682842027。

换句话说,通过41个灯开关,你可以以毫秒的粒度向我传达某个时刻,只要我们提前安排好,我们知道我们只是在特定的时间范围内进行沟通,而这个范围可以不得大于 69 年半。

进行这种安排的最简单方法是将某个时间点指定为“纪元” - 0 值。

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

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

因此,数字 60000 编码(在 UTC 时区)时间为 2000-01-01 00:01:00(UTC 时区 2000 年午夜后 1 分钟)的时刻。

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

我们的 41 位让我们到达 2069 年 7 月 1 日左右(2069 年 7 月),然后我们就耗尽了所有的位。如果你只是盲目地继续数,那么,计算机会绕圈,所以你会再次得到数字 0,我们会错误地将其读作:2000 年午夜的 Juuust。

也就是说,已经69年多了,41年简直就是完完全全的马粪。我不知道他们为什么写为 41。但是,41 至少接近 69,所以也许这过于简单化了。

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

然后,要么非常非常旧的 Instagram 帖子突然看起来像是来自 2080 年(通过向上重新定义 69 位窗口,任何不在窗口中的时间戳看起来就像是来自 2080 年的时间戳)完全错误),或者他们改变他们的ID系统,例如添加另外一些位。他们添加的每一位都会使窗口大小加倍。即使 1 位也足够再用 69 年多一点。