Java 7中Calendar.getTime()时区偏移及微秒解析问题求助
解决Java 7中Calendar时区偏移与微秒解析问题
咱们先拆解你遇到的两个问题,逐个给出可行方案:
一、阻止Calendar.getTime()的“时区偏移”
首先得纠正一个关键认知:Date对象本身不存储时区信息,它本质上只是一个从1970-01-01T00:00:00Z(UTC)开始计算的毫秒数。你看到的“增加两小时(GMT+2)”,并不是getTime()方法修改了时区,而是后续展示/转换这个Date时,用了JVM的默认时区(GMT+2)来格式化输出。
要让整个流程基于UTC处理,只需要给Calendar强制设置UTC时区即可:
Calendar cal = javax.xml.bind.DatatypeConverter.parseDateTime("2017-10-20T07:10:08.123458Z"); // 强制将Calendar的时区锁定为UTC cal.setTimeZone(TimeZone.getTimeZone("UTC")); Date dateFromCal = cal.getTime();
如果需要输出这个时间,记得用UTC时区来格式化,避免默认时区干扰:
SimpleDateFormat utcFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); // 输出会和原始字符串的UTC时间完全一致 System.out.println(utcFormatter.format(dateFromCal));
二、Java 7的微秒支持解决方案
Java 7及更早版本中,Date和Calendar只能精确到毫秒,微秒部分会被直接丢弃。针对这个问题,有两种实用的解决思路:
1. 手动拆分微秒(无需第三方库)
如果只是需要保留微秒信息用于展示或存储,不需要纳入时间戳计算,可以手动拆分字符串,把微秒部分单独提取:
String inputDate = "2017-10-20T07:10:08.123458Z"; // 拆分日期主体和小数部分 String[] dateParts = inputDate.split("\\."); String dateMain = dateParts[0]; String fractionPart = dateParts[1].replace("Z", ""); // 取前三位作为毫秒,剩下的作为微秒单独存储 String millisPart = fractionPart.substring(0, 3); int microseconds = Integer.parseInt(fractionPart.substring(3)); // 解析带毫秒的日期部分 Calendar cal = DatatypeConverter.parseDateTime(dateMain + "." + millisPart + "Z"); cal.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = cal.getTime(); // 后续可以把date和microseconds结合使用,比如存储到数据库的两个字段
2. 使用Joda-Time库(推荐,支持完整微秒处理)
Java 7没有内置的微秒支持,Joda-Time是当时行业广泛使用的时间处理库,它支持纳秒级精度,能完美解决微秒解析问题:
// 先引入Joda-Time依赖(比如Maven中添加对应依赖) DateTimeFormatter formatter = ISODateTimeFormat.dateTime(); // 直接解析包含微秒的UTC时间字符串 DateTime dateTime = formatter.parseDateTime("2017-10-20T07:10:08.123458Z"); // 获取毫秒时间戳 long millis = dateTime.getMillis(); // 获取微秒部分(按需使用) int micros = dateTime.getMicrosOfSecond();
Joda-Time的API设计比原生Calendar/Date更直观,也能避免很多时区相关的坑,是Java 8之前处理复杂时间场景的标准选择。
内容的提问来源于stack exchange,提问作者Christopher Barrett
相关产品推荐
相关产品推荐

