我在尝试使用 Freemarker 模板以所需格式显示日期时遇到一些麻烦。
我将带有日期信息的点存储在通过 FME 进程以 ISO 格式 (%Y-%m-%d) 写入的 PostGIS 数据库中,以便在具有 GeoServer 的启用时间的 WMS 中使用它们。
调用 GetFeatureInfo 时,日期显示格式为 10/4/12 12:00 AM,实际应为 2012-10-04。我们已经将服务器设置更改为 -Dorg.geotools.localDateTimeHandling=true -Duser.country=DE -Duser.timezone=GMT -Duser.language=de。
由于这没有给出预期的结果,我们尝试使用 Freemarker 模板。这个想法是检查日期格式的属性并相应地设置它们的格式。不知何故,我无法让它发挥作用。我试过这个:
<#if attribute.is_unknown_date_like>
${attribute.value?string("YYYY-MM-DD")}
<#else>
${attribute.value}
</#if>
我在条件开始的行收到一条错误消息:
freemarker.core.ParseException
我怎样才能使这个条件语句起作用?
@ddekany,你是对的,我很抱歉。未来我会牢记这一点!
所以我尝试了你的建议,如上所述,使用
?
仍然会返回错误消息,但它变得更加重要。
2020-07-01 08:19:02,521 ERROR [geoserver.ows] - freemarker.core.ParseException: Error on line 29, column 46, in template content.ftl Found is_date_like, expecting one of: is_directive, parent, js_string, j_string, uncap_first, is_transform, number, is_hash, trim, children, has_content, iso_ms, xml, iso_utc, byte, double, left_pad, matches, capitalize, number_to_datetime, contains, size, iso_local_h_nz, iso_utc_ms, iso_local_m_nz, is_collection, long, default, iso_utc_h_nz, iso_local_ms, is_boolean, last_index_of, c, iso_utc_m_nz, is_macro, rtf, iso_utc_nz, upper_case, node_name, reverse, cap_first, url, is_hash_ex, iso_nz, is_enumerable, exists, number_to_date, first, iso_local, date, iso, replace, float, right_pad, datetime, node_type, split, iso_ms_nz, number_to_time, is_sequence, iso_utc_m, html, ancestors, iso_utc_h, iso_local_ms_nz, new, last, sort, eval, lower_case, web_safe, is_date, is_string, iso_local_nz, word_list, seq_last_index_of, node_namespace, string, keys, iso_m_nz, values, seq_index_of, chunk, sort_by, iso_m, starts_with, substring, index_of, iso_h, root, floor, iso_h_nz, ceiling, if_exists, chop_linebreak, iso_local_h, length, is_indexable, groups, is_node, iso_local_m, int, iso_utc_ms_nz, xhtml, ends_with, round, interpret, is_method, namespace, short, seq_contains, time, is_number in content.ftl
所以,问题似乎出在内置内部。正如错误消息中的陈述,Freemarker 期望使用
is_date
而不是 is_date_like
,尽管 Freemarker 文档中指出应该使用 is_date_like
而不是 is_date
link。所以我尝试了你的建议 is_date
。
现在不再出现错误消息,但日期格式没有改变。
更新:添加了对
#else
分支的解析等
如果您不知道
attribute.value
是 java.lang.String
还是 java.util.Date
,您可以这样做:
<#if attribute.value?is_date_like>
${attribute.value?date?string.iso}
<#else>
${attribute.value?date("M/d/yy hh:mm a")?string.iso}
</#if>
如果您知道
attribute.value
的类型,那么您只需执行 #if
或 #else
内部的操作即可。
如果您使用的是 FreeMarker 的旧版本,则必须使用
?string.iso
,而不是 ?string("yyyy-MM-dd")
。另外,?is_date_like
可能还不可用,你必须使用attribute.value?is_unknown_date_like || attribute.value?is_datetime || attribute.value?is_date
。
顺便说一句,如果您通常以 ISO 格式输出日期/时间值,那么应该将
date_format
/time_format
/datetime_format
配置设置设置为 iso
,然后您可以省略 ?string.iso
。 (或者,这些也可以在模板中设置,如<#setting date_format='iso'>
等)