如何在Kotlin中格式化Firestore服务器Timestamp时间戳
问题原因
你当前的写法存在两个核心错误:
DateTimeFormatter是Java 8引入的java.time系列时间类的专用格式化工具,不能直接用于java.util.Date类或者字符串的格式化- 先把Date转成默认字符串再截取拼接的方式严重依赖系统默认的输出格式,时区、系统语言变化时都会出错,完全不建议使用
正确实现方案
推荐直接用java.time系列API完成转换,不需要借助旧的Date类,代码更稳定,修正后的完整代码如下:
override fun onBindViewHolder(holder: OrderListViewHolder, position: Int) { val item = orderList[position] orderViewModel.setOrderProduct(item.foodItem) orderViewModel.setStatus(item.status) val foodItem = item.foodItem?.map { it.itemName } // 修正后的日期格式化逻辑 val formattedDate = item.date?.let { timestamp -> // 将Firestore Timestamp转成带时区的时间对象,此处用系统默认时区 val zonedDateTime = timestamp.toDate().toInstant().atZone(ZoneId.systemDefault()) // 创建格式化器,指定Locale.ENGLISH保证月份为英文缩写,不需要可删除该参数 val formatter = DateTimeFormatter.ofPattern("dd MMM yyyy, HH:mm", Locale.ENGLISH) formatter.format(zonedDateTime) } ?: "" // 为空时的兜底值 Log.d("dates", formattedDate) holder.orderDate.text = formattedDate holder.foodName.text = foodItem.toString().removeSurrounding("[", "]") holder.status.text = orderViewModel.status.value.toString() }
注意事项
- 如果你的App需要适配安卓7.1及以下版本,需要在模块级
build.gradle中开启核心库脱糖(coreLibraryDesugaring)来支持java.timeAPI - 代码中去掉了非空断言
!!,改用空安全调用避免空指针异常
可选兼容方案(不推荐)
如果你不想开启脱糖,也可以用旧的SimpleDateFormat实现:
val formattedDate = item.date?.let { timestamp -> val formatter = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale.ENGLISH) formatter.format(timestamp.toDate()) } ?: ""
注意SimpleDateFormat是非线程安全的,不要声明成全局静态变量重复使用,避免多线程场景下出现格式异常。
内容的提问来源于stack exchange,提问作者Tea
相关产品推荐
相关产品推荐

