【问题标题】:Does Freemarker have any integration for JodaTime?Freemarker 是否与 JodaTime 有任何集成?
【发布时间】:2011-03-09 20:19:59
【问题描述】:

有没有办法在 Freemarker 中轻松格式化 Joda DateTime 对象?例如对于 Java 日期,我们可以使用 ?string 和其他指令。

我知道我可以调用 toDate 并获取 Java 日期,但我希望有更好的方法。

【问题讨论】:

    标签: datetime freemarker jodatime


    【解决方案1】:

    您应该可以直接从 Freemarker 调用 toString(String pattern) 方法:

    ${dateTime.toString('MM-dd-yy')}

    (未测试)

    【讨论】:

    • 太棒了,我是 Joda 的新手,没有看到这个 API。我认为,从我在 Java Date 世界的过去开始,我就认为这一定很困难。
    【解决方案2】:

    如果您不想在模板上到处乱写toString('MM-dd-yy'),还有一种更简单的方法。

    只需扩展 Freemarker 的 DefaultObjectWrapper,让它开箱即用地理解 Joda Time:

    public class JodaAwareObjectWrapper extends DefaultObjectWrapper {
    
      @Override
      public TemplateModel wrap(final Object obj) throws TemplateModelException {
        if (obj == null) { return super.wrap(obj); }
        if (obj instanceof LocalDate) { return new SimpleDate(((LocalDate) obj).toDate(), TemplateDateModel.DATE); }
        // add support for all desired types here...
        return super.wrap(obj);
      }
    }
    

    并在启动 FreeMarker 引擎时将此对象包装器提供给 FreeMarker 配置

    Configuration config = // ...
    config.setObjectWrapper(new JodaAwareObjectWrapper());
    

    然后您可以在模板中使用 FreeMarkers 标准日期内置插件,例如 ${dateTime?date}

    【讨论】:

    • +1,但更容易写if (obj instanceof LocalDate) { return super.wrap(((LocalDate)obj).toDate()); }。另外,if (obj == null) {...} 行是多余的。
    【解决方案3】:

    我不相信此时 Freemarker 中没有任何针对 JodaTime 的集成。将对象放入模型中进行格式化非常容易,即

    使用 format(String pattern, DateTime dateTime) 方法编写一个类“MyCustomJodaFormatterBean”。将 this 的一个实例放在根目录中。

    root.put("joda", 新 MyCustomJodaFormatterBean());

    然后在freemarker中,

    ${joda.format("MM-dd-yyy", dateTime)}
    

    【讨论】:

      【解决方案4】:

      在解析 FTL 文件期间,freemarker 会构建其内部对象模型。例如 java.util.Date 表达式被包装到 freemarker.template.SimpleDate 中。如果您的模型的表达式值是 org.joda.time.DateTime 类型 - freemarker 未知,它将默认包装到 freemarker.ext.beans.StringModel 中,将您的 DateTime 转换为字符串使用 toString() 方法。

      例如,假设我们在 FTL 表达式中有:

      med.expiryDate?date <= today?date
      

      其中“med.expiryDate”是日期时间类型。 "med.expiryDate" 将被包装到 freemarker.ext.beans.StringModel 中,然后使用 freemarker.template.Configuration dateFormat 解析 "med.expiryDate?date"。如果此 dateFormat 与 DateTime.toString() 的默认格式不同,则可能导致异常。

      要解决此问题,您需要让 Freemarker 了解 DateTime 也是日期,而不是字符串。编写您的自定义对象包装器:

      /**
       * Wrapper to make freemarker identify org.joda.time.DateTime objects as date.
       * User: evvo
       * Date: 5/26/2016
       * Time: 18:21
       */
      public class DateTimeAwareObjectWrapper extends DefaultObjectWrapper {
      
         @Override
         public TemplateModel wrap(Object obj) throws TemplateModelException {
            if (obj instanceof DateTime) {
               return new SimpleDate(((DateTime) obj).toDate(), getDefaultDateType());
            }
            return super.wrap(obj);
         }
      }
      

      并将其设置到 freemarker 配置中

      configuration.setObjectWrapper(new DateTimeAwareObjectWrapper());
      

      经过这样的更改,我相信 ?string 后缀也将适用于 DateTime 表达式。

      【讨论】:

        猜你喜欢
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        • 2021-09-10
        • 2016-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多