在Groovy中覆盖Joda DateTime toString

时间:2013-04-24 21:38:10

标签: grails groovy jodatime grails-plugin

所以我在我正在实现的grails项目中使用JodaTime插件,我真的不喜欢它在我执行toString时吐出ISO8601日期格式。我一直在使用toString并从messages文件中传入default.date.format,但这很麻烦。大多数情况我只是想让它自动完成。因此,自然有理由利用Groovy的神奇元编程来覆盖DateTime类上的toString。但唉它不起作用。因此讨论:

http://jira.codehaus.org/browse/GROOVY-4210

所以根据上述讨论,如果我们的类实现了一个实现toString方法的接口,我们需要覆盖接口的元类。查看joda代码库,DateTime实现了ReadableDateTime接口,该接口继承自ReadableInstant,后者是定义方法签名的地方。实际的实现在DateTime的类层次结构中完成了4个类(DateTime继承自BaseDateTime,继承自AbstractDateTime,继承自AbstractInstant,它实现了没有参数的toString)。和我一起到目前为止?

所以理论上这意味着我应该覆盖实际上没有toString签名的ReadableDateTime接口或者实际上具有readableInstant接口的ReadableDateTime接口。以下代码覆盖ReadableDateTime上的toString什么都不做。

ReadableDateTime.metaClass.toString = { ->
    delegate.toString(messageSource.getMessage(
        'default.date.format', null, LCH.getLocale()))
}

然后尝试使用ReadableInstant:

ReadableInstant.metaClass.toString = { ->
    delegate.toString(messageSource.getMessage(
        'default.date.format', null, LCH.getLocale()))
}

也没有DateTime.toString方法的所需结果。但是,这里有一些有趣的影响。看看下面的代码:

def aiToString = AbstractInstant.metaClass.getMetaMethod("toString", [] as Class[])
def adtToString = AbstractDateTime.metaClass.getMetaMethod("toString", [] as Class[])
def bdtToString = BaseDateTime.metaClass.getMetaMethod("toString", [] as Class[])
def dtToString = DateTime.metaClass.getMetaMethod("toString", [] as Class[])

def date = new DateTime()
println "ai: ${aiToString.invoke(date)} "
println "adt: ${adtToString.invoke(date)} "
println "bdt: ${bdtToString.invoke(date)} "
println "dt: ${dtToString.invoke(date)} "

前三种方法显示我的日期格式正好我喜欢它。最后一个仍显示ISO8601格式化日期。我想也许Grails的JodaTime插件可能会覆盖toString,并且它们会为这些接口添加一些方法,但与toString无关。在这一点上,我不知所措。有人有想法吗?

由于

1 个答案:

答案 0 :(得分:0)

您无法覆盖DateTime#toString(),因为DateTime班级为final

public final class DateTime   

但如果您想要其他日期格式,可以使用toString(org.joda.time.format.DateTimeFormatter)
例如

def date = new DateTime();
date.toString(ISODateTimeFormat.basicDate()); // format yyyyMMdd