简体   繁体   中英

Overriding Groovy's java.util.Date toString method

I have a Grails (version 2.5.0 ; Groovy version 2.4.3) application where I had a CustomPropertyEditorRegistry to override date formats when using fieldvalue.

I installed ElasticSerach Grails plugin version 0.0.4.4 , after installation I noticed the custom property editor was not working anymore. In an attempt to temporarily work around the problem, I decided to simply override the java.util.Date's toString() method using Groovy's meta programming.

I added this to Bootstrap.groovy:

Date.metaClass.toString = {
   return delegate.format("MM/dd/yyyy HH:mm")
}

However, when I went to the Grails console (using the Grails Console plugin):

new Date("Fri Jun 12 12:36:02 EDT 2015") as String == "Fri Jun 12 12:36:02 EDT 2015"
new Date("Fri Jun 12 12:36:02 EDT 2015").toString() == "06/12/2015 12:36"

println(new Date("Fri Jun 12 12:36:02 EDT 2015")) // prints Fri Jun 12 12:36:02 EDT 2015
println(new Date("Fri Jun 12 12:36:02 EDT 2015").toString()) // prints 06/12/2015 12:36 

Any help figuring out the custom property issue and/or overriding Date toString() would be appreciated. I have opened an issue on the ElasticSearch Grails Plugin GitHub, issue #115 as well

EDIT:

I've performed some more tests with both Grails and Groovy.

I created a new Grails 2.5.0 application with this code in the Bootstrap.groovy:

Date.metaClass.toString = {
    return delegate.format("MM/dd/yyyy HH:mm")
}

and added this to the index.gsp view:

<ul>
    <li>new Date().toString() == ${new Date().toString()}</li>
    <li>new Date() == ${new Date()}</li>
    <li>new Date() as String == ${new Date() as String}</li>
</ul>

/*Output:
new Date().toString() == 06/15/2015 10:32
new Date() == Mon Jun 15 10:32:33 EDT 2015
new Date() as String == Mon Jun 15 10:32:33 EDT 2015
*/

I also launched the groovyConsole with Groovy version 2.4.3 with this code/output:

Date.metaClass.toString = {
    return delegate.format("MM/dd/yyyy HH:mm")
}

println(new Date())
println(new Date() as String)
println(new Date().toString())

/*Output:
06/15/2015 10:38
Mon Jun 15 10:38:12 EDT 2015
Mon Jun 15 10:38:12 EDT 2015
*/

So this does appear to be an inconsistency in Groovy where it is not calling the toString() from the modified metaclass method, unless I'm doing something incorrectly or misunderstanding something.

You said you're using the Groovy console, but you mean you're running grails console , right? BootStrap doesn't run when launching the console, only in run-app and tests. If you run the toString override in the console and then run your sample code it should work fine.

Just a thought about " as String " .. if you redefine asType method:

Date.metaClass.asType = { Class clazz ->
 return "Hello"
}

(new Date()) as String
===> Hello

but still:

new Date()
===> Wed Jul 01 20:12:35 EEST 2015

Since I can't find anything wrong with the overrides and it does work when printing the instance alone new Date() , I believe the issue is that Java is calling the toString() method directly rather than letting Groovy control the method invocation process which would result in executing the asType() and toString() overridden methods. I'm not sure of a clean workaround, and I'm still unsure why the Custom Property Editors stopped working when ElasticSearch plugin was installed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM