Java LocalTime

LocalTime 是 Java 8 引入的時間類別,用於表示不含日期的時間(時、分、秒、奈秒),位於 java.time 套件中。

引入套件

import java.time.LocalTime;

建立 LocalTime

取得當前時間

LocalTime now = LocalTime.now();
System.out.println(now);  // 14:30:45.123456789

指定時間

// of(時, 分)
LocalTime time1 = LocalTime.of(14, 30);
System.out.println(time1);  // 14:30

// of(時, 分, 秒)
LocalTime time2 = LocalTime.of(14, 30, 45);
System.out.println(time2);  // 14:30:45

// of(時, 分, 秒, 奈秒)
LocalTime time3 = LocalTime.of(14, 30, 45, 123456789);
System.out.println(time3);  // 14:30:45.123456789

從字串解析

LocalTime time = LocalTime.parse("14:30:45");
System.out.println(time);  // 14:30:45

// 自訂格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime time2 = LocalTime.parse("14:30:45", formatter);

特殊常數

LocalTime midnight = LocalTime.MIDNIGHT;  // 00:00
LocalTime noon = LocalTime.NOON;          // 12:00
LocalTime min = LocalTime.MIN;            // 00:00
LocalTime max = LocalTime.MAX;            // 23:59:59.999999999

取得時間資訊

LocalTime time = LocalTime.of(14, 30, 45, 123456789);

int hour = time.getHour();         // 14
int minute = time.getMinute();     // 30
int second = time.getSecond();     // 45
int nano = time.getNano();         // 123456789

// 轉換為當天的秒數
int secondOfDay = time.toSecondOfDay();  // 52245

// 轉換為當天的奈秒數
long nanoOfDay = time.toNanoOfDay();

時間運算

加減時間

LocalTime time = LocalTime.of(14, 30, 0);

// 加上時間
LocalTime plus2Hours = time.plusHours(2);      // 16:30
LocalTime plus30Mins = time.plusMinutes(30);   // 15:00
LocalTime plus30Secs = time.plusSeconds(30);   // 14:30:30
LocalTime plusNanos = time.plusNanos(1000000); // 14:30:00.001

// 減去時間
LocalTime minus1Hour = time.minusHours(1);     // 13:30
LocalTime minus15Mins = time.minusMinutes(15); // 14:15

跨午夜處理

LocalTime time = LocalTime.of(23, 30);
LocalTime newTime = time.plusHours(2);
System.out.println(newTime);  // 01:30(自動回到次日凌晨)

LocalTime time2 = LocalTime.of(1, 0);
LocalTime earlier = time2.minusHours(3);
System.out.println(earlier);  // 22:00(自動回到前一天晚上)

修改時間

LocalTime time = LocalTime.of(14, 30, 45);

LocalTime newHour = time.withHour(10);       // 10:30:45
LocalTime newMinute = time.withMinute(0);    // 14:00:45
LocalTime newSecond = time.withSecond(0);    // 14:30:00
LocalTime newNano = time.withNano(0);        // 14:30:45

時間比較

LocalTime time1 = LocalTime.of(14, 30);
LocalTime time2 = LocalTime.of(16, 0);

boolean isBefore = time1.isBefore(time2);  // true
boolean isAfter = time1.isAfter(time2);    // false
boolean equals = time1.equals(time2);      // false

int result = time1.compareTo(time2);  // 負數(time1 較早)

計算時間差距

LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);

// 使用 Duration
Duration duration = Duration.between(start, end);
long hours = duration.toHours();      // 8
long minutes = duration.toMinutes();  // 510

// 使用 ChronoUnit
long hoursBetween = ChronoUnit.HOURS.between(start, end);     // 8
long minutesBetween = ChronoUnit.MINUTES.between(start, end); // 510
long secondsBetween = ChronoUnit.SECONDS.between(start, end); // 30600

格式化輸出

LocalTime time = LocalTime.of(14, 30, 45);

// 預設格式
System.out.println(time.toString());  // 14:30:45

// 自訂格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(time.format(formatter1));  // 14:30:45

DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("hh:mm a");
System.out.println(time.format(formatter2));  // 02:30 PM

DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("H時m分s秒");
System.out.println(time.format(formatter3));  // 14時30分45秒

轉換為其他類型

LocalTime time = LocalTime.of(14, 30, 45);
LocalDate date = LocalDate.of(2024, 12, 25);

// 結合日期建立 LocalDateTime
LocalDateTime dateTime = time.atDate(date);  // 2024-12-25T14:30:45

// 從秒數建立
LocalTime fromSeconds = LocalTime.ofSecondOfDay(52245);  // 14:30:45

// 從奈秒數建立
LocalTime fromNanos = LocalTime.ofNanoOfDay(52245000000000L);

時間截斷

LocalTime time = LocalTime.of(14, 30, 45, 123456789);

// 截斷到小時
LocalTime truncatedToHour = time.truncatedTo(ChronoUnit.HOURS);  // 14:00

// 截斷到分鐘
LocalTime truncatedToMinute = time.truncatedTo(ChronoUnit.MINUTES);  // 14:30

// 截斷到秒
LocalTime truncatedToSecond = time.truncatedTo(ChronoUnit.SECONDS);  // 14:30:45

實用範例

判斷營業時間

public static boolean isBusinessHours(LocalTime time) {
    LocalTime open = LocalTime.of(9, 0);
    LocalTime close = LocalTime.of(18, 0);
    return !time.isBefore(open) && time.isBefore(close);
}

System.out.println(isBusinessHours(LocalTime.of(10, 30)));  // true
System.out.println(isBusinessHours(LocalTime.of(20, 0)));   // false

計算工作時數

public static String calculateWorkHours(LocalTime clockIn, LocalTime clockOut) {
    Duration duration = Duration.between(clockIn, clockOut);
    long hours = duration.toHours();
    long minutes = duration.toMinutesPart();
    return hours + "小時" + minutes + "分鐘";
}

LocalTime in = LocalTime.of(9, 0);
LocalTime out = LocalTime.of(18, 30);
System.out.println(calculateWorkHours(in, out));  // 9小時30分鐘

時間區間判斷

public static boolean isInTimeRange(LocalTime time, LocalTime start, LocalTime end) {
    if (start.isBefore(end)) {
        // 正常區間(如 09:00 - 18:00)
        return !time.isBefore(start) && time.isBefore(end);
    } else {
        // 跨午夜區間(如 22:00 - 06:00)
        return !time.isBefore(start) || time.isBefore(end);
    }
}

// 夜班時間判斷
LocalTime nightStart = LocalTime.of(22, 0);
LocalTime nightEnd = LocalTime.of(6, 0);
System.out.println(isInTimeRange(LocalTime.of(23, 0), nightStart, nightEnd));  // true
System.out.println(isInTimeRange(LocalTime.of(3, 0), nightStart, nightEnd));   // true
System.out.println(isInTimeRange(LocalTime.of(12, 0), nightStart, nightEnd));  // false

格式化為 12 小時制

public static String formatTo12Hour(LocalTime time) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
    return time.format(formatter);
}

System.out.println(formatTo12Hour(LocalTime.of(14, 30)));  // 02:30 PM
System.out.println(formatTo12Hour(LocalTime.of(9, 15)));   // 09:15 AM

重點整理

  • LocalTime 表示不含日期的時間(時:分:秒.奈秒)
  • 不可變(immutable)類別
  • 使用 now() 取得當前時間
  • 使用 of() 建立指定時間
  • 跨午夜運算會自動處理(回繞到 0-24 小時範圍)
  • 使用 DurationChronoUnit 計算時間差距
  • 搭配 DateTimeFormatter 可格式化為各種格式