Why Dec 31 2010 Returns 1 as Week of Year

Why dec 31 2010 returns 1 as week of year?

The definition of Week of Year is Locale dependent.

How it is defined in US is discused in the other posts. For example in Germany (DIN 1355-1 / ISO 8601): the first Week* of Year is the first week with 4 or more days in the new year.

*first day of week is Monday and last day of week is Sunday

And Java’s Calendar pays attention to the locale. For example:

public static void main(String[] args) throws ParseException {

DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date lastDec2010 = sdf.parse("31/12/2010");

Calendar calUs = Calendar.getInstance(Locale.US);
calUs.setTime(lastDec2010);

Calendar calDe = Calendar.getInstance(Locale.GERMAN);
calDe.setTime(lastDec2010);

System.out.println( "us: " + calUs.get( Calendar.WEEK_OF_YEAR ) );
System.out.println( "de: " + calDe.get( Calendar.WEEK_OF_YEAR ) );
}

prints:

us: 1
de: 52

ADDED
For the US (and I can think of that it is the same for Mexico) the 1. Week of Year is the week where the 1. January belongs to. -- So if 1. Januar is a Saturday, then the Friday before (31. Dec) belongs the same week, and in this case this day belongs to the 1. Week of Year 2011.

Understanding java.util.Calendar WEEK_OF_YEAR

From java.util.Calendar javadoc:

First Week


Calendar defines a locale-specific seven day week using two
parameters: the first day of the week and the minimal days in first
week (from 1 to 7). These numbers are taken from the locale resource
data when a Calendar is constructed. They may also be specified
explicitly through the methods for setting their values.

When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields,
Calendar must determine the first week of the month or year as a
reference point. The first week of a month or year is defined as the
earliest seven day period beginning on getFirstDayOfWeek() and
containing at least getMinimalDaysInFirstWeek() days of that month or
year. Weeks numbered ..., -1, 0 precede the first week; weeks numbered
2, 3,... follow it. Note that the normalized numbering returned by
get() may be different. For example, a specific Calendar subclass may
designate the week before week 1 of a year as week n of the previous
year.

So it's locale-specific. In your case, if the week contains days from new year, it is counted as week 1 from the new year.

You can change this behavior by using Calendar#setMinimalDaysInFirstWeek(int).

Explain why Dec 31 2012 is week 53 and not week 1 (ISO-8601)

Not everything uses ISO 8601; there are many differing definitions of "week number". You are correct in your interpretation - 31 Dec 2012 was indeed the start of ISO week 1 of 2013.

Demonstration using GNU's date(1) command on Linux:

$ date +%GW%V -d '2012-12-31'
2013W01

If you want to use the ISO definition in Excel, you have to specify return type 21:

=WEEKNUM("2012-12-31",21)

yields 1.

Get the week of year, with sunday as the first day of the week using java calendar

You have to change minimalDaysInFirstWeek, see Calendar#setMinimalDaysInFirstWeek(int):

Sets what the minimal days required in the first week of the year are; For example, if the first week is defined as one that contains the first day of the first month of a year, call this method with value 1. If it must be a full week, use value 7.

See also GregorianCalendar:

For example, January 1, 1998 is a Thursday. If getFirstDayOfWeek() is MONDAY and getMinimalDaysInFirstWeek() is 4 (ISO 8601 standard compatible setting), then week 1 of 1998 starts on December 29, 1997, and ends on January 4, 1998. The week year is 1998 for the last three days of calendar year 1997. If, however, getFirstDayOfWeek() is SUNDAY, then week 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998; the first three days of 1998 then are part of week 53 of 1997 and their week year is 1997.

But if you code for your financial department, you should rather create your calendar with the right Locale instead of changing some properties, see Calendar#getInstance(Locale):

Gets a calendar using the default time zone and specified locale. The Calendar returned is based on the current time in the default time zone with the given locale.

How to get the YEAR for week of year for a date?

Java 8 or later?

Refer to Basil Bourque's answer to use Java's java.time API.

Otherwise (think twice!) see my original answer to use the obsolete Java API as asked in this question.


Pre Java 8?

calendar.getWeekYear(); returns 2015 for your given example.

See API documentation for GregorianCalendar#getWeekYear() as well as week year.

For reference

Calendar calendar = new GregorianCalendar(Locale.GERMAN);
calendar.set(2016, Calendar.JANUARY, 1, 0, 0, 0);
Date date = calendar.getTime();

int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
int year = calendar.getWeekYear();

System.out.println(date + " is in " + weekOfYear + " of " + year);

returns

Fri Jan 01 00:00:00 CET 2016 is in 53 of 2015

WEEK_OF_YEAR is same for two dates

Move back to starting day of the week I'm getting expected result. In my case Sunday is the starting day of week. So i setted cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY), this resolved my problem.

public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date procDate = sdf.parse("2016-01-01");
Calendar cal = Calendar.getInstance(Locale.UK);
cal.setFirstDayOfWeek(Calendar.SUNDAY);
cal.setTime(procDate);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); //Starting day of week
System.out.println(cal.get(Calendar.WEEK_OF_YEAR) );
System.out.println(cal.get(Calendar.YEAR) );

procDate = sdf.parse("2016-12-27");
cal.setTime(procDate);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); //Starting day of week
System.out.println(cal.get(Calendar.WEEK_OF_YEAR) );
System.out.println(cal.get(Calendar.YEAR) );
}

Output:

52

2015

52

2016

Wrong week of year in Android

This may be Android/Harmony-specific. For example, this works for me with desktop Java:

import java.util.*;

public class Test {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.set(2011, 0, 1, 0, 0, 0);
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR)); // Prints 52
calendar.setMinimalDaysInFirstWeek(1);
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR)); // Prints 1
}
}

Can you confirm that the exact same code (modulo logging options) logs 52 twice on Android?



Related Topics



Leave a reply



Submit