Formatting Dates
The previous sections have given you an appreciation for the way dates can be created and manipulated. This section will address the manner in which dates can be converted into Strings for display.
Java uses the concept of formatters for converting objects or primitives into Strings for display. These same formatters are also capable of acting in reverse: accepting a String and parsing it to produce an object or primitive of the appropriate type.
With dates, the base interface responsible for formatting is DateFormat, and its principle implementation is SimpleDateFormat.
In order to operate on Dates, the DateFormat needs to know the pattern the textual String should adhere to. The following are all valid representations of the same date (although to varying degrees of accuracy):
• 26 January 2015 15:34:00
• 2015-1-26 3:34pm
• Jan 26, 2015
• 2015
• January 15
Java provides an expression language that can be used to define date formats.
The following is an example of a program that uses a Calendar to construct a Date, and then uses an instance of SimpleDateFormat to print the date in the formats listed:
package dates;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class Formatting {
public static void main(String[] args) {
Calendar c = new GregorianCalendar(2014, 0, 26, 15, 34, 0);
Date date = c.getTime();
DateFormat df1 = new SimpleDateFormat("dd MMMM yyyy HH:mm:ss");
System.out.println(df1.format(date));
df1 = new SimpleDateFormat("yyyy-M-dd h:mm aa");
System.out.println(df1.format(date));
df1 = new SimpleDateFormat("MMM dd, yyyy");
System.out.println(df1.format(date));
df1 = new SimpleDateFormat("yyyy");
System.out.println(df1.format(date));
df1 = new SimpleDateFormat("MMMM yy");
System.out.println(df1.format(date));
}
}
I will not provide a full description of the formatting rules, because these can easily be looked up when needed. There are, however, a few key rules to remember:
• Each component of a date (e.g. hours, days, year) is represented by a letter, but these are case sensitive: “M” represents month, “m” represents minutes, “s” represents seconds. This is a common source of bugs, at least for myself.
• The number of times the letter is repeated may impact the presentation. For instance MMMM produces January, MMM produces Jan, MM produces 01, M produces 1.
• It is possible to interweave date components with other formatting symbols such as “-“ and “:”.
Java also supports a set of “default” formats based on the user’s locale (the concept of locales will be discussed in future chapters). For instance, the following can be used to print the day, month and year in a format appropriate to the user running the program:
DateFormat df2 = DateFormat.getDateInstance(DateFormat.SHORT);
System.out.println(df2.format(date));
The constants MEDIUM, LONG and FULL can also be used, and each provides different output.
As mentioned, you can also use SimpleDateFormat to convert Strings into Dates. The following program demonstrates this:
public static void main(String[] args) throws ParseException {
Calendar c = new GregorianCalendar(2015, 0, 26, 15, 34, 0);
Date date = c.getTime();
DateFormat df1 = new SimpleDateFormat("dd MMMM yyyy HH:mm:ss");
System.out.println(df1.parse("26 January 2015 15:34:00"));
df1 = new SimpleDateFormat("yyyy-M-dd h:mm aa");
System.out.println(df1.parse("2015-1-26 3:34 PM"));
df1 = new SimpleDateFormat("MMM dd, yyyy");
System.out.println(df1.parse("Jan 26, 2015"));
df1 = new SimpleDateFormat("yyyy");
System.out.println(df1.parse("2015"));
df1 = new SimpleDateFormat("MMMM yy");
System.out.println(df1.parse("January 15"));
}
This is an interesting example, because in many of these cases the format does not provide a value for all elements of the date. For instance, in the second last case the only date element you are providing is the year. If a value is not provided for a date component, Java simply defaults in the first value; if no month is provided it is set to January. The example above prints out:
Sun Jan 26 15:34:00 NZDT 2015
Sun Jan 26 15:34:00 NZDT 2015
Sun Jan 26 00:00:00 NZDT 2015
Wed Jan 01 00:00:00 NZDT 2015
Wed Jan 01 00:00:00 NZDT 2015