Java“周年”如何真正起作用?

这开始是一个简单的错误:我在SimpleDateFormat对象的格式字符串中使用了YYYY而不是yyyy 。 但是我对使用错误格式字符串的测试结果感到困惑。

这段代码:

 @Test public void whatTheHell() { try { SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/YYYY"); Date d1 = sdf.parse("01/07/2016"); Date d2 = sdf.parse("02/08/2016"); Date d3 = sdf.parse("11/29/2027"); System.out.println(d1.toString()); System.out.println(d2.toString()); System.out.println(d3.toString()); } catch (ParseException pe) { fail("ParseException: " + pe.getMessage()); } } 

产生这个输出:

 Sun Dec 27 00:00:00 PST 2015 Sun Dec 27 00:00:00 PST 2015 Sun Dec 27 00:00:00 PST 2026 

我在这里阅读了关于’Y’参数的文档: https : //docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html ,但我仍然看不到它的逻辑在这里工作。 特别是最后一个例子:我可以有点理解1月(也许是2月)的日期如何翻译成上一年的12月,但将11月29日的日期向后移动11个月让我感到困惑。 12月27日有什么特别之处?

谁有人解释一下?

更多信息

@Jan建议依赖toString()方法可能会有问题,所以我定义了一个日期格式来打印YYYY MM dd '-' yyyy MM dd与上面相同的代码。 这是额外的输出:

 2016 12 27 - 2015 12 27 2016 12 27 - 2015 12 27 2027 12 27 - 2026 12 27 

这很简单:2015年12月27日是2016年第1周第1天(2026年12月27日是2027年第1周第1天)。 这可以通过添加以下行来validation:

 SimpleDateFormat odf = new SimpleDateFormat("YYYY-ww-u"); System.out.println(odf.format(d1)); System.out.println(odf.format(d2)); System.out.println(odf.format(d3)); 

如果SimpleDateFormat输出日期,它可以使用所有字段:年,月,日,星期几,星期几,星期,星期等。

在解析时, SimpleDateFormat需要一组匹配的值:日,月,年星期,星期,星期和星期。 由于您提供了一周,但没有提供一周中的一周和一周中的一周,因此将这些值假设为1。


实际值取决于您的区域设置:

  • 哪一周哪一周是第1周
  • 哪一天是一周的第一天

(参见https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_and_year )

在我的系统上(使用de-ch语言环境,以“EEE MMM dd HH:mm:ss zzz yyyy – YYYY-ww-u”作为格式)我得到

  Mo Jan 04 00:00:00 MEZ 2016  -  2016-01-1
 Mo Jan 04 00:00:00 MEZ 2016  -  2016-01-1
 Mo Jan 04 00:00:00 MEZ 2027  -  2027-01-1