Reputation: 87
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
Reputation: 338654
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 ) ;
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]
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
Upvotes: 1
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
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
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
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