Dates

Use of dates is quite extensive throughout the application’s documentation. They can be tricky to work with, and therefore deserve a separate chapter. This page explains some of the date’s technical details, and how that knowledge applies to practical cases.

Classes

There are two kinds of dates available in Groovy. Their classes are both called Date, but they originate from a different package, namely java.sql and java.util. The application’s data model only uses the former kind. An entity’s date attribute is always a java.sql.Date.

The class java.sql.Date is a subclass of java.util.Date. An instance of a java.sql.Date is a java.util.Date, but not the other way around. Think of it like this: an apple is a subclass of a fruit, so an apple is by definition a fruit, but the fruit is not necessarily an apple.

When working with dates, a date instance is often already at hand, and its exact class is of no further importance. For example, use of claimLine.startDate and person.dateOfBirth for all kinds of purposes, without having to mention their class explicitly:

assert person.dateOfBirth <= claimLine.startDate

The class becomes relevant when a new fixed java.sql.Date instance is required:

def sqlDate = java.sql.Date.valueOf("2018-07-26")

Convert a java.util.Date to a java.sql.Date using the common milliseconds time attribute (more about time below):

def sqlDate = new java.sql.Date(utilDate.time)

Imports

The package names, java.sql and java.util, are fairly short, but names can become quite long. Occurrences of such names throughout dynamic logic can affect readability. Therefore, specify package names once using an import statement at the top of the logic. For example, the following statement allows the SimpleDateFormat class to be used by the subsequent logic, without specifying its package name:

import java.text.SimpleDateFormat

Groovy adds a few hidden default imports, including java.util.Date. Referring simply to the Date class in Groovy yields a java.util.Date.

Explicitly specify whenever a java.sql.Date is required. User can override the default import to java.sql.Date, but simultaneously importing two different classes with the same name is impossible.

Time

As per the official documentation, java.util.Date represents a specific instant in time, with millisecond precision. A Date carries the time of the day besides the year, month, and day. That applies to java.sql.Date as well. In the application’s data model, the time components of a date field are cleared as 00:00:00. That is different for fields with the class java.sql.Timestamp, such as claim.creationDate and ctrClaim.transactionDateTime.

Today

If an instance of the current date is necessary, create a new or empty java.util.Date. This results in a date instance that is set to the current time:

def now = new Date()

Note that the java.util prefix is not required, because of the aforementioned default import. Convert the java.util.Date to create today’s java.sql.Date:

def now = new java.sql.Date(new Date().time)

Comparing

Use the regular comparison-operators to compare dates in Groovy:

assert yesterday < tomorrow

A java.sql.Date is in fact a java.util.Date. User can compare a java.sql.Date to a java.util.Date:

assert claimLine.startDate < new Date()

Dates originating from the application’s data model always have a time component of 00:00:00, while the above newly created one does not. Therefore, those two date are not be equal, even if their year, month, and day are equal. Groovy has provided the clearTime method for this purpose:

assert claimLine.startDate <= new Date().clearTime()

Modification

Adding or subtracting a certain number of days is simple in Groovy:

def tomorrow = today + 1

More complex date modification requires more complex code. One possibility is by Java’s Calendar functionality:

def calendar = Calendar.getInstance()
calendar.setTime(claimLine.startDate)
calendar.add(Calendar.MONTH, 6)
calendar.add(Calendar.DATE, -1)
def date = calendar.getTime()

Another possibility is by using Groovy’s TimeCategory structure:

use (groovy.time.TimeCategory) {
  def date = claimLine.startDate + 6.months - 1.day
}