You are using wrong format. You need yyyy
instead of YYYY
.
If you take a look at SimpleDateFormat documentation you will find that
y Year
Y Week year
where "week year" is in sync with a WEEK_OF_YEAR cycle.
Now, why YYYY
returns 2013 for year 2014
?
To answer this question you need to understand how calendar determines that week belongs to some year. Rule is quite simple:
- week belongs to year XXXX if last
N
days of this week (usually N=4 but it is determined by getMinimalDaysInFirstWeek
from used Calendar) belongs to year XXXX
- weeks starts at day which is result from
getFirstDayOfWeek
. This result depends on Locale but in next examples we will use Monday as first day of week.
Example 1.
Assuming that first day of week is Monday and days required for week to belong to some year is 4 lets try to determine which week is first in year XXXX for January which looks like this:
January XXXX
Mon Tue Wed Thu Fri Sat Sun
27 28 29 30 31 1 2
3 4 5 6 7 8 9
...
Week from first row contains only two days which belongs to year XXXX (to January), 1st and 2nd
27 28 29 30 31 1 2
^^^ ^^^ //days which belong to January
but this is less than number of days required for this week to belong to XXXX year while next week
3 4 5 6 7 8 9
contains 7 days which belong to XXXX year. Since week in first row doesn't belong to year XXXX first week in week year will start 3 January XXXX. This means that if we parse value XXXX
with format YYYY
we will get 3rd January XXXX
.
Example 2.
Now lets say that calendar for year XXXX looks like this
January XXXX
Mon Tue Wed Thu Fri Sat Sun
30 31 1 2 3 4 5
6 7 8 9 10 11 12
...
As you can see in week
30 31 1 2 3 4 5
its last 5 days belong to year XXXX which is more than required 4 days
-> which means that this week belongs to year XXXX,
-> and it is also first week of XXXX year
-> which means that first week of this year starts at 30 December (XXXX-1)
-> which finally means that if you parse such year using YYYY
format you will get value XXXX-1.
Example 2 is actually situation from year 2014
, which is why year was interpreted as year 2013
.
BTW, if you would decide to use format with week year to set month and day you would also need to use special formats which would describe
- which week of year you want to set
- and which day of week
so instead of M
and d
you would have to use
w Week in year
u Day number of week (1 = Monday, ..., 7 = Sunday)
(hours, minutes, seconds are part of time rather than date so H
m
and s
are fine in this format)
for instance
DateFormat format = new SimpleDateFormat("YYYY-ww-uu HH:mm:ss");
Date date = format.parse("2004-53-7 10:10:10");
System.out.println(date);
which will be parsed to Sun Jan 02 10:10:10 CET 2005