Java LocalTime
Table of Contents + β
In the last lesson you learned about Java LocalDate, which holds a date with no time attached. But many things are about the clock, not the calendar, like a shop that opens at 9 or an alarm at 6:30. For exactly this, Java gives you LocalTime, which lives in the java.time package.
π€ What is LocalTime?
A LocalTime is a time of day on its own. Think of a wall clock with no calendar next to it.
- Holds hour, minute, second, and nanosecond. Nothing else.
- No date and no time zone, so
14:30is just half past two in the afternoon. - It does not know if that is today, tomorrow, or in Tokyo.
- Reach for it for times that repeat every day: opening hours, a daily reminder, a bus that leaves at the same minute.
π οΈ Creating a LocalTime
There are two main ways to make one. To get the time right now from the system clock, use LocalTime.now().
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime rightNow = LocalTime.now(); System.out.println(rightNow); }}This prints whatever time it is on your machine when you run it, down to the nanosecond. Your output will look something like the line below, but with your own time.
Output
10:15:42.123456To build a specific time instead of the current one, use LocalTime.of(). You pass the hour and minute, and Java hands back that exact time.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime opening = LocalTime.of(9, 0); LocalTime classTime = LocalTime.of(14, 30); LocalTime precise = LocalTime.of(14, 30, 15);
System.out.println(opening); System.out.println(classTime); System.out.println(precise); }}A few things to notice:
- The hour uses the 24-hour clock, so
14means 2 in the afternoon. ofcomes in different sizes: hour and minute, hour-minute-second, or one that takes nanoseconds too.- Pick the size that matches how precise you need to be.
Output
09:0014:3014:30:15The hour must be 0 to 23
The hour in LocalTime.of is on the 24-hour clock, so it must be between 0 and 23. Passing 24 or 25 does not roll over to the next day. It throws a DateTimeException instead. Minutes and seconds must be 0 to 59.
π Reading the parts of a time
Once you have a LocalTime, you often want just one piece of it. Java gives you a simple getter for each part. This example pulls every part out of one time.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime t = LocalTime.of(14, 30, 15);
System.out.println("Hour: " + t.getHour()); System.out.println("Minute: " + t.getMinute()); System.out.println("Second: " + t.getSecond()); System.out.println("Nano: " + t.getNano()); }}- Each getter returns a plain
int. SogetHour()gives14,getMinute()gives30. - We did not set a nanosecond, so
getNano()is0. - Handy for decisions based on the time, like βif the hour is before 12, say good morningβ.
Output
Hour: 14Minute: 30Second: 15Nano: 0β Adding and subtracting time
Here is the most important rule of the whole lesson. A LocalTime is immutable, meaning once created it can never change. So plusHours does not edit your time. It builds a brand new LocalTime and hands it back, and the original stays exactly as it was. This example adds and subtracts, and proves the original never moves.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime start = LocalTime.of(9, 0);
LocalTime later = start.plusHours(2); LocalTime earlier = start.minusMinutes(15);
System.out.println("Original: " + start); System.out.println("Plus 2 hours: " + later); System.out.println("Minus 15 minutes: " + earlier); }}Look at the last three lines together:
- The original
startstill prints09:00, even afterplusHoursandminusMinutes. - Those methods did not touch
start. Each returned a new time, caught inlaterandearlier. - Forget to catch the returned value and it looks like nothing happened. The number one mistake here.
Output
Original: 09:00Plus 2 hours: 11:00Minus 15 minutes: 08:45There is a matching method for every part: plusHours/minusHours, plusMinutes/minusMinutes, plusSeconds/minusSeconds. Because each returns a new LocalTime, you can chain them to read left to right.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime t = LocalTime.of(10, 0) .plusHours(1) .plusMinutes(30);
System.out.println(t); }}- Each step works on the result of the step before it:
10:00becomes11:00, then11:30. - The time wraps around the clock by itself. Push past midnight and it rolls over to the early morning, with no error.
Output
11:30π° Comparing two times
To check which of two times comes first, use isBefore and isAfter. Both return a plain true or false. To check if two times are exactly the same, use equals. This example compares an opening time with the current moment.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { LocalTime opening = LocalTime.of(9, 0); LocalTime closing = LocalTime.of(17, 0); LocalTime now = LocalTime.of(14, 30);
System.out.println(now.isAfter(opening)); System.out.println(now.isBefore(closing)); System.out.println(opening.equals(LocalTime.of(9, 0))); }}Reading the results:
isAfterreturnstruebecause 14:30 comes after 9:00.isBeforereturnstruebecause 14:30 comes before 17:00.equalsreturnstruebecause both 9:00 times hold the same value.- Together, the first two checks ask βis the shop open right now?β.
Output
truetruetrueπ The built-in constants
LocalTime ships with a few constants, fixed values you use directly off the class name, so you do not build common times by hand. This example prints all three.
import java.time.LocalTime;
public class Main { public static void main(String[] args) { System.out.println("MIN: " + LocalTime.MIN); System.out.println("MAX: " + LocalTime.MAX); System.out.println("NOON: " + LocalTime.NOON); }}LocalTime.MINis the start of the day,00:00, midnight.LocalTime.MAXis one nanosecond before midnight, the last instant before the next day.LocalTime.NOONis12:00, the middle of the day.- Useful as boundaries, like βeverything between MIN and NOON to get the morningβ.
Output
MIN: 00:00MAX: 23:59:59.999999999NOON: 12:00β±οΈ How long between two times
Often you want the gap between two times. How long until the bus? How long is the meeting? For this you use Duration.between, which measures the length from one moment to another. This example finds the gap between a start and an end.
import java.time.LocalTime;import java.time.Duration;
public class Main { public static void main(String[] args) { LocalTime start = LocalTime.of(9, 0); LocalTime end = LocalTime.of(11, 30);
Duration gap = Duration.between(start, end);
System.out.println("Hours: " + gap.toHours()); System.out.println("Total minutes: " + gap.toMinutes()); }}Duration.between(start, end)returns aDurationholding the whole length, here two and a half hours.toHours()gives the whole hours,2.toMinutes()gives the total minutes,150.toHoursdrops the leftover 30 minutes because it only counts complete hours.- For the full picture, ask for total minutes or total seconds.
Output
Hours: 2Total minutes: 150π¨ Formatting a time for people
The default printout like 14:30 is fine for code, but people often want a friendlier look, like 02:30 PM. For this you use a DateTimeFormatter, a recipe that says how the time should look. This example shows the same time in two styles.
import java.time.LocalTime;import java.time.format.DateTimeFormatter;
public class Main { public static void main(String[] args) { LocalTime t = LocalTime.of(14, 30);
DateTimeFormatter f24 = DateTimeFormatter.ofPattern("HH:mm"); DateTimeFormatter f12 = DateTimeFormatter.ofPattern("hh:mm a");
System.out.println(t.format(f24)); System.out.println(t.format(f12)); }}The pattern string is where the magic happens:
- Capital
HHmeans the hour on the 24-hour clock. Smallhhmeans the 12-hour clock. mmis the minute.aadds theAMorPMmarker.- So the first format prints
14:30, the second prints02:30 PM. - The case of the letters matters a lot. More in the mistakes section.
Output
14:3002:30 PMπ₯ Parsing text into a time
Going the other way, you often read a time from a file or a form as plain text and need to turn it into a real LocalTime. That is parsing, and you use LocalTime.parse. This example reads two text strings into times.
import java.time.LocalTime;import java.time.format.DateTimeFormatter;
public class Main { public static void main(String[] args) { LocalTime t1 = LocalTime.parse("08:45");
DateTimeFormatter f = DateTimeFormatter.ofPattern("hh:mm a"); LocalTime t2 = LocalTime.parse("02:30 PM", f);
System.out.println(t1); System.out.println(t2.plusHours(1)); }}- The first parse takes plain
08:45with no formatter, the standard shapeLocalTimealready understands. - The second is 12-hour style with a
PMmarker, so we handparsethe matching formatter to read it. - Once parsed,
t2is a realLocalTime, so we can do time math, like adding an hour to get15:30.
Output
08:4515:30β οΈ Common Mistakes
A handful of LocalTime slip-ups catch nearly everyone.
Treating LocalTime as if it changes. The immutability trap. Plus and minus methods return a new time, and people forget to keep it.
LocalTime t = LocalTime.of(9, 0);
t.plusHours(2); // β result thrown away, t is still 09:00t = t.plusHours(2); // β
keep the returned value, now t is 11:00Mixing up the 24-hour and 12-hour clock. Two in the afternoon is 14, not 2, on the 24-hour clock that of uses.
LocalTime afternoon = LocalTime.of(2, 30); // β this is 2:30 in the morningLocalTime afternoon2 = LocalTime.of(14, 30); // β
14 is 2:30 in the afternoonUsing the wrong case in the format pattern. Capital HH is the 24-hour clock, small hh is the 12-hour clock. Swapping them gives the wrong look.
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("hh:mm"); // β 14:30 prints as 02:30, no AM/PMDateTimeFormatter f2 = DateTimeFormatter.ofPattern("HH:mm"); // β
14:30 prints as 14:30Passing an hour above 23. There is no hour 24. To move into the next day, add hours and let it wrap, do not pass 24.
LocalTime t1 = LocalTime.of(24, 0); // β DateTimeException, no such hourLocalTime t2 = LocalTime.of(0, 0); // β
midnight is 0, not 24β Best Practices
Good habits that keep your time code clean and correct.
- Always catch the returned value. Since
LocalTimenever changes in place, assign the result, liket = t.plusHours(1);. If you do not, nothing seems to happen. - Use the 24-hour clock when you build a time.
LocalTime.of(14, 30)is clear and leaves no doubt about morning or afternoon. - Reach for the constants. Use
LocalTime.MIN,LocalTime.NOON, andLocalTime.MAXas clean boundaries instead of building those values yourself. - Compare with isBefore and isAfter. They read like plain English and make βis it open right now?β checks easy to follow.
- Use Duration.between for gaps. It is the right tool for the length between two times, and
toMinutesortoSecondsgive you the full amount. - Match your formatter to your text when parsing. If the text is in 12-hour style with AM or PM, parse it with a matching
DateTimeFormatter.
π§© What Youβve Learned
Nicely done. You can now work with the clock side of time in Java.
- β
LocalTimeholds a time of day, hour, minute, second, and nano, with no date and no zone. - β
Create one with
LocalTime.now()for the current time, orLocalTime.of(14, 30)for an exact time on the 24-hour clock. - β
Read parts with
getHour(),getMinute(), andgetSecond(), each returning a plainint. - β
LocalTimeis immutable, soplusHoursandminusMinutesreturn a new time and you must catch it. - β
Compare with
isBeforeandisAfter, and use the constantsMIN,MAX, andNOONfor boundaries. - β
Measure a gap with
Duration.between, and useDateTimeFormatterto format and parse times.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does LocalTime.of(14, 30) represent?
Why: The hour uses the 24-hour clock, so 14 means 2 in the afternoon, giving 14:30 or 2:30 PM.
- 2
After LocalTime t = LocalTime.of(9, 0); t.plusHours(2); what is t?
Why: LocalTime is immutable. plusHours returns a new time, but the result was thrown away, so t is still 09:00.
- 3
What does Duration.between(start, end).toMinutes() give for 9:00 to 11:30?
Why: Two and a half hours is 150 total minutes, which is what toMinutes returns.
- 4
In a DateTimeFormatter pattern, what does capital HH mean?
Why: Capital HH is the hour on the 24-hour clock; small hh is the 12-hour clock.
π Whatβs Next?
You can handle a date on its own, and now a time on its own. The natural next step is to join them, so you can say βthis exact moment, on this exact dayβ. That is what LocalDateTime is for. Letβs put the two halves together.