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)
只需要修改两个点:
- 将格式符
hh改为HH(24小时制小时标识,范围0-23) - 格式字符串补充毫秒部分,匹配输入的
.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
相关产品推荐
相关产品推荐

