【问题标题】:Overriding Joda DateTime toString in Groovy在 Groovy 中覆盖 Joda DateTime toString
【发布时间】:2013-04-18 15:13:40
【问题描述】:

所以我在我正在实施的 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 无关。在这一点上,我不知所措。有人有想法吗?

谢谢

【问题讨论】:

  • 您使用 DateTime 作为另一个对象中的字段?还是直接返回视图?
  • 我基本上将 DateTime 用于我程序中的任何日期。所以我在域类、表单等上都有它。

标签: grails groovy jodatime grails-plugin


【解决方案1】:

你不能覆盖DateTime#toString(),因为DateTime类是final

public final class DateTime   

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

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

【讨论】:

  • 这是真的吗?我可以向 DateTime 类添加一个新方法,但我似乎无法覆盖 toString 方法?
猜你喜欢
  • 2015-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
相关资源
最近更新 更多