Java Util Date
1. Introduction
When writing software applications, A developer might need to work with dates and times in their program. In this blog post, we will take a look at representing and manipulating dates and times using java.util.Date
class, the key classes, and interfaces java.util.Date
provides, and explores some common functions and operations as well as best practices and tips on handling dates and time formats when working with the Java Util Date (java.util.Date
) class.
1.1 Overview of the Java Date Util
java.util.Date
class is used to represent a date in Java. It was one of the earliest classes developers used to represent date and time. The class represents a particular moment in time, with millisecond precision since the 1st of January 1970 00:00:00 GMT (the epoch time) and provides methods
and constructors
to help developers work with date and time in Java applications.
1.2 Importance of managing dates and times in software development
Sometimes, there could be a need to store, collect, retrieve, and display dates and times in a program. Birth dates, employment dates, event timestamps, and other time-related events all depend on date and time. Understanding the concept of time zones and daylight savings would help in accurately representing the different dates and times in different locations in the world. Programming your time to the wrong time zone could lead to incorrect time references being used and stored in a program.
2. Understanding the Java Date Util
2.1 Introduction to the Date Util package
An instance of the java.util.Date
contains the current time as its date and time that can be accessed using the getTime()
method. The class extends the Object
class and implements the Serializable
, Cloneable
and Comparative<Date>
interfaces. The list below shows some methods available in the Date class.
boolean after(Date date)
boolean before(Date date)
Object clone()
int compareTo(Date date)
boolean equals(Date date)
static Date from(Instant instant)
long getTime()
int hashCode()
void setTime(long time)
-
Instant toInstant()
String toString()
2.2 Overview of the key classes and interfaces in the package
2.2.1 Date class
The Date class represents a specific instant in time, with milliseconds precision since the 1st of January 1970 00:00:00 GMT (the epoch time), and is used to keep coordinated Universal Time. It contains different methods and constructors, with most of them deprecated.
The constructors available include Date()
constructor that creates a date object representing the current time and date and a Date(long milliseconds)
constructor which creates a date object with a passed-in parameter in milliseconds since the 1st of January 1970 00:00:00 GMT.
2.2.2 Calendar class
The java.util.Calendar
class is a class that provides methods for converting between dates and time fields. java.util.Calendar
class is particularly used for doing date and time arithmetic in Java.
2.2.3 SimpleDateFormat class
The java.text.SimpleDateFormat
class is used to parse and format dates according to a format pattern. This class is used for the parsing and formatting of dates according to a pattern format you specify as a String which is passed as a parameter to its constructor. The SimpleDateFormat class can also be used to parse and format dates in a local-sensitive way. java.text.SimpleDateFormat
contains the following constructors SimpleDateFormat(String pattern_args)
and SimpleDateFormat(String pattern_args, Locale locale_args)
.
2.2.4 TimeZone class
The java.util.TimeZone
class is a class that represents a time zone offset and is also used to figure out daylight savings. It takes into consideration the various time zones in different countries around the globe. java.util.TimeZone
class used together with the java.util.Calendar
class is useful for performing calendar arithmetics across various timezones.
2.3 Exploring common operations and functionalities provided by the Date Util package
2.3.1 Parsing and formatting dates
Formatting a date means that java.text.SimpleDateFormat
formats a Date object to a String while parsing a date means that java.text.SimpleDateFormat
parses a date from a String. An instance of java.text.SimpleDateFormat
has a format()
method that is used to format a java.util.Date
instance. Similarly, java.text.SimpleDateFormat
provides a parse()
method that parses a String into a java.util.Date
instance.
2.3.2 Date Arithmetic and Manipulation
To perform date arithmetic and manipulation, The java.util.Calendar
class provides methods to handle this. The Java Calendar class provides methods to convert dates between some specific instant in time and a set of calendar fields such as Calendar.YEAR, Calendar.MONTH, Calendar.DATE, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND
.
2.3.3 Time zone handling
To handle time zones with java.util.Date
, You set the timezone on a java.text.SimpleDateFormat
object with the setTimeZone()
method for it to know what timezone you want it to display its date and time. Note that it is not recommended to use the java.util.Date
object to handle time zones as there is no timezone information available within java.util.Date
object in Java.
2.3.4 Comparison and Sorting of Dates
java.util.Date
class implements the java.lang.Comparable
interface, hence comparison of dates can be achieved using the compareTo()
method. The class also provides other methods such as after() and before()
methods to perform the comparison of two date instances in Java.
2.3.5 Date calculations and conversions
There could be a need to calculate the difference between dates in an application. Date calculations and conversions in Java can be achieved using the SimpleDateFormat
class with the Date
class. To perform date calculations and conversions between two dates, an Object is first created with the SimpleDateFormat class. The parse()
method of the SimpleDateFormat class is then used to convert text/string input from the program into a date object format. Next, The getTime()
method from the Date class is used to get the time in milliseconds of both date objects and whatever mathematical calculations need to be applied to them. The result in milliseconds could be converted to hours, weeks, days, months, or years. The built-in java.util.concurrent.TimeUnit
class provides toDays(), toHours(), toMinutes() and toSeconds()
methods to convert the time in milliseconds to days, hours, minutes, and seconds respectively.
3. Working with Dates and Times
3.1 Understanding the core concepts of dates and times
Keeping an accurate account of daylight savings and time zones is important when programming software applications with date and time. It is possible to know the time anywhere in the world, as long as you know its time zone.
3.1.1 Time zones and offsets
There are 24 time zones in the world and some countries do have multiple time zones and daylight savings. Internationally, the Universal Time Coordinated or Coordinated Universal Time (UTC) is the standard used for regulating time in the world and its offset range is from -12:00 to +14:00. Each time zone is described by an identifier and has a format of region/city for example (Africa/Lagos) and an offset from UTC. For example, the offset for Lagos is UTC+01:00.
3.1.2 Date Formats and Patterns
Choosing the right data format to represent date and time when dealing with date is important. A Date format describes how date and time values passed as String should be read from and written to. You specify a string as date and time patterns yourself for date-time formatting. Letters without quotes from ‘A’ to ‘Z’ and ‘a’ to ‘z’ are interpreted as pattern letters that represent the parts of a date or time string. The table below shows some commonly used pattern letters and some date and time pattern formats. For a more detailed list of pattern letters and patterns, please refer to the official Java Documentation for SimpleDateFormat class.
Letter | Date/Time component | Example |
---|---|---|
y | year | 2023; 23 |
M | Month in year | 07; July |
W | Week in month | 3 |
d | Day in month | 10 |
a | am/pm marker | AM |
h | Hour in am/pm (1-12) | 12 |
m | minute in hr | 30 |
s | second in minute | 25 |
z | time zone | West Africa Standard Time; WAT; GMT+01:00 |
Date and Time Pattern | Output |
---|---|
dd-MM-YYYY | 03-07-2023 |
yyyy-MM-dd | 2023-07-03 |
MM-dd-YYYY | 07-03-2023 |
HH:mm:ss | 2009-12-31 23:59:59 |
HH:mm:ss.SSS | 23:59.59.999 |
yyyy-MM-dd HH:mm:ss.SSS | 2009-12-31 23:59:59.999 |
yyyy-MM-dd HH:mm:ss.SSS Z | 2023-07-03 23:59:59.999 +0100 |
3.1.3 Time calculations and durations
Performing time calculations and durations can be a common and recurrent task in computer programming. java.util.concurrent.TimeUnit
class provides toDays(), toHours(), toMinutes() and toSeconds()
methods to perform time calculations and durations.
3.2 Implementing date and time operations using the Date Util package
3.2.1 Parsing and formatting dates
The code sample below shows an example of how to parse dates from String and format String to dates using the SimpleDateFormat
class.
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class StringDateConversion { public static void main(String[] args) { SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); try { String dateToString = formatter.format(new Date()); Date stringToDate = formatter.parse("26-02-2023"); System.out.println("Formatting a date output: " + dateToString); System.out.println("Parsing Date from String: " + stringToDate.toString()); } catch (ParseException e) { } } }
In the example code shown above, a string is passed as a parameter to the constructor of the SimpleDateFormat
class and uses a pattern format of "dd-MM-yyyy"
meaning, use 2 digits for days (dd)
, 2 digits for months (MM)
and 4 digits for years (yyyy)
.
3.2.2 Adding and subtracting time
java.util.Date
class does not provide methods to add or subtract time. java.util.Calendar
provides support for the addition and subtraction of time and date with the java.util.Date
. The The java.util.Calendar
class provides accessor methods for the timezone, year, month, day, hour, minutes, seconds, and milliseconds of a given date in a time zone. Below is an example code of how to add and subtract days, years, months, hours, minutes, and seconds from a date.
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class DateArithmetic { public static void main(String[] args) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); Date date = new Date(); System.out.println("Current Date and Time: " + dateFormat.format(date)); //instantiate a GregorianCalendar and Convert Date to Calendar Calendar calendar = new GregorianCalendar(); calendar.setTime(date); // perform basic arithmetic of addition and subtraction on calendar.add(Calendar.DATE, -10); calendar.add(Calendar.MONTH, 1); calendar.add(Calendar.YEAR, 3); calendar.add(Calendar.HOUR, -2); calendar.add(Calendar.MINUTE, 30); calendar.add(Calendar.SECOND, 10); //Convert the GregorianCalendar back to Date Date updatedTime = calendar.getTime(); System.out.println("Updated Date and Time: " + dateFormat.format(updatedTime)); } }
In the example code above, We used the calendar.add(unit, amount)
method for adding and subtracting date and time. To add to a field, add a positive number to the calendar.add(Calendar.YEAR,3)
method and to subtract from a field, add a negative value to the calendar.add(Calendar.DATE,-10)
method. The negative amount would then be subtracted from the field.
3.2.3 Converting time zones
By default, the java.util.Date
does not contain any timezone information. Printing a Date object directly would output with the default system time zone. We can use the java.text.DateFormat
with java.util.
TimeZone class together with the java.util.Date
class to convert between time zones. The example code below shows how to convert between time zones using the java.text.DateFormat
class.
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class ConvertTimezones { private static final String DATE_FORMAT = "dd-MM-yyyy HH:mm:ss.SSS z"; public static void main(String[] args) throws ParseException { SimpleDateFormat africaFormat = new SimpleDateFormat(DATE_FORMAT); Date date = new Date(); String todaysDate = africaFormat.format(date); TimeZone timezone = TimeZone.getDefault(); // Convert from TimeZone in Africa/Lagos System.out.println("TimeZone : " + timezone.getID() + " use " + timezone.getDisplayName()); System.out.println("Time in Lagos, Nigeria : " + todaysDate); // To TimeZone in America/Edmonton SimpleDateFormat americaFormat = new SimpleDateFormat(DATE_FORMAT); TimeZone timezoneAmerica = TimeZone.getTimeZone("America/Edmonton"); americaFormat.setTimeZone(timezoneAmerica); String sDateInEurope = americaFormat.format(date); Date dateInAmerica = africaFormat.parse(sDateInEurope); System.out.println("\nTimeZone : " + timezoneAmerica.getID() + " use " + timezoneAmerica.getDisplayName()); System.out.println("Time in Edmonton, AB, Canada : " + africaFormat.format(dateInAmerica)); } }
3.2.4 Handling daylight saving time
Daylight Savings is a practice of moving the clocks forward at a certain time of the year (usually summer) in some countries to use natural daylight a little longer. The following example code below shows how to handle Daylight Savings Time (DST) with the java.util.TimeZone
class.
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class DaylightSavings { public static void main(String[] args) throws ParseException { SimpleDateFormat sourceFormat = new SimpleDateFormat("dd-MM-yyyy"); SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'+|-hh:mm"); String withDLS = "10-03-2023"; String withOutDLS = "11-03-2023"; try { Date dateWithDLS = sourceFormat.parse(withDLS); Date dateWithOutDLS = sourceFormat.parse(withOutDLS); System.out.println("Default Timezone with Day Light Saving :" + targetFormat.format(dateWithDLS)); System.out.println("Default Timezone without Day Light Saving :" + targetFormat.format(dateWithOutDLS)); sourceFormat.setTimeZone(TimeZone.getTimeZone("America/Edmonton")); dateWithDLS = sourceFormat.parse(withDLS); dateWithOutDLS = sourceFormat.parse(withOutDLS); System.out.println("America/Edmonton Timezone with Day Light Saving :" + targetFormat.format(dateWithDLS)); System.out.println( "America/Edmonton Timezone without Day Light Saving :" + targetFormat.format(dateWithOutDLS)); } catch (ParseException ex) { ex.printStackTrace(); } } }
3.2.5 Calculating time differences
This section shows an example of how to calculate date and time difference using the java.util.Date
class with the SimpleDateFormat
class. The sample code below shows how to calculate the difference between two dates converted in milliseconds.
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DifferenceBetweenDates { public static void main(String args[]) throws ParseException { String dateStart = "28-06-2023 09:17:28"; String dateStop = "30-06-2023 12:37:58"; SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); Date startDate; Date endDate; try { startDate = format.parse(dateStart); endDate = format.parse(dateStop); //Difference in milliseconds long difference = endDate.getTime() - startDate.getTime(); long differenceInSeconds = difference / 1000 % 60; long differenceInMinutes = difference / (60 * 1000) % 60; long differenceInHours = difference / (60 * 60 * 1000) % 24; long differenceInDays = difference / (24 * 60 * 60 * 1000); System.out.print("Diffrence between start date and end date is : " + differenceInDays + " days, " + differenceInHours + " hours, " + differenceInMinutes + " minutes, " + differenceInSeconds + " seconds."); } catch (ParseException e) { e.printStackTrace(); } } }
The output of running the above code is shown below.
3.2.6 Working with date intervals
Sometimes a use case might involve getting the number of days from a date to another date. The following code example shows how to calculate the number of days between two dates using java.util.Date
.
import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.concurrent.TimeUnit; public class DateDifferenceInDays { public static void main(String[] args) { try { //Use SimpleDateFormat to convert String to Date SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH); Date startDate = sdf.parse("28-06-2023"); Date endDdate = sdf.parse("30-06-2023"); //Get the number of days between dates long timeDifference = Math.abs(endDdate.getTime() - startDate.getTime()); long daysDifference = TimeUnit.DAYS.convert(timeDifference, TimeUnit.MILLISECONDS); System.out.println("The number of days between end date and start date is: " + daysDifference); } catch (Exception e) { e.printStackTrace(); } } }
The above code would result in the following output
4. Best Practices and Tips
4.1 Handling date and time formats
4.1.1 Choosing the appropriate date format
When working with dates, It is a good practice to store dates in UTC format. Also, when serializing a date-time value to text, it is recommended to use the ISO 8601 standard. Always consider using a human-readable format when working with dates and times.
4.1.2 Dealing with different time zones
Software applications are developed to handle users and customers across the world with different time zones. Also, some countries are having several time zones. The concept of Daylight Savings Time (DST) is also used by some countries and should be taken into consideration while working with dates and times across different time zones. It is recommended to use java.util.ZonedDateTime
class from Java 8 DateTime API for handling dates, because it is fully aware of DST.
4.1.3 Avoiding common pitfalls in date parsing and Formatting
Always be conscious of the cost of parsing and formatting date objects. Consider using a suitable date format and pattern based on your use case.
4.2 Performance considerations
When working with dates, If you don’t design them for performance from the outset, a lot more time and effort could be spent trying to upgrade their performance.
4.2.1 Efficient date and time operations
It is more efficient and faster to manipulate a date object compared to having to parse it from a String and format it back to a String.
4.2.2 Avoiding unnecessary object creation
Avoid the unnecessary object creation of java.util.Date, java.util.TimeZone and java.util.Calendar
instances using the static modifier for variables and methods on date time fields. This would result in significantly improved performance of the application. For example, instead of declaring a local variable as private Date startDate
you should declare the variable as a static final field like private static final Date startDate
. Also making use of static initializers as shown in the example below would avoid the unnecessary creation of objects.
static { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.set(1946, Calendar.JANUARY, 1, 0, 0, 0); startDate = calendar.getTime(); calendar.set(1965, Calendar.JANUARY, 1, 0, 0, 0); endDate = calendar.getTime(); }
4.3 Migration to newer Java date/time APIs
4.3.1 Introduction to java.time
package
Java 8 introduced the java.time
package which provides a rich API for performing many common operations on Dates and simplifies the handling of complex tasks for date and time manipulation in Java applications. In the newer java.time
package, date, and time are now represented by the number of seconds and nanoseconds since Jan 1st, 1970 instead of by a single number of milliseconds used by java.util.Date
class.
4.3.2 Advantages and benefits of using the new APIs
Some advantages and benefits of the new Date time APIs are:
- Thread safety: The new
java.time
package introduced in Java 8 is immutable and thread-safe.java.util.Date
is not thread-safe, and therefore making developers write additional code to handle thread safety. - Better API design and easy to understand: The new
java.time
package provides a variety of utility methods that support the most common operations. The oldjava.util.Date
class had fewer methods that were inadequate to perform day-to-day operations. - Improved ZonedDate and Time Handling: The new package provides classes and methods for better handling of time zone logic.
5. Conclusion
In this article, we explored handling dates and times using the java.util.Date
class. We took a look at manipulating dates and handling time zones in Java using multiple examples. We also briefly introduced the new java.time
package in Java 8 and took a look at its advantages and benefits, compared to the old Date class. Understanding how to store and manipulate dates and times across different time zones efficiently is critical when developing Java applications to serve users across the globe.
6. Download the Source Code
This was a tutorial on Java Util Date in Java.
You can download the full source code of this example here: Java Util Date