Java SimpleDateFormat
Jakob Jenkov |
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 theZ
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
Tweet | |
Jakob Jenkov |