前言
在 Kotlin(基于 JVM)中,日期时间处理主要依赖 Java 8 引入的 java.time 包(JSR-310),它取代了老旧且问题较多的 java.util.Date 和 Calendar。
Kotlin 本身不提供新的日期类,但能以更简洁、安全的方式使用这些 Java 类。
核心类包括:
LocalDate:仅日期(年-月-日),无时区。YearMonth:仅日期(年-月),无时区。LocalTime:仅时间(时-分-秒-纳秒),无时区。LocalDateTime:日期 + 时间,无时区。ZonedDateTime:日期 + 时间 + 时区(含夏令时规则)。OffsetDateTime:日期 + 时间 + UTC 偏移量(无时区规则)。Instant:UTC 时间戳(自 1970-01-01T00:00:00Z 起的瞬时点)。Duration:基于秒/纳秒的时间量(如 2 小时)。Period:基于年-月-日的日历量(如 1 年 3 个月)。DateTimeFormatter:线程安全的格式化与解析工具。ZoneId/ZoneOffset:表示时区或偏移量。
遗留类如
java.util.Date、Calendar和SimpleDateFormat已不推荐使用。
日期 <=> 字符串
| 方式 | 优点 | 缺点 |
|---|---|---|
SimpleDateFormat |
简单直接,兼容老代码 | 非线程安全,API 设计老旧 |
java.time + Date.from() / Date.toInstant() |
线程安全、功能强大、可读性好 | 代码稍长,需理解新时间 API |
日期 <=> 字符串
使用java.time(推荐)
Date => 字符串
1 | import java.time.LocalDateTime |
字符串 => Date
1 | import java.time.LocalDateTime |
使用SimpleDateFormat
Date => 字符串
1 | import java.text.SimpleDateFormat |
字符串 => Date
1 | import java.text.SimpleDateFormat |
年月 <=> 字符串
年月 => 字符串
1 | val yearMonth = YearMonth.now() // 当前年月 |
字符串 => 年月
1 | val defaultMonth = "2025-06" |
获取某日所在周起止
1 | import java.time.DayOfWeek |
获取某月起止
1 | import java.time.DayOfWeek |
使用
1 | val dateStr = "2025-06" |
获取两个日期之间的所有日期
1 | val dateStr = "2025-06" |
LocalDate
LocalDate 是 Java 8 引入的 java.time 包中用于表示不带时间、不带时区的日期(年-月-日) 的不可变类。
它在 Kotlin 中使用非常自然,API 清晰且线程安全。
以下是 LocalDate 常用方法及示例(Kotlin 语法):
创建 LocalDate
1 | import java.time.LocalDate |
指定格式
1 | val str2 = "2025年12月08日" |
格式化为字符串
1 | import java.time.format.DateTimeFormatter |
获取字段(年、月、日等)
1 | val date = LocalDate.of(2025, 12, 8) |
日期计算(加减)
所有操作返回新对象(不可变):
1 | val date = LocalDate.of(2025, 12, 8) |
比较日期
1 | val d1 = LocalDate.of(2025, 12, 8) |
💡
LocalDate实现了Comparable,可直接用于sorted()、min()、max()等。
调整日期(withXXX)
1 | val date = LocalDate.of(2025, 12, 8) |
需要导入:
import java.time.temporal.TemporalAdjusters
与其它时间类型互转(简要)
1 | // LocalDate → LocalDateTime(加上时间,默认 00:00) |
小贴士
LocalDate没有时区概念,适合表示生日、节假日、合同起止日等。- 所有方法都是不可变操作,不会修改原对象。
- 推荐配合
DateTimeFormatter和TemporalAdjusters使用高级功能。