这开始是一个简单的错误:我的 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 天)。这可以通过添加这些行来验证:
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
需要一组匹配的值:日、月、年或 星期几、一年中的一周、一周年。由于您提供了一年中的一周,但没有提供一年中的星期几和星期,因此这些 to 值已假定为 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
关于java - Java "week year"究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34691582/