A Simple Guide for Java.util.Date
18 Feb 2019Why am I talking about java.util.Date
in this day and age when the “whole” community has moved on? Because the whole community has not yet moved on and several of us still work with legacy code bases, some going as far back as Java 6 and much as we are moving forth, we can’t go into the future without thoroughly coming to terms with our past :)
I bet you often deal with dates and have to frequently google how to parse date from string, convert date to different string formats for SQL storage or user-friendly display, compare dates, add and subtract days, months, years etc from a date. These are pretty common needs for most developers so let’s get on with it and move on with our lives. I will do my best to keep it short and sweet!
Date Creation
The java.util.Date class has 2 constructors, a default one and one that take a long
value which represents the the number of milliseconds that have elapsed since 00:00:00 Thursday, 1 January 1970 AKA Unix Epoch time. It’s just a way to keep ourselves and our computers sane while dealing with time in different locales and timezones:
To make for easier testing, I captured a long
time value on the day of writing this article as the default constructor internally invokes System.currentTimeInMillis()
to get the now
time:
Take note of the default format when the date is toString
‘d
Comparing Dates
The Date object has a method called getTime
which converts the date back to a long
unix epoch time. It’s a reversal of the previously seen creation process. We can just compare the long
values of 2 dates to know which is an earlier(less) date:
We can use the compareTo
instance method to compare one date to the other which is passed as an argument to compareTo
. If the date on which compareTo
is called is earlier(less) than the argument date, the result is -1, if they are the same instance in time, we get a 0 and a 1 if the argument date is less:
Finally,we have the instance methods before
and after
. They are definitely much more readable and intuitive than the previous 2, especially compareTo
. We call each of these on a Date
object and pass the second date to be compared as an argument. The results are boolean:
Date to String conversion
Frequently we will want to convert a date to a string either for storage or user-friendly display, this is done by formatting the date. java.text.DateFormat
class comes in handly, most commonly though its subclass java.text.SimpleDateFormat
. SimpleDateFormat is very simple to use and the main requirement is to understand the notation used to define formats.
For reference information about the different formatting patterns and codes we will use here(m
for minute, M
for month, s
for seconds etc), head over here.
Let’s first recall the default conversion when we haven’t specified any format:
Mon
stands for monday, Feb
for february then 18 is day of month, followed by time in hours, minutes and seconds, timezone and finally year. This may be a little verbose for your needs or you would like to have time in 12 hour clock system or remove the timezone or use the full month name etc, let’s first try to recreate the above string by specifying our own format(remember to keep this reference doc close):
Everything seems to be alright except the month section, it’s a 2
because Feb is the second month of the year, we used its code M
which represents the simplest format for the month, we could choose to make it 2 digits so that single digit months match double digit months(nov, dec) in length, we do this by appending another M
To get month in words but abbreviated as our default example gives, we append another M
to make them 3:
If we want full month name, then make them 4:
This pattern of adding and reducing the number of codes for each part of the date is common in formatting dates. Play around with this while referring to the reference doc for further clarity. For instance, let’s get the full day name by using 4 E
s:
Watch out though, as this does not work for all codes. Let’s try to convert our time to 12 hour clock system(h
for 12 and H
for 24, a
for the AM/PM marker of 12 hour system):
We can strip the zeros that appear to pad up the time in case it’s all single digits. We do this by using single forms of the codes hh
, mm
and ss
:
But it does not look intuitive right? I have commonly seen the zero stripped from the hour part but not from the minute and second parts, do what works best for your use case.
Another caveat and common cause of bugs is developers confusing upper case and lower case formatting codes. m
and M
are different, the former for minute and the latter for month. Always remember that these codes are case sensitive:
With the above examples, we can now achieve almost any format we need by a combination of the formatting codes picked from the reference documentation, see SQL date for example:
One of the most commont ISO-8601
formats that has given me headache in the past. Some APIs are strict about the date format they accept. Take note of how we are using single quotes here, they are delimiters and enable us to inject any text in the date format:
Sometimes the ISO-8601
format requires fractions of a second to be represented, we use the SSS
code:
Finally, using the powerful single quotes, we can inject any text in the formatted date:
String to Date conversion
SimpleDateFormat
has a parse
method that does the opposite of format
as we have seen above. It takes any string we have received from a file, from an API response or created by ourselves and attempts to parse it into a java.util.Date
object or throws a java.text.ParseException
if the pattern we used does not match the date.
Here it is very important to get the pattern right, that means you need to understand the format of the date string before hand. Remember, date will still give the default value we saw earlier if it is toString
‘d:
Let’s see a few other examples to gain more clarity, using the /
date delimiter which we haven’t seen explicitly before:
Let’s also see a case where we have text in the date e.g. month in words:
We used MMMM
month code because we expected a full month name, sometimes, the month is abbreviated, just do what we know already, strip a single M
:
Conclusion
In this article, we have gone through the most important ways of using java.util.Date
class along side the helper classes for formatting. This should act as a quick refresher for those that use this class once in a while or if you are preparing for an interview and just need to remind yourself.
In the next article, we will look at how to add
and subtract
dates such that you can get a date before or after the available date without apply string manipulation kung-fu. We will also look at how to decompose dates by extracting component parts i.e. year, month, day etc from a Date object as well as applying internationalisation. These are made possible by the Calendar
class.