📋 目录
一、工具类功能
把某个时区的本地时间换算成另一个时区,或把一个 UTC 瞬时落到指定时区展示,换算前后是同一瞬时、只改展示时区,也能取各时区当前时间、偏移量与全部可用时区 ID。
二、所需环境
JDK 17或以上
三、方法与调用示例(按需调用)
🔢 方法序号:1
🎯 方法用途:
- 把「某时区的本地时间」换算到另一个时区,换算前后是同一时刻
- 跨时区约会议、把用户本地时间落到服务器时区展示时用
🧩 方法定义:public static ZonedDateTime convert(LocalDateTime localDateTime, ZoneId fromZone, ZoneId toZone)
🗣️ 入参解释:public static ZonedDateTime convert(本地时间, 源时区, 目标时区)
📤 返回值解释:ZonedDateTime,目标时区下的同一瞬间
💡 边界口径:
- 等价于
localDateTime.atZone(fromZone).withZoneSameInstant(toZone),只改展示用的时区 - 本地时间落在源时区夏令时缺口时被跳过的钟点,按
atZone规则整体后移 - 落在秋季回拨的重复时间上时取较早的那次偏移
- 三个入参任一为 null 抛
IllegalArgumentException,消息带上参数名
🧪 方法示例:
- 6 月的上海中午 12 点换到纽约拿到
2026-06-15T00:00-04:00[America/New_York],纽约在夏令时差 12 小时 - 1 月同样写法拿到
2026-01-14T23:00-05:00[America/New_York],冬令时差 13 小时且跨到前一天 - 换算前后两个瞬时相比,判断拿到
true,都是2026-06-15T04:00:00Z - 纽约春季拨快跳过的凌晨 2 点半拿到
2026-03-08T07:30Z[UTC],整体后移了 - 秋季回拨出现两次的凌晨 1 点半拿到
2026-11-01T05:30Z[UTC],取较早的那次偏移 - 本地时间传 null 抛
localDateTime 不能为null,源时区传 null 抛fromZone 不能为null
🔢 方法序号:2
🎯 方法用途:
- 把一个
Instant落到指定时区上展示,得到带时区的日期时间 - 库里存的是 UTC 瞬时、页面要按用户时区显示时用
🧩 方法定义:public static ZonedDateTime atZone(Instant instant, ZoneId zone)
🗣️ 入参解释:public static ZonedDateTime atZone(瞬时点, 目标时区)
📤 返回值解释:ZonedDateTime,该瞬时指定时区下的表示
💡 边界口径:
- 瞬时点本身不含时区,换个时区只是换一种读法
- 入参为 null 抛
IllegalArgumentException - 时区要先用
of或beijing、utc拿到ZoneId
🧪 方法示例:
- 同一个
2026-07-01T00:00:00Z落到上海拿到2026-07-01T08:00+08:00[Asia/Shanghai] - 同一瞬时落到东京拿到
2026-07-01T09:00+09:00[Asia/Tokyo] - 瞬时点传 null 抛
instant 不能为null
🔢 方法序号:3
🎯 方法用途:
- 取指定时区的当前时间,返回带时区的
ZonedDateTime - 多时区看板、日志里要同时给几个时区的当下时刻时用
🧩 方法定义:public static ZonedDateTime now(ZoneId zone)
🗣️ 入参解释:public static ZonedDateTime now(时区)
📤 返回值解释:ZonedDateTime,该时区的此刻
💡 边界口径:
- 各时区结果指向同一瞬间,只是本地表示不同
- 精度到纳秒,比
nowString保留更多位 - 时区为 null 抛
IllegalArgumentException
🧪 方法示例:
- 同一时刻三个时区分别拿到
上海 2026-10-13T12:01:36.040047900、纽约 2026-10-13T00:01:36.040047900、UTC 2026-10-13T04:01:36.040047900
🔢 方法序号:4
🎯 方法用途:
- 取指定时区当前时间的字符串,固定
yyyy-MM-dd HH:mm:ss - 界面直接展示、写进备注字段这类不要时区后缀的场合用它
🧩 方法定义:public static String nowString(ZoneId zone)
🗣️ 入参解释:public static String nowString(时区)
📤 返回值解释:String,定版格式的时间文本,不含时区标识
💡 边界口径:
- 显式用
Locale.ROOT,避免区域敏感的数字符号 - 结果不带时区标识,跨时区对账时要连同时区一起落库
- 精度只到秒,纳秒被截掉
- 时区为 null 抛
IllegalArgumentException
🧪 方法示例:
nowString(上海)拿到2026-10-13 12:01:36,格式固定到秒nowString(utc)拿到2026-10-13 04:01:36,两者是同一瞬间
🔢 方法序号:5
🎯 方法用途:
- 拿到 JDK 提供的全部可用时区 ID 列表
- 做时区下拉框、校验用户配置的时区是否存在时用
🧩 方法定义:public static List<String> availableZoneIds()
🗣️ 入参解释:public static List<String> availableZoneIds()(无入参)
📤 返回值解释:List<String>,升序排列的时区 ID,不可变
💡 边界口径:
- 列表在类加载时构建一次后只读复用,多次调用返回同一实例
- 内容是 JDK 的 IANA 数据,JDK 版本不同数量会变
- 不可修改,往里 add 抛
UnsupportedOperationException
🧪 方法示例:
availableZoneIds().size()拿到604 个 ID- 第一个元素是
Africa/Abidjan,按升序排列 - 列表里是否含
Asia/Shanghai,判断拿到true
🔢 方法序号:6
🎯 方法用途:
- 取某时区相对 UTC 的小时偏移,按当前时刻计算
- 展示「UTC+8」这类标签、做偏移换算校验时用
🧩 方法定义:public static double utcOffsetHours(ZoneId zone)
🗣️ 入参解释:public static double utcOffsetHours(时区)
📤 返回值解释:double,相对 UTC 的小时数,可为负、可为半小时
💡 边界口径:
- 有夏令时的时区结果随时刻变化,纽约在 -5.0 与 -4.0 之间切换
- 半小时与 45 分钟时区都能精确表示,现实偏移都是 15 分钟的整数倍,二进制浮点对 .25/.5/.75 无舍入误差
- 要某个具体时刻的偏移,得改用该时刻的
ZonedDateTime去取 - 时区为 null 抛
IllegalArgumentException
🧪 方法示例:
utcOffsetHours(beijing())拿到8.0- 伦敦是
1.0,纽约是-4.0,符号按东西半球区分 - 加尔各答拿到
5.5,半小时偏移精确表示 - 加德满都拿到
5.75,45 分钟偏移同样精确 - 时区传 null 抛
zone 不能为null
🔢 方法序号:7
🎯 方法用途:
- 把字符串时区 ID 解析成
ZoneId,接受多种常见写法并去掉首尾空白 - 配置项、请求参数里存的是时区字符串时,先过这一道再用
🧩 方法定义:public static ZoneId of(String zoneId)
🗣️ 入参解释:public static ZoneId of(时区ID字符串)
📤 返回值解释:ZoneId,解析好的时区对象
💡 边界口径:
- 接受
Asia/Shanghai、UTC、GMT+8、+08:00这几类写法 - IANA 里没有
Asia/Beijing,北京的标准 ID 是Asia/Shanghai - 空白串与非法 ID 抛
IllegalArgumentException,只把DateTimeException转抛,不吞其它异常 - 偏移量离谱的写法同样被拒
🧪 方法示例:
of("Asia/Shanghai")解析成Asia/Shanghaiof("America/New_York")解析成America/New_York- 偏移写法
of("GMT+8")拿到GMT+08:00 of("+08:00")这种纯偏移写法同样能解析,结果是+08:00- 用不存在的
Asia/Beijing抛非法时区ID: Asia/Beijing - 偏移离谱的
GMT+25抛非法时区ID: GMT+25 - 传空白串抛
时区ID不能为空
🔢 方法序号:8
🎯 方法用途:
- 直接给出北京的
ZoneId,省得写错成Asia/Beijing - 国内业务默认时区、以及给
of做对照时用
🧩 方法定义:public static ZoneId beijing()
🗣️ 入参解释:public static ZoneId beijing()(无入参)
📤 返回值解释:ZoneId,即 Asia/Shanghai
💡 边界口径:
- 常量在类加载时构建,多次调用返回同一实例
- 它是 IANA 的
Asia/Shanghai,不是自造 ID,跨语言环境一致 - 中国无夏令时,偏移恒为 +8
🧪 方法示例:
beijing()与of("Asia/Shanghai")相等,判断拿到true
🔢 方法序号:9
🎯 方法用途:
- 直接给出 UTC 的
ZoneId,落库与跨系统对账的基准时区 - 存瞬时、比对不同来源时间时用它做统一口径
🧩 方法定义:public static ZoneId utc()
🗣️ 入参解释:public static ZoneId utc()(无入参)
📤 返回值解释:ZoneId,即 UTC
💡 边界口径:
- 常量复用,多次调用同一实例
- 与
of("UTC")等价,偏移恒为 0 - 只作时区用,瞬时本身请用
Instant
🧪 方法示例:
utcOffsetHours(utc())拿到0.0,UTC 没有偏移- 同一时刻
now(utc())拿到2026-10-13T04:01:36.040047900,比上海慢 8 小时
四、工具类源码(可直接复制)
📦 源码文件