您使用了错误的格式。你需要yyyy 而不是YYYY。
如果你看看SimpleDateFormat documentation你会发现
y Year
Y Week year
其中“week year”与WEEK_OF_YEAR 循环同步。
现在,为什么 YYYY 会为 2014 年返回 2013 年?
要回答这个问题,您需要了解日历如何确定该周属于某一年。规则很简单:
- 如果这周的最后一个
N 天(通常 N=4 但由使用的日历中的 getMinimalDaysInFirstWeek 确定)属于 XXXX 年,则该周属于 XXXX 年
- 周从
getFirstDayOfWeek 的结果开始。此结果取决于区域设置,但在接下来的示例中,我们将使用星期一作为一周的第一天。
示例 1.
假设一周的第一天是星期一,一周需要属于某年的天数是 4,让我们尝试确定哪一周是 XXXX 年 1 月的第一天,如下所示:
January XXXX
Mon Tue Wed Thu Fri Sat Sun
27 28 29 30 31 1 2
3 4 5 6 7 8 9
...
第一行的周仅包含属于 XXXX 年(到一月)的第一天和第二天的两天
27 28 29 30 31 1 2
^^^ ^^^ //days which belong to January
但这少于下周属于 XXXX 年所需的天数
3 4 5 6 7 8 9
包含属于 XXXX 年的 7 天。由于第一行中的周不属于 XXXX 年第一周 周年 将从 XXXX 年 1 月 3 日开始。这意味着如果我们将值XXXX 解析为YYYY 格式,我们将得到3rd January XXXX。
示例 2。
现在假设 XXXX 年的日历看起来像这样
January XXXX
Mon Tue Wed Thu Fri Sat Sun
30 31 1 2 3 4 5
6 7 8 9 10 11 12
...
正如你在一周中看到的那样
30 31 1 2 3 4 5
它的最后 5 天属于 XXXX 年,比要求的 4 天多
-> 表示本周属于 XXXX 年,
-> 这也是 XXXX 年的第一周
-> 这意味着今年的第一周开始于30 December (XXXX-1)
-> 这最终意味着如果您使用YYYY 格式解析这样的年份,您将获得值 XXXX-1。
示例2实际上是来自2014的情况,这就是为什么将年份解释为2013的原因。
顺便说一句,如果您决定使用带有星期年份的格式来设置月份和日期,您还需要使用特殊格式来描述
所以你必须使用 M 和 d 而不是
w Week in year
u Day number of week (1 = Monday, ..., 7 = Sunday)
(小时、分钟、秒是时间的一部分而不是日期,所以 H m 和 s 可以采用这种格式)
例如
DateFormat format = new SimpleDateFormat("YYYY-ww-uu HH:mm:ss");
Date date = format.parse("2004-53-7 10:10:10");
System.out.println(date);
将被解析为Sun Jan 02 10:10:10 CET 2005