这些内建函数用来指定日期变量中的哪些部分被使用: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
Note:spa
该内建函数从 FreeMarker 2.3.21 版本开始存在code
date_if_unknown
, time_if_unknown
, datetime_if_unknown
内建函数使用一些子类型来标记日期类型的值:日期没有时间,时间,或日期-时间。 若是变量值已经持有这些信息,那么内建函数就不会起做用。也就是说, 它不会转换变量值的子类型,若是它是未知的,则会添加子类型。
Note:
这些内建函数从 FreeMarker 2.3.21 版本开始废弃, 由于 date_format
,time_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
,等。 名称的构成由下列单词顺序组成,每部分由一个 _
分隔开:
iso
(必须的)
是 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
设置的值。
h
,m
或 ms
(可选的):时间部分的精度。 当忽略的时候,就默认设置到秒的精度(好比12:30:18
)。 h
表示小时的精度(好比 12
), m
表示分钟的精度(好比 12:30
), ms
就表示毫秒的精度(12:30:18.25
,这里表示250毫秒)。 要注意当使用 ms
时,毫秒会显示为百分制的形式 (遵循标准)并且不会去尾到 0
秒。所以, 若是毫秒的部分变成 0
的话,整个的毫秒的部分就会被忽略掉了。 同时也要注意毫秒的部分是由一个点来分隔的,而不是逗号 (遵循Web约定和XML Schema的日期/时间格式)。
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方法的返回值, 或者在数据模型中),而不能只是字符串。
这个内建函数以指定的格式转换日期类型到字符串类型。
Note:
应该不多使用这个内建函数,由于日期/时间/日期-时间值的默认格式能够全局指定 FreeMarker 的date_format
,time_format
和 datetime_format
设置。 该内建函数只在指望格式和经常使用格式不一样的地方使用。在其它地方, 默认格式应该由程序员在模板以外合理地设置。
指望的格式能够由 ?string.format
或 ?string["format"]
(或历史上等同的, ?string("format")
) 来指定。这些都是等同的,除了使用引号格式的,它能够在 format
中包含任意字符, 好比空格。format
的语法和配置设置项 date_format
,time_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]
。