FreeMarker 中的时区设置不影响所有日期时间

Timezone setting in FreeMarker not affecting all datetimes

您好 — 我在 ClickDimensions 模板中使用 FreeMarker,但在强制日期时间使用正确的时区时遇到了一些问题。我的模板顶部有这个:

<#setting time_zone="Canada/Pacific">

我试了一下,将它设置到不同的区域(例如“America/New_York”),当我调用它时它正确地调整了时间:

${.now}

太好了。 但是...我有一个变量 ('startdate'),它保存从 Microsoft Dynamics 实例中提取的日期时间值。出于某种原因,它认为这是太平洋日期时间(偏移量为 -07:00),但事实并非如此,它是 UTC。

以下是我写的一些例子:

${startdate}
${startdate?datetime("M/d/yyyy h:mm a")}
${startdate?datetime("M/d/yyyy h:mm a")?string.iso_m}
${startdate?datetime("M/d/yyyy h:mm a")?string.iso_m_nz}
${startdate?datetime("M/d/yyyy h:mm a")?string.iso_m_nz_u}

这是我收到的:

第三行揭示了问题——日期时间偏移量不正确。它应该读作 +00:00 而不是 -07:00。

如何更改与日期时间关联的偏移量...?

问题是您解析为日期时间的字符串不包含时区或偏移量。由于 datetime 在技术上是 java.util.Date(不是 java.time.LocalDateTime,它可以很高兴地对时区一无所知),FreeMarker 必须盲目地假设某个时区,这将是当前时区。

至少从 2.3.30 开始,?datetime.

没有“如果解析的字符串不包含该信息,请假定此时区”选项

真正正确的解决方案是将这些日期作为 java.util.Date-s 而不是字符串放入数据模型。理想情况下,将字符串解析为任何对象(在本例中为 java.util.Date)不是模板的职责。

如果您必须在模板内解决这个问题,因为该字符串的格式无论如何都硬连接到模板中,您可以这样做:

<#function parseMsDynDateTime(s)>
  <#return (startdate + " +0000")?datetime("M/d/yyyy h:mm a Z")>
</#function>

然后

${parseMsDynDateTime(startdate)?string.iso_m}