Better structured date editor for Grails
It's really surprising and annoying that the default structured editor for
dates and times in Grails is so limited. It only allows one to edit (or enter)
time information down to the minute. Seconds and smaller are ignored, even
though the editor specifically returns an epoch time in milliseconds with the
getTime()
method! The default editor also only works for java.util.Date
and java.sql.Date
-- not the also common java.sql.Timestamp
.
I've created a new editor that works for all 3 types mentioned and allows one to edit/enter more complete time information, including seconds (yeah!), millisecond or nanosecond, and also allows the use of an "epoch" time field to edit a raw integer.
See the editor code at StructuredDateOrTimestampEditor.java (GitHub) or download StructuredDateOrTimestampEditor.java
I setup the editor in my own registrar class, e.g.
src/groovy/mypackage/CustomPropertyEditorRegistrar.groovy
where I make several editor customizations:
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import java.beans.PropertyEditor;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.math.BigDecimal;
import java.util.Locale;
import edu.ucar.eol.spring.SqlTimestampPropertyEditor;
import edu.ucar.eol.grails.StructuredDateOrTimestampEditor;
public class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(java.sql.Timestamp.class, new StructuredDateOrTimestampEditor());
registry.registerCustomEditor(java.util.Date.class, new StructuredDateOrTimestampEditor());
registry.registerCustomEditor(java.sql.Date.class, new StructuredDateOrTimestampEditor());
}
}
and then register the bean with Spring grails-app/conf/spring/resources.groovy
:
beans = {
CustomPropertyEditorRegistrar(mypackage.CustomPropertyEditorRegistrar)
}
Finally, to make use of it you'll need the proper HTML in your view. I'm also using Joda time, and modified the Grails plugin's taglib at DateTimeTagLib.groovy (GitHub) or download DateTimeTagLib.groovy
It has all worked great so far.
Sorry, I don't have any real tests but here are some things you can try in
your grails shell
:
sed = new net.sinequanon.grails.StructuredDateOrTimestampEditor("yyyy-MM-dd HH:mm:ss.S")
ts = sed.assemble(java.sql.Timestamp, [epoch:'1'])
===> 1970-01-01 00:00:00.001
ts = sed.assemble(java.sql.Timestamp, [:])
===> null
ts = sed.assemble(java.sql.Timestamp, [year:'2014', millisecond:'123'])
===> 2014-01-01 00:00:00.123
ts = sed.assemble(java.sql.Timestamp, [year:'2014', nanosecond:'456'])
===> 2014-01-01 00:00:00.000000456
// nanosecond takes precedence over millisecond
ts = sed.assemble(java.sql.Timestamp, [year:'2014', millisecond:'123', nanosecond:'456'])
===> 2014-01-01 00:00:00.000000456
ts = sed.assemble(java.sql.Timestamp, [year:'2014', epoch:'5', millisecond:'123'])
===> 1970-01-01 00:00:00.005
// epoch is milliseconds and sets the time before nanosecond overwrites the fractional portion
ts = sed.assemble(java.sql.Timestamp, [year:'2014', epoch:'5', nanosecond:'456'])
===> 1970-01-01 00:00:00.000000456