The Joda-Time Plugin integrates the
Joda-Time date/time library into Grails. The plugin…
- Bundles the libraries necessary to use Joda Time types as persistent fields on domain classes.
- Provides the ability to bind from form inputs to Joda Time fields on domain or command objects.
- Supports JSON and XML rendering of Joda Time types.
- Provides tag-libs for input and output of Joda Time data.
- Enhances Grails' scaffolding to support domain classes with Joda Time fields.
- Adds compatibility and consistency methods to Joda Time types so that they integrate better with Groovy.
Known Issues
- In Grails 1.1.1 there is an issue with auto-timestamping using Joda Time properties. On save GroovyRuntimeException is thrown with the message @"Could not find matching constructor for: java.lang.Object(java.lang.Long)"@. The workaround is to declare the fields non-lazy (GORM is mistaking them for one-to-one associations and wrapping a lazy proxy around them - see GRAILS-4689), e.g.
DateTime dateCreated
DateTime lastUpdatedstatic mapping = {
dateCreated type: PersistentDateTime, lazy: false
lastUpdated type: PersistentDateTime, lazy: false
}
- It is currently not possible to do certain types of criteria query with DateTime properties mapped using PersistentLocalDateTimeTZ (or any other multi-column Hibernate UserType). Aggregate functions (max, min, avg, count, etc.) in projections will not work on such properties and neither will the 'between' criterion.
Release Notes
1.1
- Adds HTML5 binding and tag libs
1.0
- Adds joda:formatPeriod tag
- Allows joda:inputPattern to accept String attributes for convenience
- Fixes bug with joda:format that meant selected format was never displayed
0.5.1
- Upgrades joda-time-hibernate to version 1.2
- Allows no-selection option to work with StructuredDateTimeEditor
0.5
- Adds JSON and XML rendering support.
- Adds binding and scaffolding support for Duration and Period.
- Fixes compatibility problem with Grails 1.1 and 1.1.1.
0.4.3
- No longer automatically tries to install scaffolding templates (use grails install-joda-time-templates instead).
- list.gsp and show.gsp templates are not used when application's Grails version is 1.2+ as they are not needed.
0.4.2
- No longer tries to reinstall templates that are already installed.
- Adds DateTimeUtils.withCurrentTimestampFixed and withCurrentTImestampOffset
- Supports all Groovy mathematical operators on Joda Seconds, Minutes, Hours, Days, Months, Years, etc. classes.
0.4.1
- Fixes template installation on Windows machines where Ant's patch task does not work.
0.4
- Fixes corrupted template files from previous version.
- Fixes template compatibility with Grails 1.0.4.
0.3
- Adds the dynamic format(String) method on ReadableInstant and ReadablePartial.
- Fixes installation script for Grails 1.0.4.
- Plugin requires Grails 1.0.4 + as earlier versions don't support registering custom editors.
0.2
- Fixes bug where registration of structured date/time editor overrides registration of text -> date/time editor.
0.1
Contact
If you have questions, comments or suggestions please contact me via the
Grails user mailing list or directly at
rob@energizedwork.com.
Please raise bugs against the
Grails-JodaTime component on
JIRA.
Plugin source code is hosted on
GitHubPersistence
To persist Joda Time properties you need to use the Hibernate UserType implementations supplied by the
Joda-Time Hibernate Support library in the mapping block of your class. For example:
import org.joda.time.*
import org.joda.time.contrib.hibernate.*class Person {
String name
LocalDate birthdate
static mapping = {
birthdate type: PersistentLocalDate
}
}This even works with some of the special functionality in Grails. For example fields
dateCreated and
lastUpdated in a Grails domain object will be updated automatically by the framework. Such properties do not have to be
java.util.Date instances the functionality works fine if they are
org.joda.time.DateTime or other types instead.
Multi-column UserTypes
To use multi-column types such as
PersistentDateTimeTZ you need to include explicit mapping of both column names. For example:
import org.joda.time.*
import org.joda.time.contrib.hibernate.*class User {
DateTime registered
mapping {
registered type: PersistentDateTimeTZ, {
column name: "registered_timestamp"
column name: "registered_zone"
}
}
}You can use any name you like for the columns.
It is currently not possible to do certain types of criteria query with DateTime properties mapped using PersistentLocalDateTimeTZ (or any other multi-column Hibernate UserType). Aggregate functions (max, min, avg, count, etc.) in projections will not work on such properties and neither will the 'between' criterion.
Data Binding
The Joda-Time plugin adds automatic binding support for the following types…
Properties can be bound to simple text fields or to picker controls (see below).
Binding text inputs
By default text fields are bound in a locale-sensitive manner (e.g. to enter a LocalDate in the
en_GB locale the format is
dd/MM/yy_, in the _en_US locale the format is
MM/dd/yy and so on). Alternatively formats can be defined per type in config using keys such as
'jodatime.format.org.joda.time.DateTime' and
'jodatime.format.org.joda.time.LocalDate' which is partiularly useful when using rich UI type controls that may require a fixed format.
HTML5 input types
The HTML5 standard supports
several new input types that potentially useful for binding to Joda-Time properties. The input formats for those types are fixed rather than being locale-sensitive as they are designed for picker controls rendered by the browser or JavaScript. If you wish to use HTML5 inputs in your project simply set the config value
'jodatime.format.html5 = true' in
Config.groovy and the correct binding formats will be used.
Any formats configured using 'jodatime.format.<classname>' will override the HTML5 format for that type.
HTML5 input formats
For reference, the formats for the various input types are as follows:
| Input type | Format |
|---|
| month | yyyy-MM |
| week | xxxx-'W'ww |
| date | yyyy-MM-dd |
| time | HH:mm:ss.SSS |
| datetime-local | yyyy-MM-dd'T'HH:mm:ss.SSS |
| datetime | yyyy-MM-dd'T'HH:mm:ss.SSSZZ |
For all types Seconds and milliseconds can be omitted on input but are always rendered on output. The time zone for
datetime inputs can be either the literal
'Z' representing the
UTC time zone or a value such as
+05:30 or _-08:00_
Tag Libs
The plugin makes several new tags available. See the reference section for details.
Scaffolding
The Joda-Time plugin enhances Grails' dynamic scaffolding so it is compatible with domain classes with the following types…
To install scaffolding templates use the command:
grails install-joda-time-templates
Create and edit views use the
joda:dateTimePicker, joda:datePicker, joda:timePicker or
joda:periodPicker (see above) as appropriate. Columns on list views are sortable.
JSON and XML Rendering
The plugin registers JSON and XML converters for…
Integrating With Other Plugins
Grails UI">
The Grails-UI Plugin's datePicker tag works quite well with
Joda-Time types such as
DateTime, LocalDate or
LocalDateTime instances. The tag's
formatString argument can easily be set with
joda:inputPattern (see above). The value attribute needs to be converted to a
java.util.Date instance. Examples of use might be:
A
DateTime property with time input:
<gui:datePicker id="myDateTimeProperty" value="${myInstance?.myDateTimeProperty?.toDate()}" includeTime="true" formatString="${joda.inputPattern()}"/>A
LocalDate property:
<gui:datePicker id="myLocalDateProperty" value="${myInstance?.myLocalDateProperty?.toDateTime()?.toDate()}" formatString="${joda.inputPattern(type: org.joda.time.LocalDate)}"/>