2017-07-18 152 views
3

我使用的是Freemarker版本2.3.20Freemarker在不同時區打印日期

我有其中兩個日期都包含一個數據結構 - 一個在當地時間,一個在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")); 

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())); 

在我的模板我會想到寫這樣的:

Departure (local): ${departureTimeLocal?string['HH:mm']} 
Departure (UTC) : ${departureTimeUtc?string['HH:mm']} 

而作爲一個結果,我想看到:

Departure (local): 20:30 
Departure (UTC) : 18:30 

我看到的目前是:

Departure (local): 20:30 
Departure (UTC) : 20:30 <#-- timestamp interpreted in local time --> 

我也試過了一些東西像:

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

什麼是最好的方式來存檔這樣的東西?

是的我知道:java.util.Date並沒有真正的時區(僅用於打印)而localTime/utcTime.toInstant()都映射到祖魯時間的相同時刻。

+0

一種解決方法是'departureTimeUtc = utcTime.withZoneSameLocal(ZoneId.of(「Europe/Berlin」));' – 2017-07-18 17:40:06

+0

它會給出預期的輸出,@ Hugo,但是我們真的不想要這樣的黑客攻擊有什麼辦法可以拿出更好的東西... –

+1

@ OleV.V。的確,這就是我稱之爲「解決方法」的原因。我不使用freemarker,所以我不知道它是否有一些方法來配置日期格式 – 2017-07-18 19:48:06

回答

3

隨着freemarker的2.3.20,你可以使用iso日期內置:

${departureTimeUtc?time?iso_utc_m_nz} 

這個內置的是,因爲freemarker的2.3.21過時,取而代之的:

${departureTimeUtc?time?string.iso_m_nz_u} 

iso_m_nz_u的含義是:

  • iso:使用ISO 8601:2004格式
  • m:精確到分鐘
  • nz:沒有時區
  • u:使用而不是默認的時區

選項的完整列表,可以發現here UTC。

+0

簡單而簡單,thx:'出發(本地):$ {departureTimeLocal?time?iso_local_m_nz}''出發(UTC):$ {departureTimeUtc?time?iso_utc_m_nz}' – morecore