``````````````````````````yyyy`````TimeTime [英] `uuuu` versus `yyyy` in `DateTimeFormatter` formatting pattern codes in Java?

查看:351
本文介绍了``````````````````````````yyyy`````TimeTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

DateTimeFormatter 类文档说明了其年度的格式代码:


你2004年的一年04



y年份2004年; 04



...



年份:字母数确定最小字段宽度低于该填充使用。如果字母数为2,则使用缩减的两位数形式。对于打印,这将输出最右边的两位数字。对于解析,这将使用基数值2000解析,导致一年在2000到2099之间的范围内。如果字母数小于四(但不是两个),则符号只能按照SignStyle.NORMAL输出为负数。否则,如果超出了垫宽度,则按照SignStyle.EXCEEDS_PAD的方式输出符号。


没有其他提到时代。



那么这两个代码有什么区别, u y 年龄



应该怎样使用这种模式 uuuu-MM-dd ,而当 yyyy-MM-dd 在Java中使用日期的时候?



看起来像那些知道使用 uuuu 的人编写的示例代码,但为什么?



其他格式化类,如旧版 SimpleDateFormat 只有 yyyy ,所以我很困惑为什么java.time为年代带来这个 uuuu

解决方案

java.time -package的范围内,我们可以说:




  • 使用u而不是y更安全,因为 DateTimeFormatter 否则将坚持将一个时代与y结合使用(=年代)。所以使用u将会避免严格格式化/解析中的一些最终意外的异常。另请参阅此 SO-post 。与y相比,u符号改进的另一个小小的事情是打印/解析负的gregorian年份(过去)。


  • 否则我们可以清楚地指出,使用u而不是y的可以打破Java编程中的长期习惯。 u表示任何一年,因为a)英文单词year的第一个字母与此符号不符,b) SimpleDateFormat 自Java-7( ISO-day-number-of-week )。我们还应该看到,在ISO的上下文中使用时代(符号G)的通常是危险的我们考虑历史日期。如果与u一起使用G,则两个字段彼此无关。如果G与y一起使用,那么格式化程序是满足的,但是当历史日期要求不同的日历和日期处理时,仍然使用proleptic gregorian日历。




背景信息:



开发和集成JSR-310( java.time -packages),设计人员决定在 DateTimeFormatter 中使用CLDR / LDML-spec作为模式符号的基础。符号u已经在CLDR中被定义为幼稚的年龄,所以这个含义被采用了新的即将到来的JSR-310(但是由于向后兼容性原因而不是 SimpleDateFormat 但是,这个遵循CLDR的决定并不完全一致,因为JSR-310还引入了CLDR中并没有但仍然不存在的新模式符号,另见这个旧的 CLDR-ticket 。建议的符号I被CLDR更改为VV,最后被JSR-310覆盖,包括新符号x和X。但是,CLDR中还没有n和N,而且由于这张旧机票是关闭的,所以CLDR会在JSR-310意义上支持它是不清楚的。此外,该机票没有提及符号p(JSR-310中的填充指令,但未在CLDR中定义)。 所以我们在不同的图书馆和语言之间的模式定义之间依然没有完美的一致。



关于y:我们也不要忽视事实上,CLDR将这个年代与至少某种混合的朱利安/格里高利时代联系在一起,而不是像JSR-310那样(以消极的年代为奇怪的一面)而与犹太人的年龄一样。所以CLDR和JSR-310之间也没有完美的协议。


The DateTimeFormatter class documentation says about its formatting codes for the year:

u year year 2004; 04

y year-of-era year 2004; 04

Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive. If the count of letters is less than four (but not two), then the sign is only output for negative years as per SignStyle.NORMAL. Otherwise, the sign is output if the pad width is exceeded, as per SignStyle.EXCEEDS_PAD.

No other mention of "era".

So what is the difference between these two codes, u versus y, year versus year-of-era?

When should I use something like this pattern uuuu-MM-dd and when yyyy-MM-dd when working with dates in Java?

Seems that example code written by those in the know use uuuu, but why?

Other formatting classes such as the legacy SimpleDateFormat have only yyyy, so I am confused why java.time brings this uuuu for "year of era".

解决方案

Within the scope of java.time-package, we can say:

  • It is safer to use "u" instead of "y" because DateTimeFormatter will otherwise insist on having an era in combination with "y" (= year-of-era). So using "u" would avoid some eventually unexpected exceptions in strict formatting/parsing. See also this SO-post. Another minor thing which is improved by "u"-symbol compared with "y" is printing/parsing negative gregorian years (in far past).

  • Otherwise we can clearly state that using "u" instead of "y" breaks long-standing habits in Java-programming. It is also not intuitively clear that "u" denotes any kind of year because a) the first letter of the English word "year" is not in agreement with this symbol and b) SimpleDateFormat has used "u" for a different purpose since Java-7 (ISO-day-number-of-week). Confusion is guaranteed - for ever?

  • We should also see that using eras (symbol "G") in context of ISO is in general dangerous if we consider historic dates. If "G" is used with "u" then both fields are unrelated to each other. And if "G" is used with "y" then the formatter is satisfied but still uses proleptic gregorian calendar when the historic date mandates different calendars and date-handling.

Background information:

When developing and integrating the JSR-310 (java.time-packages) the designers decided to use CLDR/LDML-spec as the base of pattern symbols in DateTimeFormatter. The symbol "u" was already defined in CLDR as proleptic gregorian year, so this meaning was adopted to new upcoming JSR-310 (but not to SimpleDateFormat because of backwards compatibility reasons).

However, this decision to follow CLDR was not quite consistent because JSR-310 had also introduced new pattern symbols which didn't and still don't exist in CLDR, see also this old CLDR-ticket. The suggested symbol "I" was changed by CLDR to "VV" and finally overtaken by JSR-310, including new symbols "x" and "X". But "n" and "N" still don't exist in CLDR, and since this old ticket is closed, it is not clear at all if CLDR will ever support it in the sense of JSR-310. Furthermore, the ticket does not mention the symbol "p" (padding instruction in JSR-310, but not defined in CLDR). So we have still no perfect agreement between pattern definitions across different libraries and languages.

And about "y": We should also not overlook the fact that CLDR associates this year-of-era with at least some kind of mixed Julian/Gregorian year and not with the proleptic gregorian year as JSR-310 does (leaving the oddity of negative years aside). So no perfect agreement between CLDR and JSR-310 here, too.

这篇关于``````````````````````````yyyy`````TimeTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆