Reputation: 93
I like to know which week of the month a particular day falls. For example 20-Sep-2012 falls on 4th week of September but the below code displays it as 3 which is not correct. The system is dividing the days by 7 and returning the output and which is not I require. I have searched in Joda API's but not able to find the solution. Please let me know is there any way to figure out the week of a month, a day falls
Calendar ca1 = Calendar.getInstance();
ca1.set(2012,9,20);
int wk=ca1.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month :"+wk);
Upvotes: 8
Views: 26565
Reputation: 11280
I'm very late to this question, but I feel the full answer is missing, which is, that how weeks are interpreted can differ quite a lot depending on the Locale
.
The question seems to need the settings for the US (or a similar Locale
), which uses 1 as minimal days in first week, and Sunday as the first day of the week.
The question, and all the answers take a default Calendar
instance which comes with 4 as minimal days in first week, and Monday as first day of the week.
A simple demo program shows this :
public static void main(String[] args) {
{
System.out.println("--- ISO ---");
Calendar calendar = Calendar.getInstance();
System.out.println("First day of week : " + calendar.getFirstDayOfWeek());
System.out.println("Minimal days in 1st week : " + calendar.getMinimalDaysInFirstWeek());
calendar.set(2012, Calendar.SEPTEMBER, 20);
int wk = calendar.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month : " + wk);
}
{
System.out.println("--- USA ---");
Calendar calendar = Calendar.getInstance(Locale.US);
System.out.println("First day of week : " + calendar.getFirstDayOfWeek());
System.out.println("Minimal days in 1st week : " + calendar.getMinimalDaysInFirstWeek());
calendar.set(2012, Calendar.SEPTEMBER, 20);
int wk = calendar.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month : " + wk);
}
}
And that yields this output :
--- ISO ---
First day of week : 2
Minimal days in 1st week : 4
Week of Month : 3
--- USA ---
First day of week : 1
Minimal days in 1st week : 1
Week of Month : 4
CONCLUSION :
There's no need to manually set the minimal days in first week, or the first day of week. Just make sure you're using the right Locale
.
Extra
Joda time only had support for ISO weeks. Since Java 8 and the new time API you can go about it like this :
LocalDate localDate = LocalDate.of(2012, 9, 20);
TemporalField usWeekOfMonth = WeekFields.of(Locale.US).weekOfMonth();
TemporalField isoWeekOfMonth = WeekFields.ISO.weekOfMonth();
System.out.println("USA week of month " + usWeekOfMonth.getFrom(localDate));
System.out.println("ISO week of month " + isoWeekOfMonth.getFrom(localDate));
Output :
USA week of month 4
ISO week of month 3
And there's even support in the formatter :
DateTimeFormatter usDateTimeFormatter = DateTimeFormatter.ofPattern("W/MM")
.withLocale(Locale.US);
System.out.println("USA formatter : " + usDateTimeFormatter.format(localDate));
DateTimeFormatter isoDateTimeFormatter = DateTimeFormatter.ofPattern("W/MM");
System.out.println("ISO formatter : " + isoDateTimeFormatter.format(localDate));
Output :
USA formatter : 4/09
ISO formatter : 3/09
Upvotes: 2
Reputation: 79085
java.time
In March 2014, Java 8 introduced the modern, java.time
date-time API which supplanted the error-prone legacy java.util
date-time API. Any new code should use the java.time
API.
Also, shown below is a notice on the Joda-Time Home Page:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
ISO-8601 defines the week beginning with Monday. Most of Europe follows this standard for the first day of the week. There is no concept of a partial week in this system. Therefore the first week of September 2012 started on 03-September for the calendars of these countries.
In the US, a week begins on Sunday. It also has a concept of a partial week. Therefore the first week of September 2012 started on 01-September for the US calendar.
Sep 2012 in the US Calendar | Sep 2012 in the UK Calendar
java.time
APIThe simplest solution I can think of is to format the date using DateTimeFormatter.ofPattern("W")
with the applicable Locale
.
Note: You get a String
this way. If you need this value for any calculation, convert it into an int
using Integer.valueOf
.
Demo:
class Main {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("W");
public static void main(String[] args) {
LocalDate date = LocalDate.of(2012, Month.SEPTEMBER, 20);
System.out.println(date.format(FORMATTER.withLocale(Locale.US)));
System.out.println(date.format(FORMATTER.withLocale(Locale.UK)));
}
}
Output:
4
3
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 3
Reputation: 838
For those working with Joda time, this is what I am using:
/**
* For a week starting from Sunday, get the week of the month assuming a
* valid week is any week containing at least one day.
*
* 0=Last,1=First,2=Second...5=Fifth
*/
private int getWeekOfMonth( MutableDateTime calendar )
{
long time = calendar.getMillis();
int dayOfMonth = calendar.getDayOfMonth();
int firstWeekday;
int lastDateOfMonth;
int week;
int weeksInMonth;
calendar.setDayOfMonth( 1 );
firstWeekday = calendar.getDayOfWeek();
if (firstWeekday == 7)
{
firstWeekday = 0;
}
calendar.setHourOfDay( 0 );
calendar.addMonths( 1 );
calendar.addDays( -1 );
lastDateOfMonth = calendar.getDayOfMonth();
weeksInMonth = (int)Math.ceil( 1.0*(lastDateOfMonth + firstWeekday)/7 );
week = (byte)(1 + (dayOfMonth + firstWeekday - 1)/7);
week = (week == weeksInMonth)?0:week;
calendar.setMillis( time );
return week;
}
Upvotes: 0
Reputation: 1
class test {
public static void main(String[] args){
Calendar cal = Calendar.getInstance();
cal.set(2016, Calendar.AUGUST, 01);
printDayOFWeek(cal, Calendar.MONDAY, 5);//prints monday on 5th week
}
}
private static void printDayOFWeek(Calendar cal, int day, int whatweek) {
cal.set(Calendar.DAY_OF_WEEK, day);//day = Mon, tue, wed,..etc
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1); //-1 return last week
Date last = cal.getTime();
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, whatweek);
Date one = cal.getTime();
if(one.before(last) || one.compareTo(last) ==0)
{
System.out.println(whatweek +"WEEK" + cal.getTime());
}
}
Upvotes: -1
Reputation: 46219
This is due to two reasons:
The first one is this (from the API):
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
The default value for this varies (mine was 4), but you can set this to your preferred value with
Calendar.setMinimalDaysInFirstWeek()
The second reason is the one @Timmy brought up in his answer. You need to perform both changes for your code to work. Complete working example:
public static void main(String[] args) {
Calendar ca1 = Calendar.getInstance();
ca1.set(2012, Calendar.SEPTEMBER, 20);
ca1.setMinimalDaysInFirstWeek(1);
int wk = ca1.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month :" + wk);
}
This prints
Week of Month :4
Upvotes: 8
Reputation: 568
To get sure the right month is set try using the month-constants provided by the Calendar-Class.
Upvotes: 1
Reputation: 268
Month is zero-based. So ca1.set(2012,9,20) is actually setting the calendar to October.
Upvotes: 4