LocalTime をざっくり一言でいうと
LocalTime は、
「日付もタイムゾーンもいらない、“純粋な時刻(時・分・秒だけ)”」
を表すクラスです。
朝 9 時に開店、12 時に休憩開始、18 時に閉店、みたいな
- 「何時から何時まで」
- 「この時間帯かどうか」
- 「1 時間後の時刻」
といった「時刻だけ」の話を、安全に、分かりやすく扱うための道具だと思ってください。
「2025-01-01 09:00」ではなく、「09:00 という時刻」だけを扱いたいときの主役です。
LocalTime の基本:生成と取り出し
「今の時刻」と「指定した時刻」を作る
LocalTime は java.time パッケージにあります。
次の二つをまず押さえてください。
import java.time.LocalTime;
public class LocalTimeBasic {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println("now = " + now); // 例: 14:23:45.123456789
LocalTime nineAM = LocalTime.of(9, 0); // 09:00:00
LocalTime precise = LocalTime.of(9, 30, 15); // 09:30:15
System.out.println(nineAM); // 09:00
System.out.println(precise); // 09:30:15
}
}
Java重要なポイントは、of(時, 分, 秒) の時刻は、直感通り「0〜23 時」「0〜59 分」です。
古い API のような変なオフセットはありません。
LocalTime.now() は「そのマシンのデフォルトタイムゾーンでの“今の時刻”」を返しますが、
戻ってくる値自体には「タイムゾーン情報」は含まれていません。
あくまで「時刻だけ」です。
時・分・秒を取り出す
LocalTime t = LocalTime.of(9, 30, 45);
int hour = t.getHour(); // 9
int minute = t.getMinute(); // 30
int second = t.getSecond(); // 45
System.out.println(hour + "時" + minute + "分" + second + "秒");
Javaここまでで、「LocalTime は“時計だけ”を扱うクラス」という感覚が少し掴めたはずです。
LocalTime の「不変性」と安心して扱える理由
LocalTime は一度作ったら中身が変わらない
LocalTime は LocalDate と同じく、不変(immutable)です。
LocalTime t1 = LocalTime.of(9, 0);
LocalTime t2 = t1.plusHours(1);
System.out.println(t1); // 09:00
System.out.println(t2); // 10:00
JavaplusHours(1) を呼んでも、t1 自体は変化せず、新しい LocalTime が返ってきます。
可変なクラス(たとえば java.util.Date)だと、
あるメソッドに渡したら、知らないうちに中身が書き換わっていた
別スレッドから書き換えられて、結果が不安定になった
という厄介な問題が起こりますが、LocalTime ではそれが起きません。
この「変わらない」という性質は、
時刻をたくさん扱う実務のコードでは本当に頼りになる特徴です。
時刻の加算・減算・比較(ここをしっかり押さえる)
時刻に足したり引いたりする
「30 分後」「1 時間前」を求めるのはとても簡単です。
LocalTime start = LocalTime.of(9, 0);
LocalTime after30Min = start.plusMinutes(30); // 09:30
LocalTime before1Hour = start.minusHours(1); // 08:00
System.out.println(after30Min);
System.out.println(before1Hour);
Java24 時間をまたいでも、自動的に 0〜23 時の範囲に収まるように調整されます。
LocalTime late = LocalTime.of(23, 30);
LocalTime after1Hour = late.plusHours(1); // 00:30(翌日の 0:30 という「時刻」)
System.out.println(after1Hour); // 00:30
Javaここで大事なのは、「日付はまったく関係ない」という点です。
「翌日」と聞くと日付を意識したくなりますが、LocalTime は「時計の針が一周しただけ」と考えます。
時刻同士の比較(isBefore, isAfter)
「この時刻は 9 時より後か?」などの判定は、次のように書けます。
LocalTime t1 = LocalTime.of(9, 0);
LocalTime t2 = LocalTime.of(10, 30);
boolean b1 = t1.isBefore(t2); // true
boolean b2 = t2.isAfter(t1); // true
boolean b3 = t1.equals(t2); // false
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
Javaメソッド名がそのまま意味を表しているので、
ビジネスロジック(営業時間かどうか、受付時間内かどうか)を、そのままコードに落としやすくなります。
実務でよくある「時間帯の判定」を LocalTime で書いてみる
例題:営業時間内かどうかを判定する
営業時間が「9:00 〜 18:00」の店があるとします。
今の時刻が営業時間内かどうかを判定したい場面は、よくあります。
import java.time.LocalTime;
public class BusinessHours {
public static void main(String[] args) {
LocalTime open = LocalTime.of(9, 0);
LocalTime close = LocalTime.of(18, 0);
LocalTime now = LocalTime.now();
boolean isOpen =
(now.equals(open) || now.isAfter(open)) &&
now.isBefore(close);
System.out.println("現在時刻: " + now);
System.out.println("営業中か?: " + isOpen);
}
}
Javaここでやっていることを日本語にすると、
開店時刻以上かどうか(open と同じか、それより後か)
かつ
閉店時刻より前かどうか
という条件チェックです。
LocalTime だけを使っているので、
日付やタイムゾーンの影響を受けず、「時計の時刻」だけを素直に比較できます。
例題:休憩時間(12:00〜13:00)を除外する
営業時間の中でも、12:00〜13:00 は休憩時間としましょう。
さっきの例に条件を足してみます。
LocalTime open = LocalTime.of(9, 0);
LocalTime close = LocalTime.of(18, 0);
LocalTime breakFrom = LocalTime.of(12, 0);
LocalTime breakTo = LocalTime.of(13, 0);
LocalTime now = LocalTime.now();
boolean inBusinessTime =
(now.equals(open) || now.isAfter(open)) &&
now.isBefore(close);
boolean inBreakTime =
(now.equals(breakFrom) || now.isAfter(breakFrom)) &&
now.isBefore(breakTo);
boolean canServe = inBusinessTime && !inBreakTime;
Javaこのように、時間帯の判定は LocalTime と比較メソッドの組み合わせでかなり読みやすく書けます。
文字列との相互変換:フォーマットとパース
LocalTime → 文字列(format)
時間を表示用の文字列にしたいときは、DateTimeFormatter を使います。
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class LocalTimeFormat {
public static void main(String[] args) {
LocalTime time = LocalTime.of(9, 5, 3);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
String s = time.format(fmt);
System.out.println(s); // 09:05:03
}
}
Javaポイントは、
DateTimeFormatter はスレッドセーフ
古い SimpleDateFormat のように「マルチスレッドで壊れる」心配がない
という点です。
文字列 → LocalTime(parse)
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class LocalTimeParse {
public static void main(String[] args) {
LocalTime t1 = LocalTime.parse("09:30"); // ISO形式 "HH:mm" はそのままOK
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("H時m分");
LocalTime t2 = LocalTime.parse("9時5分", fmt); // パターンを指定してパース
System.out.println(t1); // 09:30
System.out.println(t2); // 09:05
}
}
JavaWeb フォームの入力値や設定ファイルの「時刻文字列」をs -> LocalTime に変換する場面で、頻出のパターンです。
LocalTime と LocalDateTime / Date / Instant の関係を整理する
LocalDateTime との組み合わせ
LocalTime は「時刻だけ」、LocalDate は「日付だけ」です。
これを合わせたのが LocalDateTime です。
具体的には、こうやって合成できます。
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
LocalDate date = LocalDate.of(2025, 1, 10);
LocalTime time = LocalTime.of(9, 30);
LocalDateTime dateTime = LocalDateTime.of(date, time); // 2025-01-10T09:30
System.out.println(dateTime);
Javaあるいは、LocalDate に atTime したり、LocalTime に atDate したりもできます。
LocalDateTime dt1 = date.atTime(time);
LocalDateTime dt2 = time.atDate(date);
Java「日付だけ」と「時刻だけ」を分けて考えたい場面では、
入力段階では LocalDate と LocalTime、
内部での処理や DB 保存の前に LocalDateTime にまとめる、という設計もよく使われます。
Date / Instant とどう付き合うか
古い API や DB ドライバなどで java.util.Date が出てくる場合、LocalTime と単純に 1 対 1 変換することはできません。
Date や Instant は「日時(瞬間)」であり、
そこから「時刻だけ」を取り出すには「どのタイムゾーンか」という情報が必ず必要になるからです。
例えば、日本時間として解釈して時刻だけ抜きたい場合は、次のようになります。
import java.time.*;
import java.util.Date;
Date legacy = new Date(); // どこかから来たとする
Instant instant = legacy.toInstant();
ZoneId zone = ZoneId.of("Asia/Tokyo");
LocalTime time = instant.atZone(zone).toLocalTime();
System.out.println(time);
Java逆に、「ある日付と時刻を日本時間の Instant / Date にしたい」なら、こうです。
LocalDate date = LocalDate.of(2025, 1, 10);
LocalTime time = LocalTime.of(9, 0);
ZoneId zone = ZoneId.of("Asia/Tokyo");
LocalDateTime ldt = LocalDateTime.of(date, time);
Instant instant = ldt.atZone(zone).toInstant();
Date dateObj = Date.from(instant);
Javaここで意識しておきたいのは、
LocalTime は「タイムゾーンに縛られない純粋な時刻」
Instant / Date は「UTC 基準の瞬間」
という違いです。
まとめ:LocalTime を自分の中でこう位置づける
LocalTime を初心者向けにまとめると、こうなります。
タイムゾーンも日付も持たない、「時・分・秒だけ」のクラス。
不変なので、勝手に書き換えられたり、スレッド間で壊れたりしない。of, now, plusMinutes, isBefore などで、時刻計算や時間帯判定を直感的に書ける。DateTimeFormatter と組み合わせて、時刻文字列との相互変換がシンプルかつ安全にできる。
LocalDate と組み合わせて LocalDateTime にしたり、タイムゾーンを指定して Instant / Date に変換したりできる。
