How to Format Dates with DateTimeFormatter

In Java (starting from Java 8), you can format dates using the DateTimeFormatter class, which provides an easier and more modern approach to date and time formatting. This class is part of the java.time.format package and works seamlessly with the java.time API (e.g., LocalDate, LocalDateTime, ZonedDateTime).

Here’s how you can format dates with DateTimeFormatter:


Example of Formatting Dates with DateTimeFormatter

package org.kodejava.datetime;

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

public class DateTimeFormatterExample {
   public static void main(String[] args) {
      // Get the current date and time
      LocalDateTime currentDateTime = LocalDateTime.now();

      // Define a formatter with a custom pattern
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");

      // Format the date and time
      String formattedDateTime = currentDateTime.format(formatter);

      // Print the result
      System.out.println("Formatted Date and Time: " + formattedDateTime);
   }
}

Example Output:

Formatted Date and Time: 02/08/2025 15:52:30

Common Patterns for Date and Time

Here are the most commonly used symbols for formatting patterns with DateTimeFormatter:

Symbol Meaning Example
y Year 2025
M Month 08 or August
d Day of the month 02
E Day name in a week Tue
H Hour (0-23) 15
h Hour (1-12, AM/PM) 3
m Minute in hour 45
s Second in minute 30
a AM/PM PM
z Time zone name PDT
'text' Literal text ‘at’

Example with Fully Custom Pattern

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class CustomDateFormatting {
   public static void main(String[] args) {
      LocalDate currentDate = LocalDate.now();

      // Custom date format
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, MMMM dd yyyy");
      String formattedDate = currentDate.format(formatter);

      // Print the formatted date
      System.out.println("Custom Formatted Date: " + formattedDate);
   }
}

Output:

Custom Formatted Date: Saturday, August 02 2025

Predefined Formatters in DateTimeFormatter

DateTimeFormatter also provides several predefined, common formatters:

Formatter Pattern Example
DateTimeFormatter.ISO_DATE yyyy-MM-dd 2025-08-02
DateTimeFormatter.ISO_TIME HH:mm:ss 15:45:30
DateTimeFormatter.ISO_DATE_TIME yyyy-MM-dd'T'HH:mm:ss 2025-08-02T15:45:30
DateTimeFormatter.BASIC_ISO_DATE yyyyMMdd 20250802
DateTimeFormatter.RFC_1123_DATE_TIME RFC 1123 format Sat, 02 Aug 2025 15:45:30

Example: Formatting Dates with Time Zones

package org.kodejava.datetime;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class ZonedDateTimeFormatterExample {
   public static void main(String[] args) {
      // Get the current date and time with time zone
      ZonedDateTime zonedDateTime = ZonedDateTime.now();

      // Define a formatter with a custom pattern that includes the time zone
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss z Z");

      // Format the ZonedDateTime
      String formattedDateTime = zonedDateTime.format(formatter);

      // Print the result
      System.out.println("Formatted Date and Time with Time Zone: " + formattedDateTime);
   }
}

Output:

Formatted Date and Time with Time Zone: 02/08/2025 15:50:30 PDT -0700

Explanation of Pattern:

  • z: Displays the short name of the time zone (e.g., PDT, GMT).
  • Z: Displays the time zone offset (e.g., -0700).

Parsing and Formatting Specific Time Zones

You can work with specific time zones using the ZoneId class:

package org.kodejava.datetime;

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class SpecificTimeZoneExample {
   public static void main(String[] args) {
      // Get the current date and time in a specific time zone
      ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/London"));

      // Define a formatter
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, MMM dd yyyy HH:mm:ss z");

      // Format the ZonedDateTime
      String formattedDateTime = zonedDateTime.format(formatter);

      // Print the result
      System.out.println("London Time: " + formattedDateTime);
   }
}

Output:

London Time: Saturday, Aug 02 2025 23:50:30 BST

Predefined Formatter for Time Zones

If you’d like to use the predefined formatters to format dates with time zones, you can try:

package org.kodejava.datetime;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class PredefinedTimeZoneFormatter {
   public static void main(String[] args) {
      // Get the current ZonedDateTime
      ZonedDateTime zonedDateTime = ZonedDateTime.now();

      // Use a predefined formatter
      String formattedDateTime = zonedDateTime.format(DateTimeFormatter.RFC_1123_DATE_TIME);

      // Print the result
      System.out.println("Formatted with Predefined Formatter: " + formattedDateTime);
   }
}

Output:

Formatted with Predefined Formatter: Sat, 02 Aug 2025 15:50:30 -0700

Notes:

  1. Thread Safety:
    Unlike SimpleDateFormat, DateTimeFormatter is thread-safe and can be safely used in concurrent environments.

  2. Extensible Patterns:
    You can use literal text in the patterns by enclosing it in single quotes ('text').

  3. Working with Time Zones:
    If you are working with time zones, you can use ZonedDateTime or OffsetDateTime along with a DateTimeFormatter.

  4. ZoneId Use:
    You can specify almost any valid time zone using ZoneId.of("Zone_Name"). Example: "America/New_York", "Asia/Tokyo", "Australia/Sydney".

  5. Daylight Saving Time:
    Time zones take daylight saving time into account automatically if applicable.
  6. Predefined Formatters with Zones:
    Predefined formatters like DateTimeFormatter.ISO_ZONED_DATE_TIME and DateTimeFormatter.RFC_1123_DATE_TIME are handy for common time zone formats.

How do I convert date string from one format to another format?

In the following code snippet we will see hot to change a date from one format to another format. For example from 2024-11-04 to 04-Nov-24 format in Java. We can use the DateTimeFormatter class from the java.time.format package to do the conversion.

The steps are:

  • Parse the original date string.
  • Format it to the desired pattern.

Here’s the complete code to do this:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateFormatConversion {
    public static void main(String[] args) {
        // The original date string
        String originalDate = "2024-11-04";

        // Define the input and output date formats
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MMM-yy");

        // Parse the original date
        LocalDate date = LocalDate.parse(originalDate, inputFormatter);

        // Format the date to the desired pattern
        String formattedDate = date.format(outputFormatter);

        // Print the formatted date
        System.out.println(formattedDate);
    }
}

Output:

04-Nov-24

In the code above we define two formatters, one for the original date format, and the second one is for the new date format. The input formatter matches the original date format (yyyy-MM-dd). The output formatter specifies the desired format (dd-MMM-yy).

We use the LocalDate.parse() method to parse the string of original date into a LocalDate object. Next, we use the LocalDate.format() method to convert into a new date format using the defined formatter object.

This approach uses java.time API introduced in Java 8, which is the recommended way to handle date and time in Java due to its immutability and thread-safety features.

How do I convert datetime string with optional part to a date object?

Since JDK 8, we can create a datetime formatter / parser pattern that can have optional sections. When parsing a datetime string that contains optional values, for example, a date without time part or a datetime without second part, we can create a parsing pattern wrapped within the [] symbols. The [ character is the optional section start symbol, and the ] character is the optional section end symbol. The pattern inside this symbol will be considered as an optional value.

We can use the java.time.format.DateTimeFormatter class to parse the string of datetime or format the datetime object, and use it with the new Java time API classes such as java.time.LocalDate or java.time.LocalDateTime to convert the string into respective LocalDate or LocalDateTime object as show in the code snippet below.

package org.kodejava.datetime;

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

public class DateTimeParseOptionalParts {
    public static final String OPT_TIME_PATTERN = "yyyy-MM-dd[ HH:mm[:ss]]";
    public static final String OPT_SECOND_PATTERN = "yyyy-MM-dd HH:mm[:ss]";

    public static void main(String[] args) {
        DateTimeFormatter optTimeFormatter = DateTimeFormatter.ofPattern(OPT_TIME_PATTERN);
        LocalDate date1 = LocalDate.parse("2023-08-28", optTimeFormatter);
        LocalDate date2 = LocalDate.parse("2023-08-28 17:15", optTimeFormatter);
        LocalDate date3 = LocalDate.parse("2023-08-28 17:15:30", optTimeFormatter);
        System.out.println("date1 = " + date1);
        System.out.println("date2 = " + date2);
        System.out.println("date3 = " + date3);

        DateTimeFormatter optSecondFormatter = DateTimeFormatter.ofPattern(OPT_SECOND_PATTERN);
        LocalDateTime datetime1 = LocalDateTime.parse("2023-08-28 17:15", optSecondFormatter);
        LocalDateTime datetime2 = LocalDateTime.parse("2023-08-28 17:15:30", optSecondFormatter);
        System.out.println("datetime1 = " + datetime1);
        System.out.println("datetime2 = " + datetime2);
    }
}

Here are the outputs of the code snippet above:

date1 = 2023-08-28
date2 = 2023-08-28
date3 = 2023-08-28
datetime1 = 2023-08-28T17:15
datetime2 = 2023-08-28T17:15:30

How do I discover the quarter of a given date?

The following code snippet shows you a various way to get the quarter of a given date. Some methods that we use below are:

  • Using the new java.time API of Java 8 IsoFields.QUARTER_OF_YEAR.
  • Using Java 8 DateTimeFormatter pattern of Q or q. The length of “q” give us a different result.
  • Using java.util.Date.
  • Using java.util.Calendar.
  • Get the quarter from an array of string.

Let’s see the code snippet in action.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.IsoFields;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateQuarter {
    public static void main(String[] args) {
        // Using Java 8
        LocalDate now = LocalDate.now();
        int quarter = now.get(IsoFields.QUARTER_OF_YEAR);
        System.out.println("quarter  = " + quarter);

        // Using DateTimeFormatter Q / q, set the Locale to get value
        // in local format
        String quarter1 = LocalDate.of(2023, 8, 17)
                .format(DateTimeFormatter.ofPattern("q", Locale.US));
        String quarter2 = LocalDate.of(2023, 8, 17)
                .format(DateTimeFormatter.ofPattern("qq", Locale.US));
        String quarter3 = LocalDate.of(2023, 8, 17)
                .format(DateTimeFormatter.ofPattern("qqq", Locale.US));
        String quarter4 = LocalDate.of(2023, 8, 17)
                .format(DateTimeFormatter.ofPattern("qqqq", Locale.US));
        System.out.println("quarter1 = " + quarter1);
        System.out.println("quarter2 = " + quarter2);
        System.out.println("quarter3 = " + quarter3);
        System.out.println("quarter4 = " + quarter4);

        // Using older version of Java
        Date today = new Date();
        quarter = (today.getMonth() / 3) + 1;
        System.out.println("quarter = " + quarter);

        // Using java.util.Calendar object. For certain date
        // we can set the calendar date using setTime() method.
        Calendar calendar = Calendar.getInstance();
        quarter = (calendar.get(Calendar.MONTH) / 3) + 1;
        System.out.println("quarter = " + quarter);

        // Custom the quarter as text
        String[] quarters = new String[]{"Q1", "Q2", "Q3", "Q4"};
        String quarterString = quarters[quarter - 1];
        System.out.println("quarterString = " + quarterString);
    }
}

And here are the result of the code snippet above:

quarter  = 1
quarter1 = 3
quarter2 = 03
quarter3 = Q3
quarter4 = 3rd quarter
quarter = 1
quarter = 1
quarterString = Q1

How do I get all Sundays of the year in Java?

You need to create a holiday calendar for your application. One of the functionality is to include all Sundays of the year as a holiday for your calendar. The following code snippet will show you how to get all Sundays of the given year.

First we need to find the first Sunday of the year using the first 3 lines of code in the main() method. After getting the first Sunday we just need to loop to add 7 days using the Period.ofDays() to the current Sunday to get the next Sunday. We stop the loop when the year of the Sunday is different to the current year.

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

import static java.time.temporal.TemporalAdjusters.firstInMonth;

public class FindAllSundaysOfTheYear {
    public static void main(String[] args) {
        // Create a LocalDate object that represent the first day of the year.
        int year = 2021;
        LocalDate now = LocalDate.of(year, Month.JANUARY, 1);
        // Find the first Sunday of the year
        LocalDate sunday = now.with(firstInMonth(DayOfWeek.SUNDAY));

        do {
            // Loop to get every Sunday by adding Period.ofDays(7) to the current Sunday.
            System.out.println(sunday.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
            sunday = sunday.plus(Period.ofDays(7));
        } while (sunday.getYear() == year);
    }
}

The output of this code snippet are:

Sunday, January 3, 2021
Sunday, January 10, 2021
Sunday, January 17, 2021
Sunday, January 24, 2021
Sunday, January 31, 2021
Sunday, February 7, 2021
Sunday, February 14, 2021
Sunday, February 21, 2021
...
Sunday, December 5, 2021
Sunday, December 12, 2021
Sunday, December 19, 2021
Sunday, December 26, 2021