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

Java中SGT转UTC时12点时段转换结果异常,求解决方案

问题根源

你的代码出现时间转换错误的核心原因是日期格式符使用错误:

  • 你用了hh:mm:ss中的hh,这是12小时制的小时标识(范围1-12),当输入12:35:45时,会被解析为当天的午夜12点(等价于前一天的24点)。
  • 新加坡时间比UTC早8小时,午夜12点减去8小时就变成了前一天的16点,这就是你得到错误结果2023-02-07T16:35:45Z的原因。
  • 另外你的输入字符串包含毫秒部分.0,但格式字符串没对应处理,虽然解析时可能忽略,但会存在潜在问题。
解决方案

方案1:修复旧代码(SimpleDateFormat)

只需要修改两个点:

  1. 将格式符hh改为HH(24小时制小时标识,范围0-23)
  2. 格式字符串补充毫秒部分,匹配输入的.0,改为yyyy-MM-dd HH:mm:ss.S

修复后的代码片段:

if (dbTime == null) {
    return null;
}
// 修改格式字符串为24小时制+匹配毫秒
SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
dateTimeFormatter.setTimeZone(TimeZone.getTimeZone(ZoneId.of("Asia/Singapore")));
Instant instant = null;
try {
    instant = dateTimeFormatter.parse(dbTime).toInstant();
} catch (ParseException e) {
    LOGGER.warn("Could not parse ({}) to valid DateTime ", dbTime, e);
    return null;
}
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);
return offsetDateTime;

方案2:使用Java 8+推荐的java.time API(更优)

SimpleDateFormat和Date类存在线程不安全、设计缺陷等问题,推荐使用Java 8引入的java.time系列API,代码更简洁且不易出错:

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DateParser {
    private static final Logger LOGGER = LoggerFactory.getLogger(DateParser.class);
    // 定义线程安全的格式化器,绑定新加坡时区
    private static final DateTimeFormatter SGT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S")
            .withZone(ZoneId.of("Asia/Singapore"));

    public OffsetDateTime parseToOffsetDateTime(String dbTime) {
        if (dbTime == null) {
            return null;
        }
        try {
            // 解析为新加坡时间,转换为UTC时区的OffsetDateTime
            return OffsetDateTime.parse(dbTime, SGT_DATE_FORMATTER)
                    .withOffsetSameInstant(ZoneOffset.UTC);
        } catch (Exception e) {
            LOGGER.warn("Could not parse ({}) to valid DateTime ", dbTime, e);
            return null;
        }
    }
}
测试验证

修改后运行你的测试用例:

@Test
void canConvertSGTToUTC() {
    String sqlDate = "2023-02-08 12:35:45.0";
    var result = dateParser.parseToOffsetDateTime(sqlDate);
    assertEquals("2023-02-08T04:35:45Z", result.toString());
}

会得到预期的正确结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:46:48