---
description: Java provides a Date class under the java.util package, The package provides several methods to play around with the date
title: Java Date and Time
image: https://www.guru99.com/images/java-date-and-time.png
---

[Skip to content](#main)

**⚡ Smart Summary**

Java Date and Time handling combines the legacy java.util.Date and SimpleDateFormat classes with the modern java.time API introduced in Java 8, giving developers immutable, thread-safe types for accurate calendar work.

- 🕒 **Legacy Date:** The java.util.Date class stores an instant in milliseconds and prints a default string through toString.
- 🔤 **Pattern Letters:** SimpleDateFormat uses letters such as yyyy, MM, dd, HH, mm, ss, and zzz to define custom output formats.
- ⚖️ **Comparison:** The compareTo method returns a negative, zero, or positive integer to order two Date instances chronologically.
- 🆕 **Modern API:** LocalDate, LocalDateTime, ZonedDateTime, and Instant in java.time replace Date and Calendar with immutable objects.
- 🧵 **Thread Safety:** DateTimeFormatter is immutable and safe to share, while SimpleDateFormat needs synchronization or a ThreadLocal wrapper.
- 🔁 **Interoperability:** Convert between the old and new APIs using Date.toInstant, Date.from, and Calendar.toInstant helpers.

Read More

![Java Date and Time](https://www.guru99.com/images/java-date-and-time.png)

Handling dates and times in Java is a routine part of building scheduling logic, log timestamps, reports, and audit trails. Before writing any code, it helps to know the parameters that make up a date:

- The **year** (in two or four digits).
- The **month** (as two digits, as the first three letters of the month, or as the full month name).
- The **date** (the actual day-of-month number).
- The **day** (the day name at the given date, such as Sun, Mon, Tue).

Java exposes many other parameters that describe a moment on the timeline, including era, week-in-year, time zone, and offset. The sections below cover each of them with runnable examples.

[![How to use Date in Java]()](https://www.guru99.com/images/uploads/2012/12/java21.jpg)

## Display Date in Java

Java provides a `Date` class in the `java.util` package. The class stores a specific instant in time to millisecond precision and offers helper methods to print, compare, and format that instant. To get the current date and time, instantiate the class with its default constructor:

```
import java.util.Date;

class Date_Ex1 {
    public static void main(String args[]) {
        // Instantiate a Date object by invoking its constructor
        Date objDate = new Date();
        // Display the Date and Time using toString()
        System.out.println(objDate.toString());
    }
}
```

**Output:**

```
Wed Nov 29 06:36:22 UTC 2017
```

The example prints the date in the default toString format. To display the same instant in a different pattern, you first need to understand the formatting letters that Java uses.

## SimpleDateFormat: Parse and Format Dates

The `SimpleDateFormat` class in `java.text` converts a `Date` object into a formatted string and parses a formatted string back into a `Date`. It uses pattern letters that map to a date or time component. The table below lists every supported letter:

| Letter | Date or Time Component | Example |
| --- | --- | --- |
| G | Era designator | AD |
| y | Year | 2026 |
| M | Month in year | July or Jul or 07 |
| w | Week in year | 27 |
| W | Week in month | 2 |
| D | Day in year | 189 |
| d | Day in month | 10 |
| F | Day of week in month | 2 |
| E | Day name in week | Tuesday or Tue |
| u | Day number of week (1 = Monday, 7 = Sunday) | 1 |
| a | AM or PM marker | PM |
| H | Hour in day (0-23) | 0 |
| k | Hour in day (1-24) | 24 |
| K | Hour in AM or PM (0-11) | 0 |
| h | Hour in AM or PM (1-12) | 12 |
| m | Minute in hour | 30 |
| s | Second in minute | 55 |
| S | Millisecond | 978 |
| z | Time zone (name) | Pacific Standard Time; PST; GMT-08:00 |
| Z | Time zone (RFC 822 offset) | -0800 |
| X | Time zone (ISO 8601 offset) | -08 or -0800 or -08:00 |

You do not need to remember the whole table. Refer to it whenever you build a new pattern.

## How to Use SimpleDateFormat

`SimpleDateFormat` is a subclass of `DateFormat` that lets you format and parse dates using the pattern letters above. Combine the letters to describe the exact string you want to produce or read.

For example:

1. Date format required: **2012.10.23 20:20:45 PST**. The appropriate format pattern is `yyyy.MM.dd HH:mm:ss zzz`.
2. Date format required: **09:30:00 AM 23-May-2012**. The appropriate format pattern is `hh:mm:ss a dd-MMM-yyyy`.

**Tip:** Watch letter case. Uppercase `M` is month, lowercase `m` is minute. Uppercase `H` is a 24-hour clock, lowercase `h` is a 12-hour clock. Mixing them up produces silently wrong output.

The program below prints the current date twice, once in default format and once through a SimpleDateFormat pattern:

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

class TestDates_Format {
    public static void main(String args[]) {
        // Current system date and time is assigned to objDate
        Date objDate = new Date();
        System.out.println(objDate);

        // Build the target pattern and format the date
        String strDateFormat = "hh:mm:ss a dd-MMM-yyyy";
        SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat);
        System.out.println(objSDF.format(objDate));
    }
}
```

**Output:**

```
Wed Nov 29 06:31:41 UTC 2017
06:31:41 AM 29-Nov-2017
```

## Compare Dates Example

[![Compare Dates Example]()](https://www.guru99.com/images/uploads/2012/12/java12.jpg)

The most reliable way to order two `Date` objects is the `compareTo()` method. It returns a negative integer when the caller is earlier, zero when both instants are equal, and a positive integer when the caller is later. The snippet below parses two date strings and prints their relative order:

**Don't Miss:**

- [Arrays in Java](https://www.guru99.com/java-arrays.html)
- [Spring Tutorial: What is Spring Framework & How to Install?](https://www.guru99.com/spring-tutorial.html)
- [Difference Between Abstract Class and Interface in Java](https://www.guru99.com/interface-vs-abstract-class-java.html)
- [Top 25 JMS (Java Message Service) Interview Questions (2026)](https://www.guru99.com/java-message-service-interview-questions.html)

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

class TestDates_Compare {
    public static void main(String args[]) throws ParseException {

        SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy");
        Date dt_1 = objSDF.parse("20-08-1981");
        Date dt_2 = objSDF.parse("12-10-2012");

        System.out.println("Date1 : " + objSDF.format(dt_1));
        System.out.println("Date2 : " + objSDF.format(dt_2));

        // compareTo returns > 0 when dt_1 is after dt_2
        if (dt_1.compareTo(dt_2) > 0) {
            System.out.println("Date 1 occurs after Date 2");
        }
        // compareTo returns < 0 when dt_1 is before dt_2
        else if (dt_1.compareTo(dt_2) < 0) {
            System.out.println("Date 1 occurs before Date 2");
        }
        // compareTo returns 0 when both dates are equal
        else {
            System.out.println("Both are the same date");
        }
    }
}
```

**Output:**

```
Date1 : 20-08-1981
Date2 : 12-10-2012
Date 1 occurs before Date 2
```

**Note:** The original code used the pattern `dd-mm-yyyy`. The lowercase `mm` letter is minute, not month, so the parser silently produced the wrong month value. The fix above uses uppercase `MM` for month, which is the correct pattern letter.

## Java 8 Modern Date and Time API (java.time)

Java 8 introduced the `java.time` package, a redesigned API inspired by the Joda-Time library. The new classes are immutable, thread-safe, and separate the human calendar from the machine timeline. The most common types are:

- `LocalDate` for a date without a time or zone (for example, a birthday).
- `LocalTime` for a wall-clock time without a date or zone.
- `LocalDateTime` for a date and time without a zone.
- `ZonedDateTime` for a date and time with a specific time zone.
- `OffsetDateTime` for a date and time with a UTC offset but no named zone.
- `Instant` for a machine timestamp measured from the UNIX epoch.
- `Duration` and `Period` for time-based and date-based amounts.

The example below prints the current date, time, timestamp, and time zone using the modern API:

```
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.time.ZoneId;

class ModernDateDemo {
    public static void main(String args[]) {
        LocalDate today = LocalDate.now();
        LocalDateTime now = LocalDateTime.now();
        ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        Instant epoch = Instant.now();

        System.out.println("LocalDate     : " + today);
        System.out.println("LocalDateTime : " + now);
        System.out.println("ZonedDateTime : " + zoned);
        System.out.println("Instant       : " + epoch);
    }
}
```

Each type has factory methods (`now`, `of`, `parse`) and immutable operations (`plusDays`, `minusHours`, `withYear`) that return a fresh value instead of mutating the original object.

## DateTimeFormatter: Format Dates in Modern Java

`DateTimeFormatter` in `java.time.format` replaces `SimpleDateFormat`. It uses the same style of pattern letters, is immutable, and is safe to share across threads without extra synchronization. The class also exposes ready-made constants such as `ISO_LOCAL_DATE` and `ISO_ZONED_DATE_TIME` for standard formats.

```
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class FormatterDemo {
    public static void main(String args[]) {
        LocalDateTime now = LocalDateTime.now();

        DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy");

        System.out.println(now.format(iso));
        System.out.println(now.format(human));

        LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso);
        System.out.println("Parsed back : " + parsed);
    }
}
```

To compare two dates in the modern API, call `isBefore`, `isAfter`, or `isEqual`. These methods read more clearly than `compareTo` and work with every `java.time` class.

## Thread Safety and Best Practices for Java Date and Time

Both `java.util.Date` and `SimpleDateFormat` predate modern concurrent Java, and each has known pitfalls. Follow the practices below to keep date handling correct in production code:

- **Prefer java.time over Date and Calendar.** The new types are immutable and thread-safe, and they model the domain more accurately (dates without times, times without zones, and so on).
- **Do not share a SimpleDateFormat across threads.** The class stores internal parse state and is not thread-safe. Wrap it in a `ThreadLocal`, synchronize on the instance, or switch to `DateTimeFormatter`.
- **Always specify a Locale.** Month and day names change with the JVM default locale, which makes patterns like `MMM` and `EEE` non-portable. Pass a locale explicitly (for example, `Locale.ENGLISH`).
- **Be explicit about time zones.** `LocalDateTime` has no zone, so convert to `ZonedDateTime` or `Instant` whenever the exact moment matters, especially for logs, database columns, and network payloads.
- **Convert between the two APIs carefully.** Use `date.toInstant()`, `Date.from(instant)`, and `calendar.toInstant().atZone(zone)` at the boundary between legacy code and modern code.
- **Store timestamps in UTC.** Persist and transmit dates as UTC (an `Instant` or an ISO 8601 string) and convert to the user zone only when displaying.

## FAQs

🕒 How do I get the current date and time in Java?

Call LocalDateTime.now() from the java.time package for a date and time in the system zone, or LocalDate.now() for a date only. On older Java, use new java.util.Date() to get the current instant.

🆚 What is the difference between java.util.Date and java.time.LocalDate?

java.util.Date represents an instant in milliseconds since the epoch and is mutable. LocalDate models a calendar date without a time or zone, is immutable and thread-safe, and offers clearer methods such as plusDays and isBefore.

🧵 Is SimpleDateFormat thread-safe?

No. SimpleDateFormat keeps mutable parse state and produces wrong results when shared across threads. Wrap it in a ThreadLocal, synchronize on the instance, or switch to DateTimeFormatter, which is immutable and safe.

🔤 What pattern do I pass to SimpleDateFormat for yyyy-MM-dd?

Pass the exact string “yyyy-MM-dd”. Uppercase MM is month, lowercase mm is minute. For a full date and time, use “yyyy-MM-dd HH:mm:ss”. Always specify a Locale so month names stay reproducible.

⚖️ How do I compare two dates in Java?

With legacy Date, use compareTo which returns a negative, zero, or positive int. With java.time, call isBefore, isAfter, or isEqual on a LocalDate or Instant. Both approaches respect chronological order.

🔁 How do I convert a Date to LocalDateTime?

Call date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). To go back, use Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Pick the zone explicitly whenever the exact moment matters.

🤖 How does AI help parse date strings in unknown formats?

AI models trained on log and document corpora infer the likely pattern from sample strings and return a matching DateTimeFormatter pattern. Machine learning classifiers also flag ambiguous fields such as month-day versus day-month order.

🛠️ Can GitHub Copilot generate Java date-formatting code?

Yes. GitHub Copilot suggests DateTimeFormatter patterns, ZonedDateTime conversions, and JUnit tests for locale-sensitive output. Review each suggestion for the correct pattern letters, Locale, and time zone before committing.

#### Summarize this post with:

ChatGPTPerplexityGrokGoogle AI

**Stay Updated on AI** **Get Weekly AI Skills, Trends, Actionable Advice.**

##### Sign up for the newsletter

Subscribe for Free

You have successfully subscribed.  
Please check your inbox.

![AI-Newsletter]() Chosen by over **350,000+** professionals

[Scroll to top](#wrapper)

×

Search for:

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.guru99.com/#organization","name":"Guru99","sameAs":["https://www.facebook.com/Guru99Official","https://twitter.com/guru99com"],"logo":{"@type":"ImageObject","@id":"https://www.guru99.com/#logo","url":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","contentUrl":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","caption":"Guru99","inLanguage":"en-US"}},{"@type":"WebSite","@id":"https://www.guru99.com/#website","url":"https://www.guru99.com","name":"Guru99","publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://www.guru99.com/images/java-date-and-time.png","url":"https://www.guru99.com/images/java-date-and-time.png","width":"700","height":"250","caption":"Java Date and Time","inLanguage":"en-US"},{"@type":"BreadcrumbList","@id":"https://www.guru99.com/java-date.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://www.guru99.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://www.guru99.com/java-tutorials","name":"Java Tutorials"}},{"@type":"ListItem","position":"3","item":{"@id":"https://www.guru99.com/java-date.html","name":"Java Date and Time"}}]},{"@type":"WebPage","@id":"https://www.guru99.com/java-date.html#webpage","url":"https://www.guru99.com/java-date.html","name":"Java Date and Time","dateModified":"2026-10-01T12:34:22+05:30","isPartOf":{"@id":"https://www.guru99.com/#website"},"primaryImageOfPage":{"@id":"https://www.guru99.com/images/java-date-and-time.png"},"inLanguage":"en-US","breadcrumb":{"@id":"https://www.guru99.com/java-date.html#breadcrumb"}},{"@type":"Person","@id":"https://www.guru99.com/author/editorial","name":"Editorial Team","url":"https://www.guru99.com/author/editorial","image":{"@type":"ImageObject","@id":"https://www.guru99.com/images/favicon-new-logo.png","url":"https://www.guru99.com/images/favicon-new-logo.png","caption":"Editorial Team","inLanguage":"en-US"},"sameAs":["https://www.guru99.com/editorial-team"],"worksFor":{"@id":"https://www.guru99.com/#organization"}},{"articleSection":"Java Tutorials","headline":"Java Date and Time","description":"Java provides a Date class under the java.util package, The package provides several methods to play around with the date","keywords":"java","speakable":{"@type":"SpeakableSpecification","cssSelector":[".entry-title",".summary"]},"@type":"Article","author":{"@id":"https://www.guru99.com/author/editorial","name":"Editorial Team"},"dateModified":"2026-10-01T12:34:22+05:30","image":{"@id":"https://www.guru99.com/images/java-date-and-time.png"},"copyrightYear":"2026","name":"Java Date and Time","subjectOf":[{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"How do I get the current date and time in Java?","acceptedAnswer":{"@type":"Answer","text":"Call LocalDateTime.now() from the java.time package for a date and time in the system zone, or LocalDate.now() for a date only. On older Java, use new java.util.Date() to get the current instant."}},{"@type":"Question","name":"What is the difference between java.util.Date and java.time.LocalDate?","acceptedAnswer":{"@type":"Answer","text":"java.util.Date represents an instant in milliseconds since the epoch and is mutable. LocalDate models a calendar date without a time or zone, is immutable and thread-safe, and offers clearer methods such as plusDays and isBefore."}},{"@type":"Question","name":"Is SimpleDateFormat thread-safe?","acceptedAnswer":{"@type":"Answer","text":"No. SimpleDateFormat keeps mutable parse state and produces wrong results when shared across threads. Wrap it in a ThreadLocal, synchronize on the instance, or switch to DateTimeFormatter, which is immutable and safe."}},{"@type":"Question","name":"What pattern do I pass to SimpleDateFormat for yyyy-MM-dd?","acceptedAnswer":{"@type":"Answer","text":"Pass the exact string \"yyyy-MM-dd\". Uppercase MM is month, lowercase mm is minute. For a full date and time, use \"yyyy-MM-dd HH:mm:ss\". Always specify a Locale so month names stay reproducible."}},{"@type":"Question","name":"How do I compare two dates in Java?","acceptedAnswer":{"@type":"Answer","text":"With legacy Date, use compareTo which returns a negative, zero, or positive int. With java.time, call isBefore, isAfter, or isEqual on a LocalDate or Instant. Both approaches respect chronological order."}},{"@type":"Question","name":"How do I convert a Date to LocalDateTime?","acceptedAnswer":{"@type":"Answer","text":"Call date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). To go back, use Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Pick the zone explicitly whenever the exact moment matters."}},{"@type":"Question","name":"How does AI help parse date strings in unknown formats?","acceptedAnswer":{"@type":"Answer","text":"AI models trained on log and document corpora infer the likely pattern from sample strings and return a matching DateTimeFormatter pattern. Machine learning classifiers also flag ambiguous fields such as month-day versus day-month order."}},{"@type":"Question","name":"Can GitHub Copilot generate Java date-formatting code?","acceptedAnswer":{"@type":"Answer","text":"Yes. GitHub Copilot suggests DateTimeFormatter patterns, ZonedDateTime conversions, and JUnit tests for locale-sensitive output. Review each suggestion for the correct pattern letters, Locale, and time zone before committing."}}]}],"@id":"https://www.guru99.com/java-date.html#schema-1133618","isPartOf":{"@id":"https://www.guru99.com/java-date.html#webpage"},"publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US","mainEntityOfPage":{"@id":"https://www.guru99.com/java-date.html#webpage"}}]}
```
