1

所以我在我正在实施的 grails 项目中使用 JodaTime 插件,我真的不喜欢它在我执行 toString 时吐出 ISO8601 日期格式。我一直在不断地放入 toString 并从消息文件中传递 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 上覆盖 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)} "

前 3 种方法显示了我希望的日期格式。最后一个仍然显示 ISO8601 格式的日期。我想也许 grails 的 JodaTime 插件可能会覆盖 toString,他们确实向这些接口添加了一些方法,但与 toString 无关。在这一点上,我不知所措。有人有想法吗?

谢谢

4

1 回答 1

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
于 2013-04-27T14:03:53.717 回答