Kotlin使用SimpleDateFormat处理日期输出格式错误是什么原因?
问题原因分析
- 获取当年第一天的代码逻辑错误
你调用calendar.set(Calendar.YEAR,0,1)的用法不符合Calendar API定义:Calendar.set(int field, int value)是单属性赋值方法,你传入三个参数的情况下,方法会被识别为set(int year, int month, int dayOfMonth),第一个参数直接传了常量Calendar.YEAR(它的实际值是1),所以相当于把年份设为1,月份设为0(一月),日期设为1,最后得到的是公元1年1月1日,和你预期的「当年第一天」完全不符,这也是输出结果中年份显示为1的直接原因。
正确的当年第一天写法:
val calendar = Calendar.getInstance() // 月份设为1月 calendar.set(Calendar.MONTH, Calendar.JANUARY) // 日期设为当月第一天 calendar.set(Calendar.DAY_OF_MONTH, 1) // 可选:把时分秒毫秒设为0,得到当天零点 calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) calendar.set(Calendar.MILLISECOND, 0) val date = calendar.time- 获取当年第一天的代码逻辑错误
- 对
Date类的认知误区java.util.Date本身不存储任何格式信息,它只是一个包装了时间戳的类。你调用Log.i("mpurusharth","last $it")打印Date对象时,调用的是Date默认的toString()方法,输出固定格式的字符串,和你定义的SimpleDateFormat没有任何关系。
你写的parseDate方法逻辑完全冗余:recordDtmFormat.parse(recordDtmFormat.format(date))相当于把Date转成指定格式字符串再转回Date,除了会丢失毫秒精度之外没有任何作用。如果需要获取指定格式的日期字符串,直接调用recordDtmFormat.format(date)即可,不需要再parse回Date。
- 对
- 工具类其他逻辑错误
你写的getTimeStamp方法中,Calendar.getInstance().time.toString()得到的字符串格式和recordDtmFormat指定的yyyy-MM-dd HH:mm:ss不匹配,运行时会抛出解析异常,无法正常使用。
- 工具类其他逻辑错误
- 额外注意点:
SimpleDateFormat是线程不安全的,不要把它声明为类的成员变量在多线程场景下复用,每次使用直接创建新实例,或者用线程本地存储包装。
- 额外注意点:
修复后的工具类参考
class TimeStampFormat { private val recordDtmFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH) // 直接返回当前时间的Date对象,不需要做多余的格式转换 fun getTimeStamp(): Date { return Date() } // 把Date转为指定格式的字符串,这才是你需要的格式化方法 fun formatDate(date: Date): String { return recordDtmFormat.format(date).also { Log.i("mpurusharth", "formatted date: $it") } } // 把指定格式的字符串转为Date对象 fun parseDate(timeStr: String): Date { return recordDtmFormat.parse(timeStr)!!.also { Log.i("mpurusharth", "parsed timestamp: ${it.time}") } } }
正确调用示例
// 获取当年第一天 val calendar = Calendar.getInstance() calendar.set(Calendar.MONTH, Calendar.JANUARY) calendar.set(Calendar.DAY_OF_MONTH, 1) calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) val firstDayOfYear = calendar.time // 格式化输出 val format = TimeStampFormat() val formattedDateStr = format.formatDate(firstDayOfYear) // 输出的formattedDateStr就是符合你预期的"2024-01-01 00:00:00"格式的字符串
内容的提问来源于stack exchange,提问作者Pemba Tamang
相关产品推荐
相关产品推荐

