Image of a plain as a blank canvas for our custom software development

Introduction to Java Time

Arteco - Information Technologies

  • :)
  • :0
  • :D
  • ;)
  • :]
foto Ramón Arnau

Ramón Arnau

Gerente de Arteco Consulting SL

Starting from JAVA 8+, new classes and methods were introduced in the JDK for the Management of Times and Dates. Here we list the main ones

Time Management in Java underwent a significant redesign in Java 8 and later versions, taking it a step further towards a well-structured and powerful API. In this article, we explain how to use it and how it differs from the API prior to java.time.

Introduction to Date Management with Java

Currently, in the Java JDK, there are two APIs for managing calendars, dates, and times that programmers can use. The first one is an obsolete API that will be removed from Java in the future, corresponding to the use of java.util.Date, java.util.Calendar, and related classes. These objects have been around since the beginning of Java, and through the evolution of the language and its use in increasingly diverse environments, they have become outdated, as some aspects were not considered during the design phase, such as concurrency and immutability.

To address these drawbacks, in the Jdk 8 version and later, the language incorporates a new API for time management, commonly referred to as java.time due to the package where its classes are located. We will see in the following lines how to use each one.

Time and Date Management in JDK 8+

Remember that the time API is only available in Java 8 and above. If you are working with an earlier version, it is advisable to review the following section.

The API known as java.time corresponds to a complete, mature, and stable redesign by the Java maintainers' community. It incorporates the best techniques for time control, allowing Java to be used in diverse and complex environments, including the calculation of astronomical dates with astonishing precision. Additionally, ease of use, immutability, and concurrency have been considered to prevent issues in the use or execution of complex applications.

The main objects in java.time for managing hours and dates are:

  • Clock: A clock that provides access to the current instant, date, and time using a time zone.
  • Duration: A time-based amount, like '34.5 seconds.'
  • Instant: An instantaneous point on the timeline.
  • LocalDate: A date without a time zone in the ISO-8601 calendar system, like 2007-12-03.
  • LocalDateTime: A date and time without a time zone in the ISO-8601 calendar system, like 2007-12-03T10:15:30.
  • LocalTime: Time without a time zone in the ISO-8601 calendar system, like 10:15:30.
  • MonthDay: A month-day in the ISO-8601 calendar system, like --12-03.
  • OffsetDateTime: A date and time with a UTC/Greenwich offset in the ISO-8601 calendar system, like 2007-12-03T10:15:30+01:00.
  • OffsetTime: A time with a UTC/Greenwich offset in the ISO-8601 calendar system, like 10:15:30+01:00.
  • Period: A time-based amount based on the date in the ISO-8601 calendar system, like '2 years, 3 months, and 4 days.'
  • Year: A year in the ISO-8601 calendar system, like 2007.
  • YearMonth: A year-month in the ISO-8601 calendar system, like 2007-12.
  • ZonedDateTime: A date and time with a time zone in the ISO-8601 calendar system, like 2007-12-03T10:15:30+01:00 Europe/Paris.
  • ZoneId: A time zone identification, like Europe/Paris.
  • ZoneOffset: A Greenwich/UTC time zone offset, like +02:00.

Using any of them is quite intuitive since they provide static methods to obtain new instances and methods that allow operations with them, always generating a new instance due to the concept of immutability. Let's see some examples:

import java.time.*;

LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = LocalDate.of(2020, 02, 20);
LocalDate localDate3 = LocalDate.parse("2020-02-20");

DayOfWeek dow = localDate1.getDayOfWeek();
int dom = localDate1.getDayOfMonth();

LocalDate localDate4 = localDate1.plusDays(3);
...

The query and operation methods are strongly unified among different objects in the package, making it tremendously easy to incorporate and operate with any of them. Tasks that were cumbersome with the obsolete API are reduced to a few lines with the new one, gaining confidence and reducing errors.

Finally, the new API incorporates a new formatter, this time reusable and thread-safe, allowing the reuse of the instance for different constructions or parallel formatting. This new formatter is located in the class java.time.format.DateTimeFormatter, and its construction follows the rule of static methods:

import java.time.*;
import java.time.format.*;

DateTimeFormatter formatter = DateTimeFormatter.of("yyyy-MM-dd");

// de String a LocalDate
LocalDate ld = LocalDate.parse("2020-04-03", formatter);

// de LocalDate a String
String ld_str = ld.format(formatter);

The examples given here are equivalent for objects like ZoneDateTime, with the exception that for those involving Zone information (latitude), it will be necessary to provide a zone id or offset so that Java can construct an instance correctly.

Dates and Times in JDK pre-8

Remember that this is an obsolete API and will be removed. You should only use this if you need to maintain an existing application where changing from the old API to the new one is impractical.

Time management in JDK pre-8 primarily involves the use of the java.util.Date object. It is based on the storage and management of a specific instant based on the milliseconds elapsed since 1970. Therefore, when a date is created based on the system time or manually inputting day, month, year, and time, it converts this set of numbers into milliseconds. Consequently, it can be deduced that adding dates or times associated with different latitudes will pose a problem.

Another issue is that these objects are not immutable, so there may be references to the same instance from different points in the application. If one of them modifies a date, for the other consumer, the date will also have been modified. This behavior is undesirable, especially in concurrent environments with multiple threads running, as it causes problems in debugging and error correction.

In any case, being aware of its limitations, the use of java.util.Date is widespread in many applications due to the extensive time this API has been deployed in different versions until Java 8 appeared. For this reason, it may be necessary to use some of these classes; let's see some examples:

import java.util.Date;
import java.text.SimpleDateFormat;
...

// system date with hour, minutes, and seconds
Date fecha1 = new Date();

// manual date
Date fecha2 = new Date(2020,01,01,12,0,0);

// convert date to string
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String fecha1_str = sdf.format(fecha1);

// convert string to date
Date fecha3 = sdf.parse("31/12/2020");

Through the Date object, we can manipulate the stored date, such as changing minutes or seconds. On the other hand, the class java.text.SimpleDateFormat allows setting a pattern based on the use of specific symbols for dates to convert to or from a character string. The used pattern indicates:

  • dd: Two digits for the day of the month.
  • MM: Two digits for the month number.
    Note: Use uppercase; lowercase refers to minutes.
  • yyyy: Four digits for the year number.

There are many more symbols for dates and times that can be used, especially for hours, minutes, time zones, daylight saving time, etc. It is advisable to review them because the symbols are maintained in the new date API.

Although the Date object is mutable, to alter a date, it is recommended to go through another class that provides more comprehensive management of hour and time adjustments, for example, to consider daylight saving time or standard time. This class is called java.util.Calendar, and its extension corresponding to the most commonly used calendar is java.util.GregorianCalendar. It is preferable to make date modifications using these to avoid potential issues caused by the pure use of milliseconds stored in Date. Let's see some examples:

import java.text.SimpleDateFormat;
import java.util.Calendar;
...

Date date = new Date();

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

// add three months
calendar.add(Calendar.MONTH, 3);

// add 25 hours
calendar.roll(Calendar.HOUR, 25);

Date dateMod = calendar.getTime();

As seen in the given example, a Date object is obtained, having been modified by the intermediate use of Calendar. Calendar has various methods to operate with the date stored inside it; we leave the reference to the Calendar API for more information.

Convert LocalDate to Date and Vice Versa

When designing the Java 8 API, the option for applications to coexist using both APIs was considered, so they slightly modified the objects on both sides to facilitate conversion between them. These methods will disappear when the obsolete API is removed from the JDK.

Normally, to convert objects from one API to the other, it is necessary to go through an instance of Instant, as indicated in the following examples:

Convert LocalDate to Date:

ZoneId defaultZoneId = ZoneId.systemDefault();
LocalDate localDate = LocalDate.of(2016, 8, 19);
Date date = Date
    .from(localDate.atStartOfDay(defaultZoneId).toInstant());

Convert Date to LocalDate:

Date date = new Date();
ZoneId defaultZoneId = ZoneId.systemDefault();
Instant instant = date.toInstant();
LocalDate localDate = instant
    .atZone(defaultZoneId).toLocalDate();

Obviously, with ZonedDateTime, the process will be somewhat simpler, as it already contains time zone information without the need to provide it again.

Conclusions

As can be observed, basic operations on times and dates in Java are quite straightforward using the API incorporated in JDK 8, which has been maintained in subsequent versions. It is the convenient way to manage this type of information in any development or program with Java that you are working on or maintaining. It is recommended, whenever possible, to replace the use of Date with LocalDate or LocalDateTime as appropriate, or even with ZonedDateTime if you maintain or develop a global application.

Optimize your development and programs in Java with the recommendations from Arteco Consulting, SL. Update your practices and adopt LocalDate, LocalDateTime, or ZoneDateTime for efficient temporal information management. Contact us today to take your projects to the next level!

Stay Connected

Newsletter

Stay up to date with the latest in technology and business! Subscribe to our newsletter and receive exclusive updates directly to your inbox.

Online Meeting

Don't miss the opportunity to explore new possibilities. Schedule an online meeting with us today and let's start building the future of your business together!

  • :D
  • :)
  • ;]
  • :0
  • :}
  • ;)
  • :>

Join the Team

We have a large portfolio of trainees who combine their academic training with experience at Arteco, learning firsthand from those on the front lines. We carry out an intensive training program aimed at rapid incorporation into real development teams.

Person running through the desert representing Arteco Consulting's Team Building
  • :)
  • :0
  • :D
  • ;)
  • :]