FreeMarker日期內建函數

date, time, datetime (當用於日期/時間/日期-時間值時)

這些內建函數用來指定日期變量中的哪些部分被使用:java

  • date:僅日期部分,沒有一天當中的時間部分。程序員

  • time:僅一天當中的時間部分,沒有日期部分。sql

  • datetime:日期和時間都在安全

在最佳狀況下,你不須要使用這些內建函數。不幸的是, 因爲Java平臺上的技術限制,FreeMarker 有時不能發現日期中的哪一部分在使用; 詢問程序員哪些變量會有這個問題。若是 FreeMarker 不得不執行須要這些信息的操做 --好比用文本顯示日期--可是它不知道哪一部分在使用,它會以錯誤來停止運行。 這就是你不得不使用這些內建函數的時候了。好比,假設 openingTime 是一個有這樣問題的變量:併發

<#assign x = openingTime> <#-- no problem can occur here -->
${openingTime?time} <#-- without ?time it would fail -->
<#-- For the sake of better understanding, consider this: -->
<#assign openingTime = openingTime?time>
${openingTime} <#-- this will work now -->

這些內建函數也能夠用來將日期-時間值轉換成日期或時間。例如:ide

Last updated: ${lastUpdated} <#-- assume that lastUpdated is a date-time value -->
Last updated date: ${lastUpdated?date}
Last updated time: ${lastUpdated?time}

將會輸出:函數

Last updated: 04/25/2003 08:00:54 PM
Last updated date: 04/25/2003
Last updated time: 08:00:54 PM

若是 ? 左邊是字符串,那麼這些內建函數 將字符串轉換成日期/時間/日期時間。this

date_if_unknown, time_if_unknown, datetime_if_unknown

Note:spa

該內建函數從 FreeMarker 2.3.21 版本開始存在code

date_if_unknown, time_if_unknown, datetime_if_unknown 內建函數使用一些子類型來標記日期類型的值:日期沒有時間,時間,或日期-時間。 若是變量值已經持有這些信息,那麼內建函數就不會起做用。也就是說, 它不會轉換變量值的子類型,若是它是未知的,則會添加子類型。

iso_...

Note:

這些內建函數從 FreeMarker 2.3.21 版本開始廢棄, 由於 date_formattime_format 和datetime_format 設置理解 "iso" (ISO 8601:2004 格式) 和 "xs" (XML Schema 格式),此外還有 Java SimpleDateFormat 格式。所以默認格式能夠設置爲ISO 8601, 要使用一次ISO格式,可使用 myDate?string.iso

這些內建函數轉換日期,時間或日期-時間值爲字符串,遵循 ISO 8601:2004 "擴展" 格式。

該內建函數有不少表現形式: iso_utc, iso_local, iso_utc_nz, iso_local_nz, iso_utc_m, iso_utc_m_nz,等。 名稱的構成由下列單詞順序組成,每部分由一個 _ 分隔開:

  1. iso (必須的)

  2. 是 utc 或 local 兩者之一 (必須的(除了給定一個參數,這個後面再來講)): 來指定根據UTC或根據當前時區來打印日期/時間/日期-時間。 當前時區是根據 FreeMarker 的設置項 time_zone 來肯定的,它一般是由程序員在模板外配置的(固然它也能夠在模板內設置, 好比使用<#setting time_zone="America/New_York">)。 請注意,若是 FreeMarker 設置項 sql_date_and_time_time_zone 已經設置而且非 null,那麼對於 java.sql.Date 和 java.sql.Time 值(也就是經過SQL從數據中得到的僅日期值和僅時間值) local的時區值將會替代 time_zone 設置的值。

  3. hm 或 ms(可選的):時間部分的精度。 當忽略的時候,就默認設置到秒的精度(好比12:30:18)。 h 表示小時的精度(好比 12), m表示分鐘的精度(好比 12:30), ms 就表示毫秒的精度(12:30:18.25,這裏表示250毫秒)。 要注意當使用 ms 時,毫秒會顯示爲百分制的形式 (遵循標準)並且不會去尾到 0 秒。所以, 若是毫秒的部分變成 0 的話,整個的毫秒的部分就會被忽略掉了。 同時也要注意毫秒的部分是由一個點來分隔的,而不是逗號 (遵循Web約定和XML Schema的日期/時間格式)。

  4. nz (可選的): nz (好比在 ${foo?utc_local_nz} 中) 表明 "沒有時區",也就意味着時區的偏移量 (好比 +02:00 或者 -04:30 或者 Z)不會顯示出來。若是這部分被忽略了 (好比在 ${foo?utc_local} 中) 那麼時區就會顯示出來, 除了兩種狀況:

    • 若是值是日期(沒有時間部分)值(再說一次,ISO 8901 標準不容許)

    • 若是值是 java.sql.Time 並且 FreeMarker 配置設置項 incompatible_improvements (一般經過 Java代碼 Configuration的構造方法參數設置) 最小是2.3.21。 存儲時間值是不分時區的,只是存儲小時,分鐘,秒和小數秒值, 因此顯示時區就沒什麼意義。

    請注意,從 FreeMarker 2.3.19 版本開始,對於XML Schema 日期/時間/日期時間格式的兼容性,時區偏移量一般包含分鐘。 (若是主要生成XML Schema格式,就使用 xs 格式。)

例如:

<#assign aDateTime = .now>
<#assign aDate = aDateTime?date>
<#assign aTime = aDateTime?time>

Basic formats:
${aDate?iso_utc}
${aTime?iso_utc}
${aDateTime?iso_utc}

Different accuracies:
${aTime?iso_utc_ms}
${aDateTime?iso_utc_m}

Local time zone:
${aDateTime?iso_local}

可能的輸出(基於當前時間和時區):

Basic formats:
2011-05-16
21:32:13Z
2011-05-16T21:32:13Z

Different accuracies:
21:32:13.868Z
2011-05-16T21:32Z

Local time zone:
2011-05-16T23:32:13+02:00

還有另一組 iso_... 內建函數形式, 你可從名稱中以忽略掉 local 或 utc, 可是要指定時區做爲內建函數的參數。例如:

<#assign aDateTime = .now>
${aDateTime?iso("UTC")}
${aDateTime?iso("GMT-02:30")}
${aDateTime?iso("Europe/Rome")}

The usual variations are supported:
${aDateTime?iso_m("GMT+02")}
${aDateTime?iso_m_nz("GMT+02")}
${aDateTime?iso_nz("GMT+02")}

可能的輸出(基於當前時間和時區):

2011-05-16T21:43:58Z
2011-05-16T19:13:58-02:30
2011-05-16T23:43:58+02:00

The usual variations are supported:
2011-05-16T23:43+02:00
2011-05-16T23:43
2011-05-16T23:43:58

若是時區參數不能被解釋,模板處理就會終止併發生錯誤。

參數能夠是 java.util.TimeZone 對象(多是Java方法的返回值, 或者在數據模型中),而不能只是字符串。

string (當用於日期/時間/日期-時間值時)

這個內建函數以指定的格式轉換日期類型到字符串類型。

Note:

應該不多使用這個內建函數,由於日期/時間/日期-時間值的默認格式能夠全局指定 FreeMarker 的date_formattime_format 和 datetime_format 設置。 該內建函數只在指望格式和經常使用格式不一樣的地方使用。在其它地方, 默認格式應該由程序員在模板以外合理地設置。

指望的格式能夠由 ?string.format 或 ?string["format"] (或歷史上等同的, ?string("format")) 來指定。這些都是等同的,除了使用引號格式的,它能夠在 format 中包含任意字符, 好比空格。format 的語法和配置設置項 date_formattime_format 和datetime_format 是同樣的。

例如:若是輸出的本地化設置是美國英語,時區是美國太平洋時區,而且 openingTime 是 java.sql.Time, nextDiscountDay 是 java.sql.Date 而 lastUpdated 是 java.sql.Timestamp 或 java.util.Date 那麼:

${openingTime?string.short}
${openingTime?string.medium}
${openingTime?string.long}
${openingTime?string.full}
${openingTime?string.xs}
${openingTime?string.iso}

${nextDiscountDay?string.short}
${nextDiscountDay?string.medium}
${nextDiscountDay?string.long}
${nextDiscountDay?string.full}
${nextDiscountDay?string.xs}
${nextDiscountDay?string.iso}

${lastUpdated?string.short}
${lastUpdated?string.medium}
${lastUpdated?string.long}
${lastUpdated?string.full}
${lastUpdated?string.medium_short} <#-- medium date, short time -->
${lastUpdated?string.xs}
${lastUpdated?string.iso}

<#-- SimpleDateFormat patterns: -->
${lastUpdated?string["dd.MM.yyyy, HH:mm"]}
${lastUpdated?string["EEEE, MMMM dd, yyyy, hh:mm a '('zzz')'"]}
${lastUpdated?string["EEE, MMM d, ''yy"]}
${lastUpdated?string.yyyy} <#-- Same as ${lastUpdated?string["yyyy"]} -->

<#-- Advanced ISO 8601-related formats: -->
${lastUpdated?string.iso_m_u}
${lastUpdated?string.xs_ms_nz}

將會輸出:

01:45 PM
01:45:09 PM
01:45:09 PM PST
01:45:09 PM PST
13:45:09-08:00
13:45:09-08:00

2/20/07
Apr 20, 2007
April 20, 2007
Friday, April 20, 2007
2007-02-20-08:00
2007-02-20

2/20/07 01:45 PM
Feb 20, 2007 01:45:09 PM
February 20, 2007 01:45:09 PM PST
Friday, February 20, 2007 01:45:09 PM PST
Feb 8, 2003 9:24 PM
2007-02-20T13:45:09-08:00
2007-02-20T13:45:09-08:00

08.04.2003 21:24
Tuesday, April 08, 2003, 09:24 PM (PDT)
Tue, Apr 8, '03
2003

2007-02-20T21:45Z
2007-02-20T13:45:09.000

Warning!

不幸的是,因爲Java平臺的限制,在數據模型中能夠有日期變量, 那裏 FreeMarker 不能決定變量是不是日期(年,月,日),仍是時間 (時,分,秒,毫秒),或者是日期-時間值。這種狀況下,當你編寫如 ${lastUpdated?string.short} 或 ${lastUpdated?string.xs} 時,FreeMarker 不知道如何來顯示日期,也就是說,格式不指定精確的字段去顯示, 或者若是隻是簡單使用 ${lastUpdated}, 那麼模板會停止執行並拋出錯誤。要阻止這些發生,可使用 ?date, ?time 和 ?datetime 內建函數 來幫助 FreeMarker。例如: ${lastUpdated?datetime?string.short}。 要詢問程序員數據模型中肯定的變量是否有這個問題, 或一般使用內建函數 ?date?time 和 ?datetime 來安全處理。

Note:

不需和格式模式使用 ?date?time 或 ?datetime, 好比 "yyyy.MM.dd HH:mm",由於使用這些模式, 就告訴 FreeMarker 來顯示哪部分日期。那麼,FreeMarker 將盲目地相信你, 若是你顯示的部分不存在於變量中,則能夠顯示"干擾"。例如, ${openingTime?string["yyyy-MM-dd hh:mm:ss a"]}, 而 openingTime 中只存儲了時間,將會顯示 1970-01-01 09:24:44 PM

要避免誤解,須要的格式不是字符串,它能夠是變量或任意表達式,好比 "..."?string[myFormat]

相關文章
相關標籤/搜索