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}
这是我收到的:
- 2019 年 5 月 23 日 4:30 下午
- 2019 年 5 月 23 日4:30:00 点
- 2019-05-23T16:30-07:00
- 2019-05-23T16:30
- 2019-05-23T23:30
第三行揭示了问题——日期时间偏移量不正确。它应该读作 +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}
您好 — 我在 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}
这是我收到的:
- 2019 年 5 月 23 日 4:30 下午
- 2019 年 5 月 23 日4:30:00 点
- 2019-05-23T16:30-07:00
- 2019-05-23T16:30
- 2019-05-23T23:30
第三行揭示了问题——日期时间偏移量不正确。它应该读作 +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}