Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Java "week year" really work?

This started as a simple error: I had YYYY instead of yyyy in my format string for a SimpleDateFormat object. But I'm totally baffled by the results of my tests with the incorrect format string.

This code:

@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());         } } 

produces this output:

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

I've read the documentation on the 'Y' parameter here: https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html, but I still can't see the logic that's working here. Particularly the last instance: I can kinda-sorta understand how the dates in January (& maybe February) can be translated into December of the previous year, but moving the date of November 29th backwards by 11 months baffles me. And what's so special about December 27th?

Can anyone explain?

MORE INFORMATION

@Jan suggested that relying on the toString() method could be a problem, so I defined a date format to print YYYY MM dd '-' yyyy MM dd in the same code as above. Here is the additional output:

2016 12 27 - 2015 12 27 2016 12 27 - 2015 12 27 2027 12 27 - 2026 12 27 
like image 646
Dave Mulligan Avatar asked Jan 09 '16 09:01

Dave Mulligan


People also ask

What is a week year Java?

In some languages, such as Java, the symbols are case-sensitive. While a lower-case yyyy is the year, an upper-case YYYY is the week year. The current week year is usually the same as the current calendar year.

What is a week Era year?

In a week-based-year, each week belongs to only a single year. Week 1 of a year is the first week that starts on the first day-of-week and has at least the minimum number of days. The first and last weeks of a year may contain days from the previous calendar year or next calendar year respectively.


1 Answers

It's simple: December 27 2015 is day 1 of week 1 of week-year 2016 (and December 27 2026 is day 1 of week 1 of week-year 2027). This can be verified by adding these lines:

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)); 

If a SimpleDateFormat outputs a date it can use all fields: year, month, day, day of week, week of month, week in year, week-year etc.

On parsing, SimpleDateFormat expects a matching set of values: either day, month, year or day of week, week in year, week-year. Since you supplied a week-year but did not supply day of week and week in year, those to values have been assumed as 1.


The actual values depend on your locale:

  • which week of a year is week 1
  • which day is the first day of the week

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

On my system (using de-ch locale, with "EEE MMM dd HH:mm:ss zzz yyyy - YYYY-ww-u" as format) I get

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
like image 166
Thomas Kläger Avatar answered Oct 16 '22 23:10

Thomas Kläger