You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取UTC时区下带三位小数秒的OffsetDateTime对象?

如何生成带三位小数秒的UTC时区OffsetDateTime对象?

原代码生成的OffsetDateTime会带六位小数秒:

OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneId.of("UTC"));

我需要一个工具方法,返回当前UTC时区下、仅带三位小数秒的OffsetDateTime对象(示例:2023-05-15T02:22:39.330Z)。但尝试下面的代码后,返回结果还是带六位小数秒:

public static OffsetDateTime offsetDateTimeUtc(){
    OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneId.of("UTC"));
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ss.SSS'Z'");
    return OffsetDateTime.parse(offsetDateTime.toString());
}

问题原因

你写的代码根本没用到自己定义的DateTimeFormatter——offsetDateTime.toString()默认会输出完整精度的ISO-8601字符串(比如2023-05-15T02:22:39.330123Z),解析后自然还是保留六位小数。

可行解决方案

不需要绕格式化解析的弯路,直接对时间对象的精度做处理即可,推荐两种方式:

方法一:截断到毫秒级(直接保留前三位小数)

最简单高效的方式,直接舍去毫秒之后的所有精度:

public static OffsetDateTime offsetDateTimeUtc() {
    return OffsetDateTime.now(ZoneId.of("UTC"))
            .truncatedTo(ChronoUnit.MILLIS);
}

方法二:四舍五入到毫秒级

如果需要对小数部分做四舍五入处理,可以手动计算调整:

public static OffsetDateTime offsetDateTimeUtc() {
    OffsetDateTime now = OffsetDateTime.now(ZoneId.of("UTC"));
    long currentMillis = now.getLong(ChronoField.MILLI_OF_SECOND);
    long currentNanos = now.getLong(ChronoField.NANO_OF_SECOND);
    
    // 计算四舍五入后的毫秒值
    long roundedMillis = currentMillis + (currentNanos >= 500_000 ? 1 : 0);
    
    // 处理毫秒满1000需要进位到秒的情况
    if (roundedMillis == 1000) {
        return now.plusSeconds(1).with(ChronoField.MILLI_OF_SECOND, 0);
    }
    return now.with(ChronoField.MILLI_OF_SECOND, roundedMillis);
}

(可选)格式化解析的正确写法

如果一定要用格式化解析的方式,得确保用自己定义的DateTimeFormatter来格式化原对象,而不是调用默认的toString():

public static OffsetDateTime offsetDateTimeUtc() {
    OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneId.of("UTC"));
    // 注意用yyyy而非YYYY(YYYY是周年,日常用yyyy表示年份),用X自动处理UTC偏移量
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    String formattedStr = formatter.format(offsetDateTime);
    return OffsetDateTime.parse(formattedStr, formatter);
}

不过这种方式涉及字符串操作,性能不如直接截断/舍入。

内容的提问来源于stack exchange,提问作者Naim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:00:08