Bas*_*que 26 datetime parsing date date-formatting java-time
在DateTimeFormatter类文件说,有关当年的格式代码:
你在2004年; 04
y年的2004年; 04
...
年份:字母数决定了使用填充的最小字段宽度.如果字母数是2,则使用减少的两位数形式.对于打印,这将输出最右边的两位数字.对于解析,这将使用2000的基值进行解析,从而产生2000到2099(包括2000和2099)范围内的一年.如果字母数小于4(但不是2),则符号仅按负号年份输出,符合SignStyle.NORMAL.否则,如果超出了焊盘宽度,则根据SignStyle.EXCEEDS_PAD输出符号.
没有提到"时代".
那么究竟是什么这两个代码之间的差异,u对y,year对year-of-era?
什么时候应该使用类似这种模式的东西uuuu-MM-dd以及何时yyyy-MM-dd使用Java中的日期?
似乎那些知道使用的代码编写的示例代码uuuu,但为什么呢?
其他格式化类如遗产SimpleDateFormat只有yyyy,所以我很困惑为什么java.time uuuu为"年代" 带来了这个.
Men*_*ild 23
在java.time-package 的范围内,我们可以说:
它是使用更安全的"U",而不是"Y",因为DateTimeFormatter将在具有时代结合,否则坚持"Y"(=年的时代).所以使用"u"可以避免在严格的格式化/解析中出现一些可能的意外异常.另见这篇SO帖子.与"y"相比,"u"-symbol改进的另一个小问题是打印/解析负的格里高利年(远在过去).
否则,我们可以清楚地说明使用"u"而不是"y"打破了Java编程中的长期习惯.直觉上也不清楚"u"表示任何一种年份,因为a)英文单词"year"的第一个字母与此符号不一致b)SimpleDateFormat因为Java-以来已将"u"用于不同的目的7(ISO-day-of-week).确保混乱 - 永远?
我们还应该看到,如果我们考虑历史日期,在ISO的背景下使用时代(符号"G")通常是危险的.如果"G"与"u"一起使用,则两个字段彼此无关.如果"G"与"y"一起使用,那么格式化程序就会满意,但是当历史日期要求不同的日历和日期处理时,仍会使用预知的格里高利历.
在开发和集成JSR-310(java.time-packages)时,设计人员决定使用CLDR/LDML-spec作为模式符号的基础DateTimeFormatter.符号"u"已经在CLDR中定义为普通的格里高利年,所以这个意思被新的即将到来的JSR-310采用(但不是SimpleDateFormat因为向后兼容的原因).
但是,这个跟随CLDR的决定并不十分一致,因为JSR-310还引入了新的模式符号,这些符号在CLDR中不存在且仍然不存在,请参阅此旧的CLDR票证.建议的符号"I"由CLDR改为"VV",最后被JSR-310取代,包括新的符号"x"和"X".但是CLDR中仍然不存在"n"和"N",并且由于这个旧票据已经关闭,所以如果CLDR在JSR-310的意义上支持它,则根本不清楚.此外,票证没有提到符号"p"(JSR-310中的填充指令,但未在CLDR中定义).因此,我们在不同的库和语言之间的模式定义之间仍然没有完全一致.
而关于"y":我们也不应忽视CLDR将这一年与至少某种混合的朱利安/格里高利年联系在一起的事实,而不是像JSR-310一样将这个年代与格雷戈里年联系起来(留下奇怪之处)消极年份除外).因此,CLDR和JSR-310之间也没有完美的协议.
And*_*eas 19
在Javadoc节模式用于格式化和解析为DateTimeFormatter它列出了以下3个相关的符号:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
Run Code Online (Sandbox Code Playgroud)
仅作比较,这些其他符号很容易理解:
D day-of-year number 189
d day-of-month number 10
E day-of-week text Tue; Tuesday; T
Run Code Online (Sandbox Code Playgroud)
的day-of-year,day-of-month和day-of-week显然是当天在给定范围(年,月,周)内.
因此,year-of-era表示给定范围(时代)内的年份,并且正上方era显示的是示例值AD(当然是其他值BC).
year是签署的年份,年份0是1 BC,年份-1是2 BC等等.
MMMM d, y GG)MMMM d, u)当然,区别仅在于年份是零还是负面,而且由于这种情况很少见,大多数人都不关心,即使他们应该这样做.
结论:如果你使用y你也应该使用G.由于G很少使用,因此正确的年份符号u不是y,否则非正年将显示不正确.
这被称为防御性编程:
防御性编程是一种防御性设计,旨在确保在不可预见的情况下软件的持续功能.
注意DateTimeFormatter与SimpleDateFormat以下内容一致:
Letter Date or Time Component Presentation Examples
------ ---------------------- ------------ --------
G Era designator Text AD
y Year Year 1996; 96
Run Code Online (Sandbox Code Playgroud)
负面年份一直是一个问题,他们现在通过添加修复它u.
yyyyor uuuu(或使用yy或uu2 位数年份)都没有区别。另外两个答案已经很好地展示了如何u和y工作的事实,但我仍然觉得缺少一些东西,所以我贡献了稍微更多基于意见的答案。
假设您不希望在格式化 1 CE 前一年,您能做的最好的事情就是检查这个假设并在它中断时做出适当的反应。例如,根据情况和要求,您可能会打印错误消息或抛出异常。一个非常软故障路径可能是使用带有图案y(时代年),G在此情况下(时代)和图案,无论是u或y正常,当今时代情况。请注意,如果您正在打印当前日期或程序编译日期,您可以确定它是在公共时代,并且可以选择跳过检查。
在许多(大多数?)情况下,解析也意味着验证意味着您无法保证输入字符串的外观。通常它来自用户或另一个系统。一个例子:一个日期字符串是 2018-09-29。如果字符串包含年份为 0 或负数(例如,或),则在uuuu和之间的选择yyyy应该取决于您想要发生的情况。假设这将是一个错误,那么直接的答案是:使用以便在这种情况下抛出异常。更精细:使用并在解析后执行解析日期的范围检查。后一种方法允许更精细的验证和在验证错误的情况下更好的错误消息。0000-08-17-012-11-13yyyyuuuu
特殊情况(Meno Hochschild 已经提到):如果您的格式化程序使用严格的解析器样式并且包含ywithout G,则解析将始终失败,因为严格来说,没有时代的时代是不明确的:1950 可能意味着公元 1950 年或公元前 1950 年(公元前 1950 年)。因此,在这种情况下,您需要u(或提供默认时代,这可以通过DateTimeFormatterBuilder)。
明确范围检查您的日期,特别是您的年份,比依赖于uuuu和yyyy捕捉意外的早期年份之间的选择要好。
| 归档时间: |
|
| 查看次数: |
8163 次 |
| 最近记录: |