user1372061
user1372061

Reputation: 87

How to calculate the number of Tuesday in one month?

How to calculate number of Tuesday in one month?

Using calender.set we can set particular month, after that how to calculate number of Mondays, Tuesdays etc. in that month?

Code is :

public static void main(String[] args )
{
    Calendar calendar = Calendar.getInstance();
    int  month = calendar.MAY; 
    int year = 2012;
    int date = 1 ;

    calendar.set(year, month, date);

    int MaxDay = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
    int mon=0;

    for(int i = 1 ; i < MaxDay ; i++)
    {        
        calendar.set(Calendar.DAY_OF_MONTH, i);
        if (calendar.get(Calendar.DAY_OF_WEEK) == calendar.MONDAY ) 
            mon++;      
    }

    System.out.println("days  : " + MaxDay);    
    System.out.println("MOndays  :" + mon);
}

Upvotes: 1

Views: 5248

Answers (5)

Basil Bourque
Basil Bourque

Reputation: 338654

tl;dr

yearMonth
.atDay( 1 )
.datesUntil( yearMonth.plusMonths(1).atDay(1) )
.map( LocalDate :: getDayOfWeek )
.filter( DayOfWeek.TUESDAY :: equals )
.count()

java.time.YearMonth

Never use the tragically-flawed legacy date-time classes. Never use Calendar, Date, etc. Use only the modern java.time classes built into Java 8 and later.

To represent a particular month of a particular year, use the YearMonth class.

YearMonth ym = YearMonth.of ( 2012 , Month.MAY ) ;

List of Tuesdays

To see the Tuesdays, get a stream of all the dates of that month. Filter for those whose day-of-week is Tuesday. Represent each date by the LocalDate class.

List < LocalDate > tuesdays =
        ym
                .atDay ( 1 )
                .datesUntil ( ym.plusMonths ( 1 ).atDay ( 1 ) )
                .filter ( date -> date.getDayOfWeek ( ).equals ( DayOfWeek.TUESDAY ) )
                .toList ( );

tuesdays = [2012-05-01, 2012-05-08, 2012-05-15, 2012-05-22, 2012-05-29]

Count of Tuesdays

If you want only a count, change that .toList() to a .count().

long countTuesdays =
        ym
                .atDay ( 1 )
                .datesUntil ( ym.plusMonths ( 1 ).atDay ( 1 ) )
                .filter ( date -> date.getDayOfWeek ( ).equals ( DayOfWeek.TUESDAY ) )
                .count ();

5

screenshot of calendar for May 2012

Upvotes: 1

assylias
assylias

Reputation: 328608

With Java 8+, you could write it in a more concise way:

public static int countDayOccurenceInMonth(DayOfWeek dow, YearMonth month) {
  LocalDate start = month.atDay(1).with(TemporalAdjusters.nextOrSame(dow));
  return (int) ChronoUnit.WEEKS.between(start, month.atEndOfMonth()) + 1;
}

Which you can call with:

int count = countDayOccurenceInMonth(DayOfWeek.TUESDAY, YearMonth.of(2012, 1));
System.out.println(count); //prints 5

Upvotes: 3

Danny C
Danny C

Reputation: 2980

Java calendar actually has a built in property for that Calendar.DAY_OF_WEEK_IN_MONTH

Calendar calendar = Calendar.getInstance(); //get instance
calendar.set(Calendar.DAY_OF_WEEK, 3);  //make it be a Tuesday (crucial)
//optionally set the month you want here
calendar.set(Calendar.MONTH, 4) //May
calendar.getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH); //for this month (what you want)
calendar.getMaximum(Calendar.DAY_OF_WEEK_IN_MONTH); //for any month (not so useful)

Upvotes: 1

cpentra1
cpentra1

Reputation: 1220

AlexR mentioned the more efficient version. Thought I would give it a whirl:

private int getNumThursdays() {
    // create instance of Gregorian calendar 
    Calendar gc = new GregorianCalendar(TimeZone.getTimeZone("EST"), Locale.US);
    int currentWeekday = gc.get(Calendar.DAY_OF_WEEK);

    // get number of days left in month
    int daysLeft = gc.getActualMaximum(Calendar.DAY_OF_MONTH) - 
            gc.get(Calendar.DAY_OF_MONTH);

    // move to closest thursday (either today or ahead)
    while(currentWeekday != Calendar.THURSDAY) {
        if (currentWeekday < 7)  currentWeekday++;
        else currentWeekday = 1;
        daysLeft--;
    }

    // calculate the number of Thursdays left
    return daysLeft / 7 + 1;
}

note: When getting the current year, month, day etc. it is dependent on your environment. For example if someone manually set the time on their phone to something wrong, then this calculation could be wrong. To ensure correctness, it is best to pull data about the current month, year, day, time from a trusted source.

Upvotes: 0

AlexR
AlexR

Reputation: 115338

Without writing whole code here is the general idea:

    Calendar c = Calendar.getInstance();
    c.set(Calendar.MONTH, Calendar.MAY); // may is just an example
    c.set(Calendar.YEAR, 2012);
    int th = 0;
    int maxDayInMonth = c.getMaximum(Calendar.MONTH);
    for (int d = 1;  d <= maxDayInMonth;  d++) {
        c.set(Calendar.DAY_OF_MONTH, d);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        if (Calendar.THURSDAY == dayOfWeek) {
            th++;
        }
    }

This code should count number of Thursday. I believe you can modify it to count number of all days of week.

Obviously this code is not efficient. It iterates over all the days in the month. You can optimize it by getting just get day of the week of the first day, the number of days in month and (I believe) you can write code that calculates number of each day of week without iterating over the whole month.

Upvotes: 8

Related Questions