Java SimpleDateFormat

Jakob Jenkov
Last update: 2021-03-09

The java.text.SimpleDateFormat class is used to both parse and format dates according to a formatting pattern you specify yourself. When parsing dates, the Java SimpleDateFormat typically parses the date from a Java String. When formatting dates, the SimpleDateFormat typically formats a Date object into a String, although it can also format the date into a StringBuffer.

This text explains how to use the SimpleDateFormat class to format dates.

Creating a SimpleDateFormat

You create a SimpleDateFormat instance like this:

String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

The pattern parameter passed to the SimpleDateFormat constructor is the pattern to use for parsing and formatting of dates. The pattern syntax is covered later in this text. The pattern is just a regular Java String.

Formatting Dates

Once you have created a SimpleDateFormat instance you can format dates using its format() method. Here is an example:

String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

String date = simpleDateFormat.format(new Date());
System.out.println(date);

The Date instance passed to the format() method is a java.util.Date instance.

The output printed from the above SimpleDateFormat example would be:

2018-09-09

Notice how the formatted date string starts with the year, then month, then day. The sequence of the date fields are determined by the date pattern passed to the SimpleDateFormat constructor. As mentioned earlier, this format will be explained a bit later in this Java SimpleDateFormat tutorial.

Format Date Into StringBuffer

The Java SimpleDateFormat class is also capable of formatting a Date object into a StringBuffer, instead of returning an individual String with the date formatted. The SimpleDateFormat class does this via a version of the format() method that takes the Date, StringBuffer and a FieldPosition instance as parameters.

Here is an example of formatting a date into a StringBuffer using Java SimpleDateFormat :

StringBuffer stringBuffer = new StringBuffer();
Date now = new Date();

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
simpleDateFormat.format(now, stringBuffer, new FieldPosition(0));

It is not exactly clear how the FieldPosition instance is used. It seems the format() method appends the formatted String to the end of the StringBuffer no matter what the int value passed to the FieldPosition constructor is.

Parsing Dates

You can parse a String into a java.util.Date instance using the parse() method of the SimpleDateFormat instance. Here is an example:

String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

Date date = simpleDateFormat.parse("2018-09-09");

Once this code is executed, the date variable points to a Date instance representing september 9th, 2018.

Creating a SimpleDateFormat For a Specific Locale

You can create a SimpleDateFormat instance targeted at a specific Java Locale. Doing so will format the dates according to that Locale whenever relevant. For instance, a formatting pattern including the name of the week day will write the week day in the language of the given Locale. Here is an example:

String pattern = "EEEEE dd MMMMM yyyy HH:mm:ss.SSSZ";
SimpleDateFormat simpleDateFormat =
        new SimpleDateFormat(pattern, new Locale("da", "DK"));

String date = simpleDateFormat.format(new Date());
System.out.println(date);

The output printed from this code could be:

søndag 09 september 2018 09:53:17.013+0200

Notice how week day (søndag = sunday) and month (september) is written in Danish.

Pattern Syntax

You can use the following symbols in your formatting pattern:

G Era designator (before christ, after christ)
y Year (e.g. 12 or 2012). Use either yy or yyyy.
M Month in year. Number of M's determine length of format (e.g. MM, MMM or MMMMM)
d Day in month. Number of d's determine length of format (e.g. d or dd)
h Hour of day, 1-12 (AM / PM) (normally hh)
H Hour of day, 0-23 (normally HH)
m Minute in hour, 0-59 (normally mm)
s Second in minute, 0-59 (normally ss)
S Millisecond in second, 0-999 (normally SSS)
E Day in week (e.g Monday, Tuesday etc.)
D Day in year (1-366)
F Day of week in month (e.g. 1st Thursday of December)
w Week in year (1-53)
W Week in month (0-5)
a AM / PM marker
k Hour in day (1-24, unlike HH's 0-23)
K Hour in day, AM / PM (0-11)
z Time Zone
' Escape for text delimiter
' Single quote

Characters other than these will be treated as normal text to insert into the pattern, and thus into the formatted dates.

Some characters can be used in different numbers. For instance, you can write either yy for a 2-character version of the year (e.g. 12), or you can write yyyy for a 4-character version of the year (e.g. 2012). For more information about the patterns accepted, see the JavaDoc for the SimpleDateFormat class.

Pattern Examples

Here are a few Java SimpleDateFormat date pattern examples:

Pattern Example
dd-MM-yy 31-01-12
dd-MM-yyyy 31-01-2012
MM-dd-yyyy 01-31-2012
yyyy-MM-dd 2012-01-31
yyyy-MM-dd HH:mm:ss 2012-01-31 23:59:59
yyyy-MM-dd HH:mm:ss.SSS 2012-01-31 23:59:59.999
yyyy-MM-dd HH:mm:ss.SSSZ 2012-01-31 23:59:59.999+0100
EEEEE MMMMM yyyy HH:mm:ss.SSSZ Saturday November 2012 10:45:42.720+0100

DateFormatSymbols

It is possible to customize the date symbols used in the formatted output, for a specific Locale. You do so using a java.text.DateFormatSymbols instance. Here is an example:

Locale locale = new Locale("en", "UK");
DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale);
dateFormatSymbols.setWeekdays(new String[]{
        "Unused",
        "Sad Sunday",
        "Manic Monday",
        "Thriving Tuesday",
        "Wet Wednesday",
        "Total Thursday",
        "Fat Friday",
        "Super Saturday",
});

String pattern = "EEEEE MMMMM yyyy";
SimpleDateFormat simpleDateFormat =
        new SimpleDateFormat(pattern, dateFormatSymbols);

String date = simpleDateFormat.format(new Date());
System.out.println(date);

First a new DateFormatSymbols instance is created for the UK Locale.

Second, a new set of names for week days is set. Notice that the first string "unused" is never used. The indices in this array must start from one, to be indexable by the Calendar.SUNDAY, Calendar.MONDAY etc. constants. The Calendar.SUNDAY constant is 1, Calendar.MONDAY is 2 etc.

Third a SimpleDateFormat is created using the DateFormatSymbols, and a date is formatted with it. The output printed from this could would look like this:

Super Saturday November 2012

Notice how the custom week day name is used.

You can set more date formatting symbols on the DateFormatSymbols instance. Here are the methods you can use to set additional symbols:

dateFormatSymbols.setWeekdays();
dateFormatSymbols.setAmPmStrings();
dateFormatSymbols.setEras();
dateFormatSymbols.setLocalPatternChars();
dateFormatSymbols.setMonths();
dateFormatSymbols.setShortMonths();
dateFormatSymbols.setShortWeekdays();
dateFormatSymbols.setZoneStrings();

See the JavaDoc for the java.text.DateFormatSymbols class for more details about these methods and symbols.

Set Time Zone of SimpleDateFormat

The examples shown so far in this tutorial are all using the system default time zone. That means, that in case you are formatting a date, the SimpleDateFormat will assume you want to format that date according to the system's time zone. However, this may not always be what you want.

You can set the time zone of a SimpleDateFormat using its setTimeZone() method. The setTimeZone() method takes an Java TimeZone instance (java.util.TimeZone) as parameter. Here is an example showing how to set the time zone of a Java SimpleDateFormat instance:

SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");

simpleDateFormat1.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));

Once the time zone is set, the SimpleDateFormat will change its formatting. Here is an example that sets the time zone to two different time zones, and formats the same date with each time zone:

Date now = new Date();

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");

simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(simpleDateFormat.format(now));

simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
System.out.println(simpleDateFormat.format(now));

The output printed from this examnple would be similar to:

2018-09-09 10:43:54+0100
2018-09-09 11:43:54+0200

Notice the +0100 and +0200 parts of the formatted dates. These indicate what time zone the time is formatted as. By the way, the reason London is 1 hour ahead of UTC / GMT, and Paris is 2 hours ahead, is because of summer time. During winter time the time zone offsets would have been +0000 and +0100.

ISO Date Format

Sometimes you might want to format a Date according to the ISO date format. More specifically, the ISO 8601 date format. The ISO 8601 date format (hereafter just called ISO date format) looks like this:

yyyy-MM-ddTHH:mm:ss:sssZ

The ISO 8601 date format has the advantage, that if you sort date strings formatted using the ISO 8601 format, the strings will actually be sorted in date order. In other words, the alphabetical order is the same as the date-time order.

The only new characters in the above format are the T between the date and time, and the Z at the end of the pattern representing the time zone. Both will explained below. Notice, that the ISO 8601 date format does not seem to include milliseconds in its date format.

The T is actually a literal character that has to be located between the date and time parts of an ISO 8601 date string. For instance:

2018-09-24T17:48:00

The Z character representing the time zone can either be:

  • A literal Z character. In that case the Z represents the UTC time zone.
  • A time zone string encoded using one of the patterns:
    • ±hh:mm
    • ±hhmm
    • ±hh

Of these ISO time zone formats, the Java SimpleDateFormat class only supports the second format (+hhmm), or the format ending with the Z character.

In order to create a Java SimpleDateFormat instance using the ISO 8601 format ending with the Z character for the UTC time zone, you need to using the following date pattern String:

yyyy-MM-dd'T'HH:mm:ss'Z'

Notice how the T and Z characters are both enclosed in single quote characters. This is to make the SimpleDateFormat class treat them as literal characters to be inserted, instead of trying to interpret them as representing some part of the date. If you do not enclose the T and Z characters in single quotes, you will get an exception when creating the SimpleDateFormat instance. Here is an example of creating a Java SimpleDateFormat using the above ISO 8601 date format pattern:

String isoDatePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(isoDatePattern);

String dateString = simpleDateFormat.format(new Date());

Here is an example of a date formatted by a SimpleDateFormat using the above pattern:

2018-09-24T18:01:24Z

In order to format a date as according to the ISO 8601 date format with a different time zone than UTC, use the following date pattern when creating a Java SimpleDateFormat instance:

yyyy-MM-dd'T'HH:mm:ssZ

Notice that the Z character is no longer enclosed in single quotes. Here is an example of creating a Java SimpleDateFormat using the above date format:

String isoDatePattern = "yyyy-MM-dd'T'HH:mm:ssZ";

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(isoDatePattern);

String dateString = simpleDateFormat.format(new Date());

The date string generated from the above code example will look similar to this:

2018-09-24T18:09:24+0200

Jakob Jenkov

Featured Videos

Java ConcurrentMap + ConcurrentHashMap

Java Generics

Java ForkJoinPool

P2P Networks Introduction

















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next