LocalTime 是 Java 8 引入的不可变日期时间对象(位于 java.time 包),用于表示 ISO-8601 日历系统中不包含时区的纯时间信息(例如 10:15:30)。它通常以“时-分-秒”的形式呈现,并支持纳秒级精度 —— 例如 13:45:30.123456789 这样的时间值可被精准存储。
该类专注于时间维度,不涉及日期或时区信息,仅描述类似墙上时钟显示的“本地时间”。由于缺乏偏移量或时区等上下文,它无法直接对应时间轴上的某个具体瞬间。
ISO-8601 日历系统作为全球多数地区通用的现代民用历法,是 LocalTime 的基础。LocalTime 假定所有日历系统均采用相同的日间时间表示方式。
LocalTime 属于基于值的类,因此应避免对其实例使用身份敏感操作(如 == 引用比较、身份哈希码或同步),这类操作可能导致不可预期的结果,比较 LocalTime 时应优先使用 equals 方法。
LocalTime 的特性:
不可变性:对象创建后无法修改,所有修改操作(如增减时间)都会返回新实例,避免线程安全问题。
精确到纳秒:支持纳秒级精度(范围:00:00:00.000000000 至 23:59:59.999999999)。
无时区依赖:仅表示本地时间,不包含时区信息,适合处理与时区无关的时间逻辑。
ISO-8601 全称为 国际标准化组织 8601 号标准(International Organization for Standardization 8601),是一套由国际标准化组织制定、用于统一表示日期和时间的规范。其核心目标是解决全球不同地区日期时间格式不统一的问题(如 “MM/DD/YYYY” 与 “DD/MM/YYYY” 的混淆),提供一套通用、无歧义、机器可解析的表示方法,广泛应用于计算机系统、数据交换、通信协议等场景。
ISO-8601 定义了多种日期、时间及组合格式,以下是最常用的核心类型:
格式类型 | 格式示例 | 说明 |
完整日期 | 2024-05-20 | 年 - 月 - 日(4 位年,2 位月 / 日,分隔符 “-”) |
省略分隔符日期 | 20240520 | 无分隔符的紧凑格式,机器解析更高效 |
年 - 月 | 2024-05 | 仅表示年份和月份(无具体日期) |
年 | 2024 | 仅表示年份 |
注意:月份和日期必须用2 位数字表示(如 1 月写作 “01”,5 日写作 “05”),避免 “2024-1-5” 这类不规范格式。
时间支持从 “时” 到 “纳秒” 的不同精度,且默认基于24 小时制(无 AM/PM 区分):
格式类型 | 格式示例 | 说明 |
时 - 分 - 秒 | 14:30:45 | 时:分: 秒(2 位时 / 分 / 秒,分隔符 “:”) |
时 - 分 | 14:30 | 仅表示时和分(无秒) |
带小数秒 | 14:30:45.123 | 秒后可加小数(支持毫秒、微秒、纳秒) |
省略分隔符时间 | 143045 | 无分隔符的紧凑格式(如1430表示 14:30) |
日期和时间组合时,需用大写字母 “T” 分隔(避免与数字混淆),这是 ISO-8601 的标志性格式:
格式示例 | 说明 |
2024-05-20T14:30:45 | 完整日期 + 完整时间(最常用) |
20240520T143045.123 | 紧凑格式 + 毫秒精度 |
2024-05-20T14:30 | 完整日期 + 时 - 分(无秒) |
ISO-8601 支持表示带时区的时间,核心是通过 “UTC 偏移量” 或 “时区标识符” 明确时间对应的地理区域:
UTC 偏移量格式:在时间后加“±HH:MM”或“±HHMM”(UTC 本身用“Z”表示,即“Zulu 时间”)。示例:2024-05-20T14:30:45+08:00(东八区时间,如北京/上海)、2024-05-20T06:30:45Z(UTC 时间)。
时区标识符格式:使用 IANA 时区标识符(如“Asia/Shanghai”),需配合偏移量,示例:2024-05-20T14:30:45+08:00[Asia/Shanghai]。
时间间隔:表示两个时间点之间的持续时间,格式为“开始时间 / 结束时间”。示例:2024-05-20T09:00:00/2024-05-20T12:00:00(2024 年 5 月 20 日 9 点到 12 点)。
周期:表示重复的时间间隔,格式为 “PnYnMnDTnHnMnS”(“P”为周期前缀,“T”分隔日期和时间部分)。示例:P1Y2M3DT4H5M6S(1 年 2 个月 3 天 4 小时 5 分 6 秒)、PT1H30M(1 小时 30 分钟)。
static LocalTime now()
获取当前系统时间(不带时区)。
static LocalTime of(int hour, int minute)
根据小时和分钟创建 LocalTime。
参数说明:
hour 表示小时,取值 0-23。
minute 表示分钟,取值 0-59。
static LocalTime of(int hour, int minute, int second)
根据小时、分钟、秒创建 LocalTime。
参数说明:
hour 表示小时,取值 0-23。
minute 表示分钟,取值 0-59。
second 表示秒,取值 0-59。
static LocalTime of(int hour, int minute, int second, int nanoOfSecond)
根据小时、分钟、秒、纳秒创建 LocalTime。
参数说明:
hour 表示小时,取值 0-23。
minute 表示分钟,取值 0-59。
second 表示秒,取值 0-59。
nanoOfSecond 表示纳秒,取值 0-999,999,999。
static LocalTime parse(CharSequence text)
解析字符串为 LocalTime(默认格式 HH:mm:ss 或 HH:mm),如14:30:25。
示例:
import java.time.LocalTime; public class LocalTimeExample { public static void main(String[] args) { // 获取当前时间 LocalTime currentTime = LocalTime.now(); System.out.println("当前时间: " + currentTime); // 使用小时、分钟创建 LocalTime specificTime1 = LocalTime.of(14, 30); System.out.println("指定时间(时:分): " + specificTime1); // 使用小时、分钟、秒创建 LocalTime specificTime2 = LocalTime.of(14, 30, 45); System.out.println("指定时间(时:分:秒): " + specificTime2); // 使用小时、分钟、秒、纳秒创建 LocalTime specificTime3 = LocalTime.of(14, 30, 45, 123456789); System.out.println("指定时间(带纳秒): " + specificTime3); // 从字符串解析 LocalTime parsedTime = LocalTime.parse("10:15:30"); System.out.println("解析的时间: " + parsedTime); } }
运行结果:
当前时间: 15:14:33.605261058 指定时间(时:分): 14:30 指定时间(时:分:秒): 14:30:45 指定时间(带纳秒): 14:30:45.123456789 解析的时间: 10:15:30
int getHour() 获取小时(24 小时制),返回值 0-23。
int getMinute() 获取分钟,返回值 0-59。
int getSecond() 获取秒,返回值 0-59。
int getNano() 获取纳秒,返回值 0-999,999,999。
示例:
import java.time.LocalTime; public class LocalTimeGetTime { public static void main(String[] args) { LocalTime time = LocalTime.of(15, 30, 45, 123456789); int hour = time.getHour(); // 小时 (0-23) int minute = time.getMinute(); // 分钟 (0-59) int second = time.getSecond(); // 秒 (0-59) int nano = time.getNano(); // 纳秒 (0-999,999,999) System.out.println("小时: " + hour); System.out.println("分钟: " + minute); System.out.println("秒: " + second); System.out.println("纳秒: " + nano); } }
运行结果:
小时: 15 分钟: 30 秒: 45 纳秒: 123456789
LocalTime plusHours(long hoursToAdd)
增加指定小时数,参数 hoursToAdd 表示设置的小时,可正可负。正数小时增加小时数,负数表示减少小时数。
LocalTime plusMinutes(long minutesToAdd)
增加指定分钟数,参数 minutesToAdd 表示设置的分钟,可正可负。
LocalTime plusSeconds(long secondsToAdd)
增加指定秒数,参数 secondsToAdd 表示设置秒数,可正可负。
LocalTime minusHours(long hoursToSubtract)
减少指定小时数,参数 hoursToSubtract 表示减少的小时数,可正可负。
LocalTime withHour(int hour)
修改小时值,参数 hour 表示小时,取值 0-23。
LocalTime withMinute(int minute)
修改分钟值,参数 minute 表示分钟,取值 0-59。
示例:
import java.time.LocalTime; public class LocalTimeSetTimeExample { public static void main(String[] args) { LocalTime original = LocalTime.of(10, 0); System.out.println("原时间:" + original); // 增加小时 LocalTime plusHours = original.plusHours(2); // 12:00 System.out.println("增加2小时:" + plusHours); // 增加分钟 LocalTime plusMinutes = original.plusMinutes(30); // 10:30 System.out.println("增加30分钟:" + plusMinutes); // 减少小时 LocalTime minusHours = original.minusHours(1); // 09:00 System.out.println("减少1小时:" + minusHours); // 减少分钟 LocalTime minusMinutes = original.minusMinutes(15); // 09:45 System.out.println("减少15分钟:" + minusMinutes); // 设置小时 LocalTime withHour = original.withHour(14); // 14:00 System.out.println("设置小时为14点:" + withHour); // 设置分钟 LocalTime withMinute = original.withMinute(45); // 10:45 System.out.println("设置分钟为45:" + withMinute); } }
运行结果:
原时间:10:00 增加2小时:12:00 增加30分钟:10:30 减少1小时:09:00 减少15分钟:09:45 设置小时为14点:14:00 设置分钟为45:10:45
boolean isBefore(LocalTime other)
判断当前时间是否早于目标时间。参数 other 为比较的目标时间。返回 true 表示当前时间更早,返回 false 表示当前时间不早于目标时间(即晚于或等于)。
boolean isAfter(LocalTime other)
判断当前时间是否晚于目标时间。参数 other 为比较的目标时间。返回 true 表示当前时间更晚,返回 false 表示当前时间不晚于目标时间(即早于或等于)。
boolean isEqual(LocalTime other)
判断当前时间与目标时间是否完全相等(精确到纳秒)。参数 other 为比较的目标时间。返回 true 表示两者相等,返回 false 表示不相等。
示例:
import java.time.LocalTime; public class LocalTimeComp { public static void main(String[] args) { // 创建两个时间对象用于比较 LocalTime time1 = LocalTime.of(10, 30); // 10:30 LocalTime time2 = LocalTime.of(12, 15); // 12:15 // 比较time1是否在time2之前 boolean isBefore = time1.isBefore(time2); // true (10:30 在 12:15 之前) System.out.println("time1是否在time2之前: " + isBefore + " (10:30 在 12:15 之前)"); // 比较time1是否在time2之后 boolean isAfter = time1.isAfter(time2); // false (10:30 不在 12:15 之后) System.out.println("time1是否在time2之后: " + isAfter + " (10:30 不在 12:15 之后)"); // 检查time1是否是午夜(00:00) boolean isMidnight = time1.equals(LocalTime.MIDNIGHT); // false (time1是10:30) System.out.println("time1是否是午夜(00:00): " + isMidnight); // 检查time2是否是正午(12:00) boolean isNoon = time2.equals(LocalTime.NOON); // false (time2是12:15,NOON是12:00) System.out.println("time2是否是正午(12:00): " + isNoon); // 额外示例:比较相等的情况 LocalTime time3 = LocalTime.of(12, 15); boolean isEqual = time2.equals(time3); // true (两个时间都是12:15) System.out.println("time2与time3是否相等: " + isEqual + " (两个时间都是12:15)"); } }
运行结果:
time1是否在time2之前: true (10:30 在 12:15 之前) time1是否在time2之后: false (10:30 不在 12:15 之后) time1是否是午夜(00:00): false time2是否是正午(12:00): false time2与time3是否相等: true (两个时间都是12:15)
LocalTime truncatedTo(TemporalUnit unit)
将时间截断到指定的单位,截断后该单位以下的时间字段会被设置为最小值(通常为 0)。例如,截断到分钟时,秒和纳秒会被清零;截断到小时时,分钟、秒和纳秒会被清零。参数 unit 表示要截断到的时间单位(需是 LocalTime 支持的单位,如 ChronoUnit.HOURS、ChronoUnit.MINUTES、ChronoUnit.SECONDS 等)。
示例:
import java.time.LocalTime; import java.time.temporal.ChronoUnit; public class LocalTimeTruncateExample { public static void main(String[] args) { // 创建一个包含时、分、秒、纳秒的时间 LocalTime originalTime = LocalTime.of(14, 35, 47, 123456789); System.out.println("原始时间: " + originalTime); // 输出:14:35:47.123456789 // 截断到小时(分钟、秒、纳秒清零) LocalTime truncatedToHour = originalTime.truncatedTo(ChronoUnit.HOURS); System.out.println("截断到小时: " + truncatedToHour); // 输出:14:00 // 截断到分钟(秒、纳秒清零) LocalTime truncatedToMinute = originalTime.truncatedTo(ChronoUnit.MINUTES); System.out.println("截断到分钟: " + truncatedToMinute); // 输出:14:35 // 截断到秒(纳秒清零) LocalTime truncatedToSecond = originalTime.truncatedTo(ChronoUnit.SECONDS); System.out.println("截断到秒: " + truncatedToSecond); // 输出:14:35:47 } }
运行结果:
原始时间: 14:35:47.123456789 截断到小时: 14:00 截断到分钟: 14:35 截断到秒: 14:35:47
String format(DateTimeFormatter formatter)
按指定格式将时间转换为字符串。参数 formatter 为自定义格式器,如 DateTimeFormatter.ofPattern("HH:mm")。
示例:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class TimeFormatExample { public static void main(String[] args) { // 获取当前时间 LocalDateTime now = LocalDateTime.now(); // 创建自定义格式器 DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("HH:mm:ss"); DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("MM/dd/yyyy"); // 使用format方法转换为字符串 String formattedTime1 = now.format(formatter1); String formattedTime2 = now.format(formatter2); String formattedTime3 = now.format(formatter3); System.out.println("完整时间格式: " + formattedTime1); System.out.println("仅时间部分: " + formattedTime2); System.out.println("仅日期部分: " + formattedTime3); } }
运行结果:
完整时间格式: 2025-09-02 06:27:19 仅时间部分: 06:27:19 仅日期部分: 09/02/2025
(1)LocalTime 不包含时区信息,如需处理时区,请使用 ZonedDateTime 或 OffsetTime
(2)所有修改方法(如 plusHours(), withMinute())都会返回一个新的 LocalTime 实例,原实例保持不变。
(3)解析字符串时,默认格式为 HH:mm:ss 或 HH:mm:ss.SSS 等符合 ISO-8601 标准的格式
LocalTime 提供了清晰、直观的 API 来处理时间,避免了旧版日期时间 API 的诸多问题,是处理本地时间的首选类。