Freemarker 在不同时区打印日期

mor*_*ore 5 java freemarker date

我正在使用 Freemarker 版本2.3.20

我有一个数据结构,其中包含两个日期 - 一个在本地时间,一个在UTC 时间

// 2017-07-17 18:30 UTC
ZonedDateTime utcTime = ZonedDateTime.of(2017, 7, 17, 18, 30, 0, 0, ZoneId.of("UTC"));
// 2017-07-17 20:30 (+02:00)
ZonedDateTime localTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/Berlin"));
Run Code Online (Sandbox Code Playgroud)

Freemarker 只能处理java.util.Date所以我要交出日期。

Map<String, Object> mapping = new HashMap<String, Object>();
mapping.put("departureTimeLocal", Date.from(localTime.toInstant()));
mapping.put("departureTimeUtc", Date.from(utcTime.toInstant()));
Run Code Online (Sandbox Code Playgroud)

在我的模板中,我希望编写如下内容:

Departure (local): ${departureTimeLocal?string['HH:mm']}
Departure (UTC)  : ${departureTimeUtc?string['HH:mm']}
Run Code Online (Sandbox Code Playgroud)

因此,我希望看到:

Departure (local): 20:30
Departure (UTC)  : 18:30
Run Code Online (Sandbox Code Playgroud)

我目前看到的是:

Departure (local): 20:30
Departure (UTC)  : 20:30    <#-- timestamp interpreted in local time -->
Run Code Online (Sandbox Code Playgroud)

我也试过类似的东西:

Departure (converted): ${(departureTimeLocal?string['yyyy-MM-dd HH:mm'] + ' UTC')?datetime['yyyy-MM-dd HH:mm z']?string['HH:mm']}
--> Departure (converted): 22:30
Run Code Online (Sandbox Code Playgroud)

归档此类内容的最佳方式是什么?

是的,我知道:java.util.Date并没有真正的时区(仅用于打印)并且localTime/utcTime.toInstant()两者都映射到祖鲁时间的相同时刻。

obo*_*ain 4

在 freemarker 2.3.20 中,您可以使用内置的iso日期:

${departureTimeUtc?time?iso_utc_m_nz}
Run Code Online (Sandbox Code Playgroud)

自 freemarker 2.3.21 起,此内置函数已弃用,并替换为:

${departureTimeUtc?time?string.iso_m_nz_u}
Run Code Online (Sandbox Code Playgroud)

的含义iso_m_nz_u是:

  • iso:使用 ISO 8601:2004 格式
  • m:精确到分钟
  • nz:没有时区
  • u:使用 UTC 而不是默认时区

可以在此处找到完整的选项列表。