为什么Java的SimpleDateFormat解析这个

发布于 2024-10-30 09:24:39 字数 147 浏览 6 评论 0原文

您好,我使用自定义格式字符串设置了一个简单的日期格式: MMddyy

和我给它提供以下值来解析: 4 1 01

我认为它不应该解析这个,因为有空格,但简单日期格式返回日期

4 月 4 日 0001AD

有什么想法吗?

Hi I've got a simple date format set up with a custom format string:
MMddyy

and I give it the following value to parse:
4 1 01

I don't think it should parse this because of the spaces but the Simple Date Format is returning the date

April 4th 0001AD

any ideas why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

电影里的梦 2024-11-06 09:24:39

这是预期的行为 - 您告诉 DateFormat 对象需要一个日期的 6 个字符的字符串表示形式,这就是您传入的内容。空格被解析正常。但是,如果您使用“4x1x01”,则会出现错误。请注意,解析时,leniency 默认为 true,例如

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("4 1 01"); // runs successfully (as you know)

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("41 01"); // 5 character String - runs successfully

DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("41 01"); // 5 character String - causes exception

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("999999"); // 6 character String - runs successfully

DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("999999"); // 6 character String - causes exception

,当 leniency 设置为 true(默认行为)时,解析会努力破译无效输入,例如,31 天的月份的第 35 天将成为下个月的第 4 天。

This is expected behaviour - you are telling the DateFormat object to expect a 6 character String representation of a date and that is what you passed in. Spaces are parsed OK. However, if you used "4x1x01" you would get an error. Note that when parsing, leniency defaults to true e.g.

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("4 1 01"); // runs successfully (as you know)

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("41 01"); // 5 character String - runs successfully

DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("41 01"); // 5 character String - causes exception

DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("999999"); // 6 character String - runs successfully

DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("999999"); // 6 character String - causes exception

When leniency is set to true (the default behaviour), the parse makes an effort to decipher invalid input e.g. the 35th day of a 31 day month becomes the 4th day of the next month.

放肆 2024-11-06 09:24:39

对于解析,模式的大小(重复字符的数量)不是相应文本的预期大小。从 javadoc 中,对于不同的相关表示类型:

  • 数字:对于解析,模式字母的数量将被忽略,除非需要分隔两个相邻字段。
  • 年份:在解析过程中,只有由恰好两位数字 [...] 组成的字符串才会被解析为默认世纪。 任何其他数字字符串,例如一位数字字符串、三位或更多数字字符串或并非全是数字的两位数字字符串(例如“-1”),均按字面解释。因此,使用相同的模式解析“01/02/3”或“01/02/003”
  • 月份:如果模式字母的数量为 3 个或更多,则将月份解释为文本;否则,它被解释为数字。

空格会导致解析器停止解析实际的字段(尾随空格对于数字无效)并从下一个字段开始。由于该模式在这两个字段之间没有空格,因此它不会被消耗,并且是第二个字段的一部分(前导空格有效)。因此得到的年份不是“恰好两位数”,并且不会被解析为默认世纪。

解析测试(lenient 设置为 false):

FORMAT   TEXT     RESULT (ISO yyyy-MM-dd)
-------------------------------------------------
dddyy    01011    2011-01-10  
dddyy    10 11    0011-01-10  (year is 3 chars: " 11")
dddyy    10 1     0001-01-10  (year is 2 char but not 2 digits: " 1")

dddy     01011    2011-01-10  ("y" same as "yy")

dd yy    10 11    2011-01-10  (ok, whitespace is consumed, year: "11")

d/y      3/4      0004-01-03  (year is not 2 digits)
d/y      3/04     2004-01-03  

M/d/y    4/6/11   2011-04-06

for parsing the size of a pattern (number of repeated characters) is not the expected size of the corresponding text. From the javadoc, for the different relevant presentation types:

  • Number: For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.
  • Year: During parsing, only strings consisting of exactly two digits […] will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern
  • Month: If the number of pattern letters is 3 or more, the month is interpreted as text; otherwise, it is interpreted as a number.

The whitespace causes the parser to stop parsing the actual field (trailing spaces are not valid for numbers) and start with the next one. Since the pattern does not have a space between these two fields, it is not consumed and is part of the second field (leading spaces are valid). So the year got is not "exactly two digits" and will not be parsed into the default century.

Parsing tests (lenient set to false):

FORMAT   TEXT     RESULT (ISO yyyy-MM-dd)
-------------------------------------------------
dddyy    01011    2011-01-10  
dddyy    10 11    0011-01-10  (year is 3 chars: " 11")
dddyy    10 1     0001-01-10  (year is 2 char but not 2 digits: " 1")

dddy     01011    2011-01-10  ("y" same as "yy")

dd yy    10 11    2011-01-10  (ok, whitespace is consumed, year: "11")

d/y      3/4      0004-01-03  (year is not 2 digits)
d/y      3/04     2004-01-03  

M/d/y    4/6/11   2011-04-06
ゃ懵逼小萝莉 2024-11-06 09:24:39

2 位数字年份不明确 - 因此假设 0001 - 以 01 结束的第一年。您可以转换为 4 位数字年份 - 也许使用字符串操作吗?

The 2 digit year is ambiguous - and it is therefore assuming 0001 - the first year that would have ended in 01. Can you convert to 4 digit years - maybe using String manipulation?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文