当前位置:

首页 > 编程开发 > 如何正确使用long类型8字节内存存储大时间戳以避免精度截断

如何正确使用long类型8字节内存存储大时间戳以避免精度截断

Java的长整型可精确存储大时间戳,但跨语言JSON传输至JavaScript时,由于JavaScript的数字类型采用双精度浮点数,仅能安全表示2的53次方以内的整数,超过则精度丢失。解决方法:对外输出可能超限的长整型值一律转为字符串。

本文目录
    在Ja va的世界里,用`long`存时间戳到底会不会丢精度?这个问题看似简单,却常让不少开发者踩坑。先说结论:`long`本身完全没问题,精度丢失的锅,多半要甩给跨语言传输——特别是Ja vaScript那一端。 先理解一下为什么`long`在Ja va内部是安全的。Ja va的`long`是有符号64位整型,取值范围从-9.22×10¹⁸到9.22×10¹⁸,而当前毫秒级时间戳(比如`System.currentTimeMillis()`返回的值)大约在1.7×10¹²左右,离`long`的上限还差着好几个数量级。所以,**在Ja va内部运算、存储、甚至数据库的BIGINT字段映射中,long完全可以精确表示,没有任何精度损失**。 那精度丢失到底发生在哪里?答案就在JSON传输这个环节。Ja vaScript的`Number`类型采用的是IEEE 754双精度浮点数,它只能安全表示绝对值小于等于2⁵³−1(约9.007×10¹⁵)的整数。一旦后端返回的`long`值超过这个阈值,前端解析时就会悄悄四舍五入。打个比方:`1629872445049`这个值没问题,但换成`9223372036854775807`,到了浏览器里就变成了`9223372036854776000`——这种肉眼可见的偏差,只要你在Postman里看响应体是对的,但打开浏览器控制台一打印发现变了,基本就锁定了是JS浮点解析造成的。 那么哪些场景最容易中招呢?典型的有分布式ID(比如Snowflake算法生成的ID)、远期时间戳(比如2120年的到期时间)、大文件的最后修改时间。验证方法很简单:后端返回后,分别用Postman和浏览器控制台对比一下结果,不一致就说明问题出在JSON解析上。 正确的做法是从源头隔离浮点风险,核心原则只有一句话:**只要涉及可能超过2⁵³的long值对外输出,一律转成String**。具体实现有几种方式: - 序列化层统一处理:使用Jackson时加`@JsonFormat(shape = JsonFormat.Shape.STRING)`注解;Fastjson则配`@JSONField(serializeUsing = ToStringSerializer.class)`。 - 在DTO中直接把字段类型声明为String,比如`private String orderId;`而不是`private Long orderId;`,接收时再按需调用`parseLong()`(仅在可信上下文中使用)。 - 数据库交互保持BIGINT:MySQL/PostgreSQL的`BIGINT`与Ja va的`long`天然匹配,JDBC驱动默认正确转换,无需任何额外干预。 最后再提一个时间戳单位换算的小细节。业务计算中请务必使用`TimeUnit`工具类,不要手写`*1000`或`/60/60`这种魔法数字。比如`TimeUnit.SECONDS.toMillis(30)`安全得到30000,类型仍然是long;而`TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())`自动向下取整,语义清晰。需要特别注意的是,不要写成`(int) TimeUnit.HOURS.toMillis(2)`——强转可能导致溢出,直接用long接收就好。至于日志展示时需要小数,那可以用`ms / 1000.0`,这是展示需求,和精度换算无关,与`TimeUnit`的使用场景不同。 说到底,这其实不复杂,但容易忽略。只要记住“跨语言传输时long超限要转String”这一条,就能避开大部分坑。

    如何正确使用long类型8字节内存存储大时间戳以避免精度截断

    为什么 long 本身不丢精度

    Ja va 的 long 是有符号 64 位整型,取值范围是 −9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。而毫秒级时间戳(如 System.currentTimeMillis() 或 Instant.now().toEpochMilli())当前最大值才约 1.7×10¹²(2026 年),远未触及 long 上限。所以在 Ja va 内部运算、存储、数据库 bigint 字段映射中,long 完全够用且无精度损失。

    精度丢失真正发生在哪里

    问题不出在 Ja va,而出在前后端 JSON 传输环节:Ja vaScript 的 Number 类型是 IEEE 754 双精度浮点数,仅能安全表示 ≤ 2⁵³−1(即 9,007,199,254,740,991)的整数。一旦后端返回的 long 值(如雪花 ID 或未来年份的时间戳)超过该阈值,前端解析就会四舍五入——比如 1629872445049 没事,但 9223372036854775807 就会变成 9223372036854776000。

    • 典型高危字段:分布式 ID(Snowflake)、远期时间戳(如 2120 年的到期时间)、大文件最后修改时间
    • 验证方式:Postman 看响应体是正确的,浏览器 console 打印却变了 → 基本锁定为 JS 解析问题

    正确做法:从源头隔离浮点风险

    核心原则:只要涉及可能超 2⁵³ 的 long 值对外输出,一律转 String。

    • 序列化层统一处理:用 Jackson 时加 @JsonFormat(shape = JsonFormat.Shape.STRING) 注解;Fastjson 同理配 @JSONField(serializeUsing = ToStringSerializer.class)
    • DTO 字段显式声明为 String:比如 private String orderId; 而非 private Long orderId;,接收时再按需 parseLong(仅在可信上下文)
    • 数据库交互保持 bigint:MySQL/PostgreSQL 的 BIGINT 与 Ja va long 映射天然匹配,JDBC 驱动默认正确转换,无需额外干预

    时间戳单位换算别踩坑

    业务计算中要用 TimeUnit,而不是手写 *1000 或 /60/60:

    • TimeUnit.SECONDS.toMillis(30) → 安全得 30000,类型仍是 long
    • TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) → 自动向下取整,语义清晰
    • 避免 (int) TimeUnit.HOURS.toMillis(2):强转可能溢出,直接用 long 接收
    • 日志展示需要小数?用 ms / 1000.0 —— 这是展示需求,不是精度换算,和 TimeUnit 场景不同

    不复杂但容易忽略,只要记住上面几点,基本就能稳住了。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 时间戳
    相关文章 更多
    PDF如何加电子签名时间戳_PDF签名与时间戳添加操作
    PDF如何加电子签名时间戳_PDF签名与时间戳添加操作

    如何为PDF添加电子签名与可信时间戳? 在数字文档流转中,确保文件的完整性和签署时间的权威性至关重要。电子签名搭配可信时间戳,恰恰能同时解决“谁签的”和“何时签的”这两个核心问题,让一份PDF文件具备法律效力和审计价值。那么,具体该如何操作呢?其实,从专业桌面软件到便捷的在线工具,都有相应的解决方案

    怎么通过 OffsetDateTime.now() 获取带有时区偏移量的精确业务时间戳
    怎么通过 OffsetDateTime.now() 获取带有时区偏移量的精确业务时间戳

    OffsetDateTime.now()默认使用系统时区偏移,易因服务器时区不一致导致时间错乱。业务中应显式指定时区(如UTC或固定偏移),避免依赖系统默认。其精度与Instant一致,但需注意序列化与数据库写入时的偏移语义一致性。

    怎么通过 Instant.now() 获取符合 UTC 标准的当前精确时间戳对象
    怎么通过 Instant.now() 获取符合 UTC 标准的当前精确时间戳对象

    Instant.now()返回基于Unix纪元的UTC纳秒偏移量,不受本地时区影响,无需额外转换。实际精度取决于操作系统硬件,通常为毫秒级。序列化或存储时需注意纳秒可能被数据库或框架截断丢失。

    Java 中 System.nanoTime 怎么获取单调的系统时间戳
    Java 中 System.nanoTime 怎么获取单调的系统时间戳

    System.nanoTime()基于内核单调时钟,纳秒级分辨率且严格单调递增,不受系统时钟调整(如NTP)影响。此方法仅用于计算两个时刻间的耗时差值,不可获取绝对时间或日历时间,广泛应用于高精度性能测量与算法耗时分析。

    金山文档怎样插入日期时间戳_金山文档动态时间设置【教程】
    金山文档怎样插入日期时间戳_金山文档动态时间设置【教程】

    金山文档支持五种插入时间戳方法:一、插入可自动更新的动态日期时间;二、用快捷键插入静态日期或时间;三、在页眉页脚嵌入动态时间戳;四、通过文档属性添加元数据级时间戳;五、在表格中用=TODAY()或=NOW()函数生成实时时间。 在金山文档里给内容加上一个“时间印记”,是很多工作场景下的刚需。无论是记

    Python将时间转为时间戳的方法
    Python将时间转为时间戳的方法

    Python中时间转时间戳核心用datetime或time模块:字符串需先strptime解析再timestamp();datetime对象直接调用timestamp();UTC时间须明确时区以避免偏差。

    Java获取当前时间戳的几种方法
    Java获取当前时间戳的几种方法

    最推荐使用Instant.now().toEpochMilli()获取时间戳,1.System.currentTimeMillis()高效简单;2.Date().getTime()已过时;3.Instant支持纳秒且线程安全;4.LocalDateTime需结合时区转换。

    C++获取秒级和毫秒级时间戳方法
    C++获取秒级和毫秒级时间戳方法

    使用chrono库可获取秒级和毫秒级时间戳,推荐C++11及以上版本;2.time.h的time函数适用于仅需秒级精度的场景;3.需要微秒级精度时仍可用chrono;4.所有方法基于UTC,时区转换需额外处理。

    如何在 Go 中使用正则表达式匹配时间戳?
    如何在 Go 中使用正则表达式匹配时间戳?

    在Go中,可以使用正则表达式匹配时间戳:编译正则表达式字符串,例如用于匹配ISO8601时间戳的表达式:^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$。使用regexp.MatchString函数检查字符串是否与正则表达式匹配。

    将php数字时间戳转换为日期和时间
    将php数字时间戳转换为日期和时间

    PHP数字时间戳转换为日期和时间:使用date()函数将时间戳转换为特定格式的日期和时间。使用gmdate()函数将时间戳转换为格林尼治时间(GMT)格式的日期和时间。支持其他格式说明符,如d(日期)、m(月份)、Y(年份)、H(小时)、i(分钟)和s(秒)。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。