日期/时间转换器

在 JSF 格式的字符串值与 JavaScript™ 日期对象之间进行转换。例如,日期时间转换器可将字符串“February 2, 2005”(它可以是输入字段的值)转换为 JavaScript 日期对象。

实际上,JSF 日期时间转换器是 Java™ SimpleDateFormat 类的 JavaScript 实现。

日期时间转换器可将字符串(通常是输入字段的值)转换为 JavaScript 日期对象,或将相应的日期对象转换为字符串。该转换由描述日期的格式(例如,日期组件的顺序、每个组件的格式以及分隔符等)的 Java 日期格式模式进行控制。

日期转换器使用的格式是“随语言环境而定的”。该格式准确地定义日期组件的顺序,例如,组件是按月-日-年顺序还是按年-月-日顺序来显示。它还准确地定义用作组件之间的分隔符的字符,例如,使用 / 字符来分隔所有组件,或使用一个空格来分隔前两个组件,以及使用逗号-空格来分隔其后的两个组件。日期/时间中使用的所有“单词”都是从本地化字符串文件中获取的,该文件已包含在(或发送至)页面中。页面中的所有转换都将使用相同的单词集,例如,所有转换都将使用法语。当前,不能让一些转换使用一种语言,而让另一些转换使用不同的语言。

为了最大程度地与实际情况相吻合,日期转换器使用 Java DateFormat 类所使用的算法来转换日期/字符串,以使客户端和服务器端转换相同。

此转换器可供其他客户端组件使用,例如,JSFBehaviorValidate、日期时间辅助(日期/时间的键盘辅助)以及客户端数据高速缓存。如果程序员需要将包含已格式化数据的字符串“强制转换”为 JavaScript 日期对象,则也可以直接使用此转换器。

JavaScript 构造函数

hX_5.addConverter("id", new hX_5.DateTimeConverter(attributes)); 其中

id

组件所连接至的 HTML 标记的 ID。

属性

表 1. 日期/时间转换器属性

属性名称

描述

format

转换此值时要使用的 Java 日期时间模式。请参阅下面的内容以了解详细信息。

ICU4J

如果存在且不为 false,则星号和加号将作为模式字符来解析,而辅助分组符号将在该模式中进行解析。

base-2digit-span

对位数为 2 的年份进行解析时,当前日期之前的许多年份将被视为“上个世纪”。例如,如果今年是 2003,范围是 30,则“73”与“99”之间的年份将被视为“1973 到 1999”。注意,按照 Microsoft® 标准,此值是 30,而按照 Java 标准,此值是 80。

first-day-of-week

如果存在,则指定在计算“星期”时要使用星期几。0 表示星期日,1 表示星期一,以此类推。
注: 即使未设置 ICU4J,也应该始终提供此属性,以便可以正确计算“w”和“Y”。

digits

如果提供,则表示 Unicode 字符集中有效零数字(而不是西文字符“0”)的单字符。如果对值进行格式化,则 Unicode 字符集中的此字符和后续 9 个字符将作为“数字”来输出。如果此值是从字符串转换的,则这些字符将解析为数字。这对于非西文数字同样适用,例如,正确的阿拉伯数字和/或印度-阿拉伯数字。值是此字符(以十进制表示)的 Unicode 代码点。例如,阿拉伯数字 0 是十六进制 660,因此在这种情况下,1632 应该是此属性的值。

epoch

要使用的日历/纪元系统。即使未设置 ICU4J,也可以指定此属性。支持下列系统:

(无)

格里高利日历和基督日历(AD/BC)

b

格里高利日历和佛教日历(佛日历)

h

希伯来日历

i

伊斯兰教日历(圣日历)

j

格里高利日历和日本日历(君主日历)

strict

如果为 0(字面值),则对值进行解析时将忽略所有“字面值”,将重新排列所有错误排列的组件,使用当前日期时间提供任何缺少的组件,允许拼写错漏(只要不对其计算产生影响),以及忽略“E”和其他重复组件。

如果为 1(精确),则对值进行解析时将忽略所有“字面值”,使用当前日期时间提供任何缺少的组件,允许拼写错漏(只要不对其计算产生影响),以及忽略“E”和其他重复组件。例如,如果模式为 MMMM dd, yyyy,则用户可以输入“Feb/02/04”,它将被解析为 February 02, 2004。

如果为 2(非常精确),则要求准确匹配,不过长月份名称会“缩短”为最小的唯一字符数目,并忽略“E”和其他重复组件。字面值必须准确匹配。

格式

有关 Java 十进制格式数字模式的更多信息,如果 ICU4J 未启用,则请参阅 http://java.sun.com/j2se/1.4.2/docs/api/java/text/DateFormat.html;如果 ICU4J 已启用,则请参阅 http://icu.sourceforge.net/apiref/icu4j/。对语法进行了概括,模式包含一系列格式化字符,其中每个字符描述在日期/时间中的相应位置所允许使用的内容。基本格式化字符包括:

GGGG

纪元符号,表示为完整字符串,例如,“Heisei”(平成纪元)或“Anno Domini”(公元)。注意,GGGG 的 Java Util 1.4x 实现不能正常工作 - 它显示 AD,而不是 Anno Domini。

GGG, GG, G

纪元符号,表示为短字符串,例如,“A.D”或“Hei”。

yyyy

年份,表示为一个最多带 3 个前导零的四位数字符串,例如,1993。

yyy

如果不是日语,则与 yy 相同。如果是日语,则年份表示为一个最多带 2 个前导零的三位数字符串。

yy

如果不是日语,则年份表示为一个两位数的字符串,例如,93,而不是 1993。输入时将遵循世纪计算规则,请参阅上面的 base-2digit-span。如果是日语,则年份表示为一个最多带一个前导零的字符串,例如,“Heisei 02”。

y

如果不是日语,则与 yy 相同。如果是日语,则年份不带前导零。

IYYYY, YYY, YY, Y

与“y”相同,但与“w”模式字符配合使用。将对年份进行调整以使它对于年份的第一周/最后一周是正确的,例如,Jan 1, 2005 在使用“w YYYY”显示时将变成“53 2004”。

MMMM

月份,表示为完整的字符串,例如,“January”。

MMM

月份,表示为缩写的字符串,例如,“Jan”。注意,在 Java 中,月份几乎始终为三个字符的缩写词。

MM

月份,表示为一个数字,根据需要包括一个前导零,例如,“09”。

M

月份,表示为一个不包括前导零的数字,例如,“9”。

EEEE

星期几,表示为完整的字符串,例如,“Wednesday”。

EEE, EE, E

星期几,表示为缩写的字符串,例如,“Wed”。注意,在 Java 中,星期几通常是三个字符的缩写词。

Ie

星期几,表示为数字。值从 1 开始,且已本地化。例如,如果一周中的第一天是星期二,则星期三将变成“2”。

dd

几号,表示为数字,根据需要包括一个前导零,例如,“04”。

d

几号,表示为一个不包括前导零的数字,例如,“4”。

DDD

一年中的某一天,表示为数字,根据需要包括最多两个前导零,例如,002。

DD

一年中的某一天,表示为数字,根据需要包括最多一个前导零,例如,020。

D

一年中的某一天,表示为数字,不包括前导零,例如,189。

F

一个月中的第几个星期几,表示为数字,例如,2 表示这个月中的第二个星期三。注意:在解析字符串时将忽略 F。

Ig, gg ... gggggggg

... gggggggg 儒略日期,从 January 1, 4713 BC(作为 0 值)算起的某一天。

ww

一年中的某一周,表示为数字,根据需要包括前导零,例如,05。

w

一年中的某一周,表示为数字,不包括前导零,例如,51。

W

一个月中的第几周,表示为数字,例如,2。注意:将字符串转换为日期时将忽略 w 和 W。此外,从日期转换为字符串时,将使用 Java 的规则。在 Java 中,一年中的第一周结束于这一年的第一个星期六,因此第一周可能没有 7 天,而第二周是从第一周之后的星期日开始计算的,后续各周以此类推。

hh

12 小时制中的第几个小时,根据需要包括前导零,例如,06。

h

12 小时制中的第几个小时,不包括前导零,例如,6。

HH

24 小时制中的第几个小时,例如,17,并根据需要包括前导零,例如,07。

H

24 小时制中的第几个小时,不包括前导零,例如,7 和 17。

kk

与 HH 相似,但从 1 算起,即,01-24。

k

与 H 相似,但从 1 算起,即,1-24。

KK

与 hh 相似,但从 1 算起,即,01-12。

K

与 h 相似,但从 1 算起,即,1-12。

mm

分钟,根据需要包括前导零,例如,08。

m

分钟,不包括前导零,例如,8。

ss

秒,根据需要包括前导零,例如,09。

s

秒,不包括前导零,例如,9。

SSS

毫秒,显示全部三个数字。

SS

毫秒,显示前两个数字。

S

毫秒,显示第一个数字。

a

AM/PM 标记,扩展为语言环境所需的大小。

IA, AA ... AAAAAAAA

一天中的第几毫秒。

z

时区,扩展为语言环境所需的大小。时区的常规格式是 GMT+nn:nn,其中 nn:nn 是与 GMT 的偏移量。对于特定的语言,例如,英语,可能会改用“常见形式的”时区,例如,EST 或 PST。

Iv

不带“夏令时”指示符的时区。该时区不受支持,原因是客户机将始终使用客户机上通常为夏令时的时区来显示时间。

IZ

以 RFC 822 格式来表示的时区。该格式是 +/-nnnn,其中 nn:nn 是与 GMT 的偏移量。

zzzz

“长格式”的时区。该时区不受支持,原因是无法对其进行解析。

o

一个月中的第几天。它不受支持,原因是无法对其进行本地化。

Iu

ICU4J 加长年份。它不受支持,原因是它对 hxclient 所支持的年份似乎毫无意义。

'

使用单引号将与符号相冲突的文字文本括起。

''

使用两个单引号来指定一个内容为单引号的文字字符。

注: 对于只能表示数字的格式字符,例如,F 或 S,Java 允许使用更多字符,其位数可大于该字符所表示的最大值的位数。例如,FF 是合法的,虽然最大值是 5,SSSS 也是合法的,虽然最大值是 999。在这种情况下,Java 将使用前导零来填充值的左边。日期转换器对此不提供任何支持。

通过将上面的字符组装在一个字符串中来构造格式,上面的每个字符在该模式中最多只能出现一次。在格式字符串中遇到的、不属于上面的格式化字符的任何字符都将作为“定界符”(文字文本)来处理。例如,在格式字符串“MM/dd/yyyy”中,斜杠将被作为字面值来处理。必须注意,不要在无意中将格式化字符包含在文字文本中。某些格式化字符比较费解,许多用户可能不知道它们是否为格式化字符。对于可能与格式字符串字符相冲突的任何文本,请使用单引号将其括起。例如,“hh o'' clock”将不会返回“12 o'clock”,相反,由于“o”是格式字符,它将返回“12 12th' cl12thck”。如果字母字符包含在格式中,而该字符不是格式字符并且未使用引号括起,则 Java 可能会抛出异常,但它不会对所有非格式字符的字母字符都抛出异常。

在构造模式以用于将字符串转换为日期对象时,必须注意确保提供了足够的组件,以使字符串可以被明确解释。例如,如果您包含一个“z”(时区),则应该在格式中包含一个“日期”,这是因为如果不知道日期,则将无法解释时区。如果格式中没有日期,则将缺省使用今天的日期。

必须注意,打开 ICU4J 将更改现有模式的解释方式。例如,如果 ICU4J 是关闭的,则对值“Jan 1, 2005”应用模式“Y: yyyy”后,此值将显示为“Y: 2005”。如果 ICU4J 是打开的,则值将显示为“04: 2005”。在 ICU4J 关闭时,“Y”不是模式字符,因此它被视为一个字面值。在 ICU4J 打开时,它是模式字符。

API 调用

表 2. 日期时间转换器 API 调用

API 调用

描述

number = stringToValue(string)

将字符串转换为 JavaScript 数字对象。失败时返回 NULL。

string = valueToString(date)

将 JavaScript 日期对象转换为字符串。失败时返回 NULL。

string = lastError()

如果转换失败,则将失败原因作为本地化字符串返回。

object = setAttribute(attribute)

设置属性,或如果以前已设置属性,则更改其值。

string = getAttribute(attribute-name)

检索属性的当前值。

局限性

在 Java 中,对日期时间对象进行处理以及转换为这些对象或从这些对象转换时,存在许多问题/局限性。JavaScript 转换器也存在同样的问题/局限性。本文档中未对所有问题进行详尽描述。以下列表描述了其中一些较为重要的局限性和问题。

示例代码

将输入字段的值转换为 JavaScript 日期,然后给该日期加一并再次存储到结果。

// Construct the converter with a format of MMMM dd, yyyy
hX.addConverter("AZ1", new hX.DateTimeConverter("format:MMMM dd, yyyy", "strict:2", 
                  "base-2digit-span:30"));

// Convert the value of an input field from a string formatted using this pattern to a JS date
var x = document.getElementById("form1:text1");
var cvt = hX.getConverterById("AZ1");
var d = cvt.stringToValue(x.value);

// Check for errors
if (d==null)
    alert ("ERROR: " + cvt.lastError());

// Increment the value and put it back
else {
    d.setDate(d.getDate()+1);
    x.value = cvt.valueToString(d);
}
相关任务
将输入组件添加至 Faces JSP 页面

反馈