Java 1.7中如何转换UTC日期字符串并去除T和Z?
问题排查与解决方案
嗨,我来帮你理清问题所在,然后给出修复方案和更简便的实现方式~
1. 为啥会抛出ParseException?
你的代码核心问题是解析用的日期格式和输入字符串完全不匹配,还有几个小细节也错了:
- 你用
SimpleDateFormat("YYYY-MM-dd HH:mm:ss")去解析2018-05-23T23:22:16.000Z,输入里的T分隔符、.000毫秒部分、末尾的Z都没在解析模式里对应上,自然解析失败。 - 最后返回
convertedDate.toString()是错的,Date的toString()会输出JVM默认时区的日期,格式也不是你要的yyyy-MM-dd HH:mm:ss。 - 额外提醒:
YYYY是“周年”(按周算的年份),日常用日期应该用yyyy(公历年),不然跨年周可能会出问题。
2. 修复后的原生Java 1.7实现
针对Java 1.7,我们需要先按输入格式解析,再按目标格式输出:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class DateUtils { public static String convertToNewFormat(String dateStr) throws ParseException { // 定义输入格式:匹配带T、毫秒、Z的UTC字符串 SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); inputSdf.setTimeZone(TimeZone.getTimeZone("UTC")); // 解析得到Date对象 Date utcDate = inputSdf.parse(dateStr); // 定义输出格式:你想要的目标格式 SimpleDateFormat outputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); outputSdf.setTimeZone(TimeZone.getTimeZone("UTC")); // 格式化输出 return outputSdf.format(utcDate); } }
这里的关键是:
- 输入模式里的
'T'和'Z'用单引号包裹,告诉解析器这些是固定字符,不是日期模式的一部分。 .SSS用来匹配输入里的.000毫秒部分。- 解析和格式化都设置UTC时区,确保时间不会因为本地时区偏移而变。
3. 用Apache Commons Lang简化实现
如果可以引入第三方库,Apache Commons Lang的FastDateFormat会更省心——它线程安全,比SimpleDateFormat更可靠,代码也更简洁:
先引入依赖(以Maven为例):
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> <!-- 选一个兼容Java 1.7的版本即可 --> </dependency>
然后实现代码:
import org.apache.commons.lang3.time.FastDateFormat; import java.text.ParseException; import java.util.TimeZone; public class DateUtils { // 预定义格式实例,线程安全可复用 private static final FastDateFormat INPUT_FORMAT = FastDateFormat.getInstance( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC") ); private static final FastDateFormat OUTPUT_FORMAT = FastDateFormat.getInstance( "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("UTC") ); public static String convertToNewFormat(String dateStr) throws ParseException { return OUTPUT_FORMAT.format(INPUT_FORMAT.parse(dateStr)); } }
这样代码更简洁,还避免了SimpleDateFormat在多线程环境下的线程安全问题,推荐在项目里使用~
内容的提问来源于stack exchange,提问作者PacificNW_Lover
相关产品推荐
相关产品推荐

