🕰️ Java Date & Time API: Your Time Travel Guide!
The Big Picture
Imagine you have a magical calendar that can:
- Tell you today’s date and time ⏰
- Know what time it is anywhere in the world 🌍
- Calculate how long until your birthday 🎂
- Format dates in any way you want 📝
That’s exactly what Java’s Date & Time API does! It’s like having a super-smart watch that understands time everywhere.
🏠Local Date and Time Classes
What’s “Local”?
Think of “local” like your bedroom clock. It shows YOUR time, right where you are. It doesn’t care about time zones—it just shows the time on your wall.
LocalDate: Just the Day
LocalDate is like a calendar page. It knows the year, month, and day—but NO time.
// Today's date
LocalDate today = LocalDate.now();
// 2024-01-15
// A specific date
LocalDate birthday = LocalDate.of(2024, 6, 15);
// 2024-06-15
// What day is tomorrow?
LocalDate tomorrow = today.plusDays(1);
Real Life: When you write your birthday on a form, you just need the date—not the exact time you were born!
LocalTime: Just the Clock
LocalTime is like a clock without a calendar. Hours, minutes, seconds—but NO date.
// Current time
LocalTime now = LocalTime.now();
// 14:30:45
// Set an alarm
LocalTime alarm = LocalTime.of(7, 30);
// 07:30
// 2 hours later
LocalTime later = now.plusHours(2);
Real Life: When you set an alarm, you just say “7:30 AM”—you don’t say “7:30 AM on January 15th 2024”!
LocalDateTime: Date + Time Together
LocalDateTime is like a smart calendar that shows BOTH the date AND the time.
// Right now: date and time
LocalDateTime now = LocalDateTime.now();
// 2024-01-15T14:30:45
// A movie starts at...
LocalDateTime movieTime = LocalDateTime.of(
2024, 1, 20, // date
19, 30 // time: 7:30 PM
);
// Move to next week, same time
LocalDateTime nextWeek = now.plusWeeks(1);
Real Life: When you book a doctor’s appointment, you need BOTH the date AND the time!
graph TD A["LocalDate"] -->|Date Only| D["2024-01-15"] B["LocalTime"] -->|Time Only| E["14:30:45"] C["LocalDateTime"] -->|Date + Time| F["2024-01-15T14:30:45"]
🌍 Zoned Date and Time
The Problem with “Local”
Here’s a puzzle: If it’s 3 PM in New York, what time is it in Tokyo?
Your bedroom clock can’t answer that. But ZonedDateTime can!
ZonedDateTime: Time with a Passport
Think of ZonedDateTime as time that carries its passport—it knows WHERE it belongs.
// Your local time with zone
ZonedDateTime here = ZonedDateTime.now();
// 2024-01-15T14:30:45-05:00[America/New_York]
// Same moment in Tokyo
ZonedDateTime tokyo = here.withZoneSameInstant(
ZoneId.of("Asia/Tokyo")
);
// 2024-01-16T04:30:45+09:00[Asia/Tokyo]
// Create a specific zoned time
ZonedDateTime meeting = ZonedDateTime.of(
2024, 1, 20, 10, 0, 0, 0,
ZoneId.of("Europe/London")
);
ZoneId: The Passport Stamp
ZoneId is like a country stamp on a passport. It tells Java which timezone you mean.
// See all available zones
Set<String> zones = ZoneId.getAvailableZoneIds();
// "America/New_York", "Europe/Paris", "Asia/Tokyo"...
// Get a specific zone
ZoneId nyZone = ZoneId.of("America/New_York");
ZoneId tokyoZone = ZoneId.of("Asia/Tokyo");
// Your system's zone
ZoneId myZone = ZoneId.systemDefault();
ZoneOffset: Hours from Greenwich
ZoneOffset is simpler—just the hour difference from UTC.
// 5 hours behind UTC
ZoneOffset offset = ZoneOffset.of("-05:00");
// Create OffsetDateTime
OffsetDateTime odt = OffsetDateTime.now();
// 2024-01-15T14:30:45-05:00
graph TD A["LocalDateTime"] -->|Add Zone| B["ZonedDateTime"] B -->|Convert| C["Same Moment<br>Different Clock"] C -->|New York 3PM| D["Tokyo 5AM<br>Next Day!"]
Real Life: When you schedule a video call with friends in different countries, you need ZonedDateTime to make sure everyone shows up at the right time!
⏱️ Duration and Period
The Difference
Imagine measuring:
- How long a movie is → Duration (hours, minutes, seconds)
- How old you are → Period (years, months, days)
Duration: For Precise Time
Duration measures time in seconds and nanoseconds. Perfect for short, precise measurements.
// How long between two times?
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);
Duration workDay = Duration.between(start, end);
// PT8H30M (8 hours 30 minutes)
// Create specific durations
Duration twoHours = Duration.ofHours(2);
Duration ninetyMins = Duration.ofMinutes(90);
// Add duration to time
LocalTime breakTime = start.plus(Duration.ofHours(4));
// 13:00
Period: For Calendar Time
Period measures time in years, months, and days. Perfect for human-scale time.
// How long until Christmas?
LocalDate today = LocalDate.of(2024, 1, 15);
LocalDate christmas = LocalDate.of(2024, 12, 25);
Period untilXmas = Period.between(today, christmas);
// P11M10D (11 months, 10 days)
// Create specific periods
Period oneYear = Period.ofYears(1);
Period twoMonths = Period.ofMonths(2);
Period threeWeeks = Period.ofWeeks(3);
// Add period to date
LocalDate nextBirthday = today.plus(Period.ofYears(1));
Why Two Different Classes?
Think about it:
- “The meeting lasted 2 hours” → Duration ✓
- “I’ve been alive for 25 years” → Period ✓
graph TD A["Measuring Time"] --> B{What kind?} B -->|Precise:<br>hours/minutes/seconds| C["Duration"] B -->|Calendar:<br>years/months/days| D["Period"] C --> E["Movie length<br>Race time<br>Sleep hours"] D --> F["Age<br>Subscription<br>Vacation days"]
📝 Date Time Formatting
Making Dates Pretty
Computers like 2024-01-15. Humans prefer January 15, 2024 or 15/01/2024.
DateTimeFormatter is your translator!
Built-in Formatters
LocalDate date = LocalDate.of(2024, 1, 15);
LocalDateTime dateTime = LocalDateTime.now();
// ISO format (default)
String iso = date.format(
DateTimeFormatter.ISO_LOCAL_DATE
);
// "2024-01-15"
// Other built-in styles
String full = dateTime.format(
DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.FULL
)
);
// "Monday, January 15, 2024 at 2:30:45 PM EST"
Custom Patterns
Want YOUR own format? Use pattern letters!
DateTimeFormatter custom = DateTimeFormatter.ofPattern(
"dd/MM/yyyy"
);
String uk = date.format(custom);
// "15/01/2024"
DateTimeFormatter fancy = DateTimeFormatter.ofPattern(
"EEEE, MMMM d, yyyy 'at' h:mm a"
);
String pretty = dateTime.format(fancy);
// "Monday, January 15, 2024 at 2:30 PM"
Pattern Letter Cheat Sheet
| Letter | Meaning | Example |
|---|---|---|
y |
Year | 2024 |
M |
Month | 01 or January |
d |
Day | 15 |
E |
Day name | Mon or Monday |
H |
Hour (24h) | 14 |
h |
Hour (12h) | 2 |
m |
Minute | 30 |
s |
Second | 45 |
a |
AM/PM | PM |
Tip: More letters = longer output!
M→ 1MM→ 01MMM→ JanMMMM→ January
🔍 Date Time Parsing
From Text to Date
Parsing is the opposite of formatting. It turns text back into date objects.
// Parse ISO format (default)
LocalDate date = LocalDate.parse("2024-01-15");
LocalTime time = LocalTime.parse("14:30:45");
// Parse with custom format
DateTimeFormatter ukFormat = DateTimeFormatter.ofPattern(
"dd/MM/yyyy"
);
LocalDate ukDate = LocalDate.parse(
"15/01/2024",
ukFormat
);
// Parse date and time together
DateTimeFormatter full = DateTimeFormatter.ofPattern(
"yyyy-MM-dd HH:mm"
);
LocalDateTime meeting = LocalDateTime.parse(
"2024-01-20 10:30",
full
);
Handling Parse Errors
What if someone types garbage?
try {
LocalDate bad = LocalDate.parse("not-a-date");
} catch (DateTimeParseException e) {
System.out.println("Oops! That's not a valid date.");
}
Real Life: When users type dates into forms, you need to parse them—and handle mistakes gracefully!
graph LR A["String Text"] -->|parse| B["Date Object"] B -->|format| C["String Text"] A -.->|Invalid?| D["DateTimeParseException"]
🎯 Temporal Adjusters
Smart Date Navigation
Imagine asking your calendar:
- “What’s the next Monday?”
- “When’s the last day of this month?”
- “What’s the first Friday of next month?”
TemporalAdjusters answers these questions!
Built-in Adjusters
LocalDate today = LocalDate.of(2024, 1, 15); // Monday
// First/Last day of month
LocalDate firstDay = today.with(
TemporalAdjusters.firstDayOfMonth()
);
// 2024-01-01
LocalDate lastDay = today.with(
TemporalAdjusters.lastDayOfMonth()
);
// 2024-01-31
// Next/Previous day of week
LocalDate nextFri = today.with(
TemporalAdjusters.next(DayOfWeek.FRIDAY)
);
// 2024-01-19
LocalDate lastSun = today.with(
TemporalAdjusters.previous(DayOfWeek.SUNDAY)
);
// 2024-01-14
More Useful Adjusters
// First Monday of the month
LocalDate firstMon = today.with(
TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)
);
// 2024-01-01
// Third Thursday (like Thanksgiving!)
LocalDate thirdThu = LocalDate.of(2024, 11, 1).with(
TemporalAdjusters.dayOfWeekInMonth(
3, DayOfWeek.THURSDAY
)
);
// 2024-11-21
// Next or same (includes today if it matches)
LocalDate nextOrSameMon = today.with(
TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY)
);
// 2024-01-15 (today IS Monday!)
Complete Adjuster List
| Adjuster | What It Does |
|---|---|
firstDayOfMonth() |
First day of current month |
lastDayOfMonth() |
Last day of current month |
firstDayOfYear() |
First day of current year |
lastDayOfYear() |
Last day of current year |
firstDayOfNextMonth() |
First day of next month |
next(DayOfWeek) |
Next occurrence of day |
previous(DayOfWeek) |
Previous occurrence of day |
nextOrSame(DayOfWeek) |
This day or next occurrence |
previousOrSame(DayOfWeek) |
This day or previous occurrence |
firstInMonth(DayOfWeek) |
First specific day in month |
lastInMonth(DayOfWeek) |
Last specific day in month |
dayOfWeekInMonth(n, DayOfWeek) |
nth occurrence of day in month |
graph TD A["Today: Jan 15"] --> B["TemporalAdjusters"] B --> C["firstDayOfMonth<br>Jan 1"] B --> D["lastDayOfMonth<br>Jan 31"] B --> E["next Friday<br>Jan 19"] B --> F["previous Sunday<br>Jan 14"]
🎉 Putting It All Together
Here’s a real-world example combining everything:
// 1. Get current time in New York
ZonedDateTime nyNow = ZonedDateTime.now(
ZoneId.of("America/New_York")
);
// 2. Find next Monday
ZonedDateTime nextMeeting = nyNow.with(
TemporalAdjusters.next(DayOfWeek.MONDAY)
).withHour(10).withMinute(0);
// 3. Convert to Tokyo time
ZonedDateTime tokyoMeeting = nextMeeting.withZoneSameInstant(
ZoneId.of("Asia/Tokyo")
);
// 4. Format nicely
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(
"EEEE, MMM d 'at' h:mm a z"
);
System.out.println("NY: " + nextMeeting.format(fmt));
// NY: Monday, Jan 22 at 10:00 AM EST
System.out.println("Tokyo: " + tokyoMeeting.format(fmt));
// Tokyo: Tuesday, Jan 23 at 12:00 AM JST
🚀 Key Takeaways
- Local classes = Your bedroom clock (no timezone)
- Zoned classes = Clock with a passport (knows its location)
- Duration = Precise time (hours, minutes, seconds)
- Period = Calendar time (years, months, days)
- Formatter = Translator (Date ↔ String)
- Adjusters = Smart calendar navigation
You now have the power to master time in Java! 🎯
