Date and DateTime (Quick Reference)
The preferred date types for dates and timestamps are:
java.time.LocalDate - best practice for dates
org.joda.time.DateTime - best practice for timestamps
java.util.Date - if java.time.LocalDate cannot be used due to historical reasons and backwards compatibility
However various legacy APIs return the dates and timestamps also in the following various data types:
The preferred objects to work with dates and timestamps are java.time.LocalDate and org.joda.time.DateTime.
If you retrieve dates as java.lang.String, java.util.Date, java.sql.Date, java.sql.Timestamp, convert them to java.time.LocalDate and org.joda.time.DateTime right after retrieval and before accessing them.
Read more how certain APIs behave:
- 1 QueryAPI
- 2 Input Builders
- 3 Other Date and DateTime functions
- 3.1 api.targetDate()
- 3.2 api.parseDateOnly(String pattern, String date) (since 16.0)
- 3.3 api.parseDateWithPattern(String pattern, String date)
- 3.4 api.parseDateTime(String pattern, String datetime)
- 3.5 DateTime.toString(String pattern)
- 3.6 Date.getTime()
- 3.7 DateTime.getMillis()
- 3.8 new Date(long millis)
- 3.9 new DateTime(long millis)
- 4 Legacy Querying API
- 5 Legacy Input API
- 6 Other Legacy Date Functions
QueryAPI
QueryAPI returns the dates consistently for both system and configured fields as:
java.time.LocalDate for Date fields
org.joda.time.DateTime for system fields and configured fields of a type Timestamp or DateTime
def qapi = api.queryApi()
def t1 = qapi.tables().products()
qapi.source(t1, [t1.SomeDate, t1.SomeTimestamp, t1.createDate(), t1.lastUpdateDate()])
.stream { it.each {
it.SomeDate.getClass() // => java.time.LocalDate.class
it.SomeTimestamp.getClass() // => org.joda.time.DateTime.class
it.createDate.getClass() // => org.joda.time.DateTime.class
it.lastUpdateDate.getClass() // => org.joda.time.DateTime.class
} }similarly for the Analytics:
def qapi = api.queryApi()
def t1 = qapi.tables().dataSource("SalesTransactions")
qapi.source(t1, [t1.InvoiceDate, t1.lastUpdateDate()])
.stream { it.each {
it.InvoiceDate.getClass() // => java.time.LocalDate.class
it.lastUpdateDate.getClass() // => org.joda.time.DateTime.class
} }Input Builders
The values of the input Map are populated from the incoming JSON payload from the end user as is, meaning with no implicit conversion. So to get an expected type, an explicit conversion is needed.
InputBuilderFactory.createDateUserEntry()
Returns the input.<name> set by end user as java.lang.String, so you should convert the date to java.util.Date using the api.parseDateWithPattern().
if (api.isInputGenerationExecution()) {
return api.inputBuilderFactory()
.createDateUserEntry("DateEntry")
.setLabel("DateEntry")
.getInput()
}
return api.parseDateWithPattern("yyyy-MM-dd", input.DateEntry)InputBuilderFactory.createDateTimeUserEntry()
Returns the input.<name> set by end user as java.lang.String, so you should convert it to org.joda.time.DateTime the using api.parseDateTime().
if (api.isInputGenerationExecution()) {
return api.inputBuilderFactory()
.createDateTimeUserEntry("DateTimeEntry")
.setLabel("DateTimeEntry")
.getInput()
}
return api.parseDateTime("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", input.DateTimeEntry)Other Date and DateTime functions
api.targetDate()
Returns the Target Date parameter set by end user as java.util.Date. Note it can hold hours, minutes and seconds depending on the context.
api.targetDate().getClass() // => java.util.Dateapi.parseDateOnly(String pattern, String date) (since 16.0)
Any date represented as a String can be parsed to java.time.LocalDate using the api.parseDateWithPattern().
api.parseDateWithPattern("yyyy-MM-dd", "2020-07-10").getClass() // => java.time.LocalDateapi.parseDateWithPattern(String pattern, String date)
Any date represented as a String can be parsed to java.util.Date using the api.parseDateWithPattern().
api.parseDateWithPattern("yyyy-MM-dd", "2020-07-10").getClass() // => java.util.Dateapi.parseDateTime(String pattern, String datetime)
Any date represented as a String can be parsed to org.joda.time.DateTime using the api.parseDateTime().
api.parseDateTime("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "2024-02-20T22:33:44.555Z") // => org.joda.time.DateTimeDateTime.toString(String pattern)
org.joda.time.DateTime can be formatted to String using the DateTime.toString().
DateTime.now().toString("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") // => "2025-05-13T08:42:12.590Z"Date.getTime()
Returns the number of milliseconds since epoch from java.util.Date.
new Date().getTime() // => 1747126318578DateTime.getMillis()
Returns the number of milliseconds since epoch from org.joda.time.DateTime.
DateTime.now().getMillis() // => 1747126318578new Date(long millis)
Returns the java.util.Date from the number of milliseconds since epoch.
new Date(1747126318578) // => java.util.Date, 2025-05-13new DateTime(long millis)
Returns the org.joda.time.DateTime from the number of milliseconds since epoch.
new DateTime(1747126318578) // => org.joda.time.DateTime, 2025-05-13T08:51:58.578ZLegacy Querying API
api.find() and api.stream()
When the fields Argument is Provided
If you provide the fields argument, api.find() and api.stream() return the following:
System fields as java.util.Date.
Configured fields of a Date type as java.lang.String.
Configured fields of a Timestamp type as java.lang.String with milliseconds and trailing 'Z' for timezone.
def p = api.find("P", 0, 1, null, ["SomeDate", "SomeTimestamp", "createDate", "lastUpdateDate"])[0]
p.SomeDate.getClass() // => java.lang.String, e.g. "2024-12-10"
p.SomeTimestamp.getClass() // => java.lang.String, e.g. "2024-12-17T07:04:00.000Z"
p.createDate.getClass() // => java.util.Date
p.lastUpdateDate.getClass() // => java.util.DateWhen the fields Argument is not Provided (= get all fields)
If you do not provide the fields argument, api.find() and api.stream() return the following:
System fields as java.lang.String without milliseconds and trailing 'Z' for timezone.
Configured fields of a Date type as java.lang.String.
Configured fields of a Timestamp type as java.lang.String with milliseconds and trailing 'Z' for timezone.
def p = api.find("P")[0]
p.attribute1.getClass() // => java.lang.String, e.g. "2024-12-10"
p.attribute2.getClass() // => java.lang.String, e.g. "2024-12-17T07:04:00.000Z"
p.createDate.getClass() // => java.lang.String, e.g. "2016-04-26T14:42:37"
p.lastUpdateDate.getClass() // => java.lang.String, e.g. "2024-12-03T10:50:37"DatamartContext.executeQuery()
Date fields are returned as java.sql.Date.
TimeStamp fields are returned as org.joda.time.DateTime.
def ctx = api.getDatamartContext()
def ds = ctx.getDataSource("SalesTransactions")
def q1 = ctx.newQuery(ds)
.select("InvoiceDate") // Date field
.select("lastUpdateDate") // DateTime field
def row = ctx.executeQuery(q1)
.getData()
.getRowValues(0)
row.InvoiceDate.getClass() // => java.sql.Date
row.lastUpdateDate.getClass() // => org.joda.time.DateTimeDatamartContext.executeSqlQuery()
Date fields are returned as java.sql.Date.
TimeStamp fields are returned as java.sql.Timestamp.
def ctx = api.getDatamartContext()
def dm1 = ctx.getDataSource("SalesTransactions")
def q1 = ctx.newQuery(dm1)
.select("InvoiceDate") // Date field
.select("lastUpdateDate") // DateTime field
.setMaxRows(10)
def row = ctx.executeSqlQuery("""SELECT * FROM T1""", q1)
.getRowValues(0)
row.invoicedate.getClass() // => java.sql.Date
row.lastupdatedate.getClass() // => java.sql.TimeStampLegacy Input API
api.dateUserEntry() and api.dateTimeUserEntry() for Configurators
api.dateUserEntry("date").getClass() // => java.lang.String
api.dateTimeUserEntry("date").getClass() // => java.lang.Stringapi.dateUserEntry() and api.dateTimeUserEntry() for Data Loads
api.dateUserEntry("date").getClass() // => class java.util.Date
api.dateTimeUserEntry("date").getClass() // => class org.joda.time.DateTimeOther Legacy Date Functions
api.parseDate(String pattern, String date)
Any date represented as a String can be parsed to java.util.Date using the api.parseDate().
api.parseDate("yyyy-MM-dd", "2020-07-10").getClass() // => java.util.DateDate.format(String pattern)
java.util.Date can be formatted to a String using the new Date.format().
new Date().format("yyyy-MM-dd") // => "2025-05-13"Found an issue in documentation? Write to us.