Android中解析服务器时间并转换为本地时间显示至RecyclerView
解决ISO时间转本地时间并格式化的问题
我来帮你搞定这个时间转换的坑!你遇到的问题核心是解析格式和输入的时间字符串不匹配,导致转换失败或者结果错误。
先看你的输入时间:2018-04-04T08:41:21.265185Z,这是标准的ISO 8601 UTC时间格式,包含了T(日期和时间分隔符)、毫秒部分(.265185)和Z(代表UTC时区)。而你原来用的SimpleDateFormat("yyyy-MM-dd HH:mm:ss")完全不匹配这个格式,自然得不到正确的Date对象。
下面给你两种解决方案,分别兼容低版本Android和推荐的高版本写法:
方案一:兼容Android API 25及以下(使用SimpleDateFormat)
// 1. 先解析ISO格式的UTC时间,注意格式字符串要完全匹配输入 SimpleDateFormat isoParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.getDefault()); isoParser.setTimeZone(TimeZone.getTimeZone("UTC")); // 必须设为UTC,因为Z代表UTC时间 Date utcDate = null; try { utcDate = isoParser.parse(bookingTime); } catch (ParseException e) { e.printStackTrace(); // 解析失败时返回默认提示,避免崩溃 return "Invalid Time"; } // 2. 将UTC时间转换为本地时区,并格式化为"h:mm a"(如8:41 PM) SimpleDateFormat localFormatter = new SimpleDateFormat("h:mm a", Locale.getDefault()); localFormatter.setTimeZone(TimeZone.getDefault()); // 使用设备本地时区 String finalTime = localFormatter.format(utcDate);
方案二:Android API 26及以上(推荐使用java.time包,线程安全)
SimpleDateFormat是线程不安全的,在RecyclerView的Adapter中频繁使用可能会出问题。API 26及以上可以用Java 8引入的java.time包,更可靠:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 解析ISO时间为UTC瞬时时间 Instant instant = Instant.parse(bookingTime); // 转换为设备本地时区的时间 ZonedDateTime localDateTime = instant.atZone(ZoneId.systemDefault()); // 格式化为目标样式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a", Locale.getDefault()); String finalTime = localDateTime.format(formatter); } else { // 这里回退到方案一的代码,兼容低版本 }
额外提醒
- 在RecyclerView的Adapter中,建议提前把所有时间转换好并存放在数据源里,不要在
onBindViewHolder中每次都解析转换,这样能提升列表滚动的性能。 - 注意Locale的设置,如果需要固定显示英文的AM/PM,就用
Locale.ENGLISH代替Locale.getDefault()。
内容的提问来源于stack exchange,提问作者Satyam Gondhale
相关产品推荐
相关产品推荐

