user1686408
user1686408

Reputation: 93

How to find week of the month

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

Answers (7)

bowmore
bowmore

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

Arvind Kumar Avinash
Arvind Kumar Avinash

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.

The first day of a week is locale-sensitive

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

Solution using java.time API

The 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

Try it on Ideone

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 3

Jason K.
Jason K.

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

kondra p
kondra p

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

Keppil
Keppil

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

AnarchoEnte
AnarchoEnte

Reputation: 568

To get sure the right month is set try using the month-constants provided by the Calendar-Class.

Upvotes: 1

Timmy
Timmy

Reputation: 268

Month is zero-based. So ca1.set(2012,9,20) is actually setting the calendar to October.

Upvotes: 4

Related Questions