Start Learning
Javaneer
Back to stage
Stage 3·Intermediate Java

Date/Time & I/O

The java.time API, formatting, streams and readers, buffering, and serialization.

18 min readIntermediate
On this page

Two everyday essentials round out the intermediate toolkit: working with dates and times using the modern java.time API, and understanding Java's I/O streams - the pipes through which data flows.

The modern java.time API

Older date classes (Date, Calendar) were confusing and error-prone. Modern Java (8+) replaced them with java.time - clear, immutable, and pleasant.

The core types:

import java.time.*;

LocalDate  date  = LocalDate.now();          // 2026-07-19 (date only)
LocalTime  time  = LocalTime.now();          // 14:30:00   (time only)
LocalDateTime dt = LocalDateTime.now();      // both
ZonedDateTime zoned = ZonedDateTime.now();   // with time zone
LocalDate vs. ZonedDateTime

A LocalDate is like "December 25th" written on a birthday card - a date with no time zone attached. A ZonedDateTime is like "the exact moment a flight departs from Tokyo" - a precise instant that depends on where you are. Use the simplest type that captures what you actually mean.

Creating and manipulating dates

Everything is immutable - operations return new objects:

LocalDate today = LocalDate.of(2026, 7, 19);
LocalDate nextWeek = today.plusWeeks(1);      // 2026-07-26
LocalDate lastMonth = today.minusMonths(1);   // 2026-06-19

System.out.println(today.getDayOfWeek());     // SUNDAY
System.out.println(today.isBefore(nextWeek)); // true

Durations and periods

  • Duration measures time-based amounts (hours, minutes, seconds).
  • Period measures date-based amounts (years, months, days).
Duration meeting = Duration.ofMinutes(90);
System.out.println(meeting.toHours());        // 1

Period age = Period.between(
        LocalDate.of(2000, 1, 1), LocalDate.now());
System.out.println(age.getYears() + " years");

Formatting and parsing

Convert between dates and text with DateTimeFormatter:

LocalDate date = LocalDate.of(2026, 7, 19);

String text = date.format(DateTimeFormatter.ofPattern("dd MMM yyyy"));
System.out.println(text);                     // 19 Jul 2026

LocalDate parsed = LocalDate.parse("2026-12-25");  // ISO format

java.time is immutable and thread-safe

Because these types never change after creation, you can share them freely across threads without worry - a big improvement over the old, mutable Date. Always reach for java.time in modern code.

I/O streams: pipes for data

Beyond files, Java models all input and output as streams - sequences of data flowing from a source to a destination.

Streams are like water pipes

Data flows through a stream like water through a pipe: from a source (a file, the keyboard, a network socket) to a destination (a file, the screen, another computer). You can attach fittings - buffers to speed flow, readers to interpret the water as text.

Two families:

  • Byte streams (InputStream/OutputStream) - raw bytes, for any data.
  • Character streams (Reader/Writer) - text, with character encoding.
// Buffered reading of text, line by line
try (var reader = Files.newBufferedReader(Path.of("data.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

Buffering: why it matters

Reading one byte at a time from disk is painfully slow. A buffer reads a big chunk into memory at once, so your code gets data fast. Always wrap raw streams in buffered versions (or use the Files.newBufferedReader helpers, which do it for you).

Serialization: handle with care

Java can turn objects into bytes (serialization) to save or send them. It's convenient but has security and versioning pitfalls. For data you exchange with other systems, prefer a well-defined format like JSON (via a library such as Jackson) over Java's built-in serialization.

Quick check

Why is java.time preferred over the older Date and Calendar classes?

Key takeaways

  • java.time provides LocalDate, LocalTime, LocalDateTime, and ZonedDateTime - immutable and thread-safe.
  • Date math returns new objects (plusDays, minusMonths); Duration measures time, Period measures dates.
  • DateTimeFormatter converts between dates and text.
  • Java models I/O as streams: byte streams for raw data, character streams (Reader/Writer) for text.
  • Always buffer streams for performance; prefer JSON over Java serialization for data exchange.

Next, we connect to the outside world over the network - sockets, HTTP, and calling a real REST API.