SimpleDateFormat:不一致的模式字母

时间:2014-07-02 08:01:18

标签: java simpledateformat

最近我查看了SimpleDateFormat的文档,并注意到(在我看来)它们如何处理解析字母的一些不一致。

例如,看看这些表示:

M: Month in year
D: Day in year
d: Day in month

“x in year”是比“x in month”更大的时间跨度,因此具有大写字母,所以这对我来说非常有意义。

但是有

w: Week in year
W: Week in month

在这里,字母被交换,这在我看来是完全违反直觉的。似乎这两者应该是相反的,以符合上面提到的“模式”。

另一个例子是不同的小时表示:

H: Hour in day (0-23)
k: Hour in day (1-24)
K: Hour in am/pm (0-11)
h: Hour in am/pm (1-12)

我有点理解。以0开头的小写字母,以1开头的小写字母。 在这里,两个小写字母都应该交换,因为不应该相同的字母属于同一个类别吗? (H/h表示一天中的小时,K/k表示上午/下午的小时数

所以我的问题是这样的:这种看似反直觉的表现背后有原因吗?

我能想到的唯一原因是,由于向下兼容性,以后添加了一些这些模式字母并且它们无法更改已存在的模式字母。但除此之外,它对我来说没有多大意义。

1 个答案:

答案 0 :(得分:2)

引用:

  

“我能想到的唯一原因是,其中一些模式   在以后添加了字母,他们无法改变   已存在的,因为向下兼容。“

你的怀疑是正确的。但你不能(仅)责怪Sun各自的Oracle设计师。他们刚刚取代了最初来自Taligent(现在合并到IBM)的所有东西。 IBM本身是定义CLDR-standard的Unicode联盟背后的领先公司之一。在该标准中,所有这些模式符号都被定义(实际上是以完全不一致的方式 - 只能通过历史发展来解释)。

更糟糕的是,CLDR中的不一致并没有停止:最近我们除了SHORT,LONG等之外还有一个NARROW变体。这意味着如果你想将一个月的短信表示为单个字母,那么你需要指定模式符号MMMMM(5个字母,因为已经为数字短格式保留了一个字母M)。

另一个注意事项:SimpleDateFormat甚至没有严格遵循CLDR。例如,Oracle已经在Java-version 7中将模式符号“u”定义为ISO-Day周数(1 =星期一,...,7 =星期日),尽管CLDR早先已经引入了相同的符号ISO-年。 Java 8再次出现偏差,发明了CLDR中未知的新符号,但尝试更密切地关注CLDR。

我们已经使用模式语言存在显着差异(比较Java-6,Java-7,Java-8,纯CLDR和Joda-Time)。我担心这永远不会停止。