Working with Date and Time in Java

Java provides multiple APIs for handling date and time, evolving significantly over versions to address design flaws and usability issues.

Legacy java.util.Date

The java.util.Date class represents a specific instant in time with millisecond precision. Despite its name, it encapsulates both date and time.

Date now = new Date(); // Current timestamp
// Deprecated constructor: year is offset from 1900, month is 0-based
Date legacyDate = new Date(95, 11, 17); // December 17, 1995

Accessing components uses deprecated methods:

int year = now.getYear() + 1900;   // Add 1900 to get actual year
int month = now.getMonth() + 1;    // Add 1 to convert from 0-based index
int day = now.getDate();           // Day of month (1–31)
int hour = now.getHours();         // Hour in 24-hour format

Similarly, mutation methods like setYear() and setMonth() are deprecated due to poor design and lack of time zone awareness.

Comparison is supported via:

boolean earlier = now.before(legacyDate);
boolean later = now.after(legacyDate);
boolean same = now.equals(legacyDate);

java.util.Calendar

Calendar is an abstract class offering more flexible date manipulation than Date. It’s typically instantiated via getInstance():

Calendar cal = Calendar.getInstance(); // Uses default time zone and locale

Field access uses constants:

int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1; // Still 0-based
int day = cal.get(Calendar.DAY_OF_MONTH);

Setting values:

cal.set(1995, Calendar.DECEMBER, 17); // Month constant avoids off-by-one errors

Arithmetic operations:

cal.add(Calendar.DAY_OF_MONTH, 1);  // Add one day
cal.add(Calendar.YEAR, -1);         // Subtract one year

Note: Calendar is mutable and not thread-safe. Each thread should use its own instance.

Modern java.time API (Java 8+)

The java.time package inrtoduces immutable, thread-safe, and intuitive classes:

LocalDate dateOnly = LocalDate.now();
LocalTime timeOnly = LocalTime.now();
LocalDateTime full = LocalDateTime.now();

Formatting uses DateTimeFormatter:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String output = full.format(fmt);

Parsing is equally straightforward:

LocalDateTime parsed = LocalDateTime.parse("2024-08-05T15:30:00");
// Or with custom format
LocalDateTime customParsed = LocalDateTime.parse("2024-08-05 15:30:00", fmt);

This API avoids the pitfalls of earlier classes by separating date-only, time-only, and combined representations, and by being inherently immutable.

SimpleDateFormat (Legacy Formatting)

Part of java.text, SimpleDateFormat handles parsing and formatting for Date objects:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(new Date());

try {
    Date parsed = sdf.parse("2024-08-05 15:30:00");
} catch (ParseException e) {
    e.printStackTrace();
}

Common pattern symbols include:

  • yyyy – four-digit year
  • MM – two-digit month
  • dd – two-digit day
  • HH – hour (24-hour)
  • mm – minutes
  • ss – seconds

However, SimpleDateFormat is not thread-safe and should not be shared across threads without synchronization.

Given its limitations, the java.time API is strongly preferred for new code.

Tags: java Date and Time java.time Calendar SimpleDateFormat

Posted on Mon, 11 May 2026 11:01:12 +0000 by ahoo