以Javascript 53位数字格式存储64位时间戳 背景

以Javascript 53位数字格式存储64位时间戳 背景,javascript,numbers,timestamp,precision,Javascript,Numbers,Timestamp,Precision,我正在解码缓冲区中的数据,该缓冲区的时间戳编码为8字节(64位) 通常这不会是一个问题,除了JavaScript中的Number只能处理高达53位的数字,否则会失去精度 问题 这意味着,如果我将时间戳存储在JavaScript数字中,我将失去精度,因为数字格式不足以存储时间戳 由于这是一个需要时间精度至少达到秒的应用程序,我不希望失去太多的精度 例子 为了证明我的观点,这里有一个十六进制字符串,它的时间戳为64位。如果您使用的是Node.js,则可以按如下方式对其进行测试: //a small

我正在解码缓冲区中的数据,该缓冲区的时间戳编码为8字节(64位)

通常这不会是一个问题,除了JavaScript中的
Number
只能处理高达53位的数字,否则会失去精度

问题 这意味着,如果我将时间戳存储在JavaScript数字中,我将失去精度,因为数字格式不足以存储时间戳

由于这是一个需要时间精度至少达到秒的应用程序,我不希望失去太多的精度

例子 为了证明我的观点,这里有一个十六进制字符串,它的时间戳为64位。如果您使用的是Node.js,则可以按如下方式对其进行测试:

//a small timestamp from our current time in history
var buf = Buffer.from(
    "162F1544EA81242A",
    "hex"
);

buf.readUInt( 0, 6 ); // lost 2 bytes of precision here!
此时间戳应在将来提供一些值:

假设此时间戳的单位为微秒(1/1000000秒): 格林尼治时间:2020年8月27日星期四上午9:16:18.476您的时区: 2020年8月27日星期四上午11:16:18.476 GMT+夏令时02:00

问题:
  • 如果64位时间戳以JavaScript 53位数字格式保存,它将丢失多少精度(以毫秒为单位)

这显然很容易测试,JavaScript使用精确的64位浮点来存储数字,浮点意味着精度随着数字的增加而降低,因此选择所需的最大可能值并尝试减去1、2、3等,直到得到不同的值,这样,您就可以精确地获得可以注册的最小时差。

JavaScript的
数字。MAX_SAFE_INTEGER
,2^53-1的值为9007199254740991。但是,请注意,除了53位整数精度外,还有一个符号位,因此如果时间戳是有符号的,您也可以利用它

让我们坚持以微秒为单位的时间戳,而不是毫秒。53位加上一个符号位可以覆盖多少时间范围?将9007199254740991微秒转换为年,大约得到±285年。在大多数情况下,这应该足够好了


如果您选择降低分辨率并转换为毫秒,那么您的时间戳可以覆盖±285000年。

Javascript将日期存储为一个数字,并且具有毫秒精度,。所以1秒的准确度应该不会给你带来任何问题。IOW:您应该释放0毫秒。问题是,当给定一个BigInt(64位长)时,我不知道数字的行为。BIGINT将在不久的将来添加到JS中,但在此之前我没有解决方案。您能给出一个示例缓冲区和预期的示例输出吗?为问题添加了一个示例!这意味着什么日期和时间,您的原始版本是完全有效的Javascript日期,为什么要更改?您以前的版本
新日期(0x162F1544EA8)
很好。时间戳不是浮点。它们是INT。这就是为什么这是一个问题,因为javascript只能描述最长53位的时间戳。javascript中没有长,它只是转换为浮点,53位只是准确存储的部分。