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
.
NOTE: 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 }