Core Java

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.

LetterDate/Time componentExample
yyear2023; 23
MMonth in year07; July
WWeek in month3
dDay in month10
aam/pm markerAM
hHour in am/pm (1-12)12
mminute in hr30
ssecond in minute25
ztime zoneWest Africa Standard Time; WAT; GMT+01:00
Some commonly used pattern letters
Date and Time PatternOutput
dd-MM-YYYY03-07-2023
yyyy-MM-dd2023-07-03
MM-dd-YYYY07-03-2023
HH:mm:ss2009-12-31 23:59:59
HH:mm:ss.SSS23:59.59.999
yyyy-MM-dd HH:mm:ss.SSS2009-12-31 23:59:59.999
yyyy-MM-dd HH:mm:ss.SSS Z2023-07-03 23:59:59.999 +0100
Some commonly used pattern examples and output

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).

Fig 1.0. Output from Parsing and Formatting a Date
Fig 1.0. Output from Parsing and Formatting a Date

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));
    }
}
Fig 2.1 Output of adding and subtracting time
Fig 2.1 Output of adding and subtracting time

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));
    }
}

Fig 2.2 Output from converting time zones
Fig 2.2 Output from converting time zones

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.

Fig 3.1. Output of Date Time difference
Fig 3.1. The output of Date Time difference

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

Fig 3.2. Output from working with date intervals
Fig 3.2. Output from working with date intervals

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 old java.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.

Download
You can download the full source code of this example here: Java Util Date

Omozegie Aziegbe

Omos holds a Master degree in Information Engineering with Network Management from the Robert Gordon University, Aberdeen. Omos is currently a freelance web/application developer who is currently focused on developing Java enterprise applications with the Jakarta EE framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button