REVISEALGOLEARN|PRACTICE|PROGRESS

Date & Time API

Legacy Date and Time

Understand legacy date classes: java.util.Date, Calendar, and SimpleDateFormat, along with their design flaws.

Interview: Focuses on legacy concurrency bugs (SimpleDateFormat race conditions) and explaining why these classes are obsolete.

Last Updated: June 13, 2026 • 10 min read

Prior to Java 8, date and time representation relied on classes like java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat. These classes suffered from severe design flaws, particularly thread-safety bugs.

Core Idea

Legacy date classes are mutable and non-thread-safe, leading to subtle concurrency bugs.

Why It Matters

Using SimpleDateFormat in multi-threaded environments can corrupt date values, causing data discrepancies.

Interview Lens

Tests explanation of why SimpleDateFormat is not thread-safe and how to handle legacy code migrations.

Legacy API Design Flaws

  • Mutability: java.util.Date is mutable. Calling setTime() modifies the value directly, making it dangerous to pass around without defensive copying.
  • Non-thread-safe Formatting: SimpleDateFormat maintains internal state during parsing. Sharing a static formatter across threads causes overlapping state updates and silent date corruptions.
  • Confusing Offsets: Month indices start at 0 (January is 0), but days start at 1. Years are offset by 1900.

Code Walkthrough

The following example demonstrates how a shared SimpleDateFormat can corrupt data under concurrent execution.

import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatBugDemo { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

public static void main(String[] args) { Runnable task = () -> { try { // Multiple threads executing this concurrently will corrupt internal state! Date d = sdf.parse("2026-06-13"); System.out.println("Parsed: " + sdf.format(d)); } catch (Exception e) { // Frequently throws NumberFormatException under race conditions } };

for (int i = 0; i < 5; i++) { new Thread(task).start(); } } }

Interview-Relevant Information

Q: How can you make SimpleDateFormat thread-safe without migrating to Java 8?
Answer: You can: 1. Instantiate a new SimpleDateFormat local variable inside each method call (adds GC overhead). 2. Synchronize access to the shared formatter instance. 3. Wrap it in a ThreadLocal so each thread has its own formatter instance.

Quick Checklist

Why is SimpleDateFormat not thread-safe? What are the month numbering rules in Calendar? If yes, you understand legacy date-time flaws.

Use Cases

Integrating with legacy databases using pre-Java 8 structures.

Refactoring older backend services to use thread-safe modern date types.

Common Mistakes

Declaring SimpleDateFormat as static and sharing it across threads without synchronization, leading to runtime failures.

Forgetting that Month indices are 0-based in Calendar, setting December to index 12 instead of 11.