8

I want to get the day on which the first Monday of a specific month/year will be.

What I have:

I basically have two int variables, one representing the year and one representing the month.

What I want to have:

I want to know the first Monday in this month, preferably as an int or Integer value.

For example:

I have 2014 and 1 (January), the first Monday in this month was the 6th, so I want to return 6.

Problems:

I thought I could do that with the Calendar but I am already having trouble setting up the calendar with only Year and Month available. Furthermore, I'm not sure how to actually return the first Monday of the month/year with Calendar.

I already tried this:

Calendar cal = Calendar.getInstance();
cal.set(this.getYear(),getMonth(), 1);
int montag = cal.getFirstDayOfWeek();
for( int j = 0; j < 7; j++ ) {
    int calc = j - montag;
    if( calc < 0 ) {
        calc += 6;
    }
    weekDays[calc].setText(getDayString(calc));
}
Makoto
  • 104,088
  • 27
  • 192
  • 230
Jakob Abfalter
  • 4,980
  • 17
  • 54
  • 94
  • 2
    No, `getFirstDayOfWeek` is just a localisation method. See the docs: http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getFirstDayOfWeek() – Dave May 31 '14 at 14:59
  • 2
    Are you asking what getFirstDayOfWeek() does? [The javadoc](http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getFirstDayOfWeek%28%29) tells that: *Gets what the first day of the week is; e.g., SUNDAY in the U.S., MONDAY in France.* – JB Nizet May 31 '14 at 14:59
  • 1
    [This question](http://stackoverflow.com/q/76223/1079354), although it's asking for a "last Friday", is a more appropriate solution for your problem; you could easily follow the same pattern shown there to solve your question. – Makoto May 31 '14 at 15:29
  • To respond to your edit, your original code was almost exactly correct. The only mistake was that you used getFirstDayOfWeek when you should have been using a different function (and possibly the loop needed some tweaking). Check the docs and you'll find the function you want. – Dave May 31 '14 at 15:37

10 Answers10

28

Java.time

Use java.time library built into Java 8 and TemporalAdjuster. See Tutorial.

import java.time.DayOfWeek;
import java.time.LocalDate;
import static java.time.temporal.TemporalAdjusters.firstInMonth;

LocalDate now = LocalDate.now(); //2015-11-23
LocalDate firstMonday = now.with(firstInMonth(DayOfWeek.MONDAY)); //2015-11-02 (Monday)

If you need to add time information, you may use any available LocalDate to LocalDateTime conversion like

firstMonday.atStartOfDay() # 2015-11-02T00:00
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Przemek
  • 7,111
  • 3
  • 43
  • 52
15

getFirstDayOfWeek() returns which day is used as the start for the current locale. Some people consider the first day Monday, others Sunday, etc.

This looks like you'll have to just set it for DAY_OF_WEEK = MONDAY and DAY_OF_WEEK_IN_MONTH = 1 as that'll give you the first Monday of the month. To do the same for the year, first set the MONTH value to JANUARY then repeat the above.

Example:

private static Calendar cacheCalendar;

public static int getFirstMonday(int year, int month) {
    cacheCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    cacheCalendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
    cacheCalendar.set(Calendar.MONTH, month);
    cacheCalendar.set(Calendar.YEAR, year);
    return cacheCalendar.get(Calendar.DATE);
}

public static int getFirstMonday(int year) {
    return getFirstMonday(year, Calendar.JANUARY);
}

Here's a simple JUnit that tests it: http://pastebin.com/YpFUkjQG

Octavia Togami
  • 4,186
  • 4
  • 31
  • 49
3

First of all you should know the latest version of java i.e. JAVA8 Get familiar with LocalDate in JAVA8

Then only go through below code

public class Test {

    public static void main(String[] args) {
        LocalDate date=LocalDate.of(2014,1, 1);
        for(int i=0;i<date.lengthOfMonth();i++){
            if("Monday".equalsIgnoreCase(date.getDayOfWeek().toString())){

                break;
            }else{
                date=date.plusDays(1);
            }
        }

        System.out.println(date.getDayOfMonth());

    }

}
Arsen Davtyan
  • 1,891
  • 8
  • 23
  • 40
Abhishek Mishra
  • 611
  • 4
  • 11
  • `date.lengthOfMonth()`? but we would find a Monday within the first 7 days of any given month `for(int i=0;i<7;i++){` – weston Oct 05 '17 at 19:21
2

The method getFirstDayOfWeek() is not helpful. Quoting its javadoc:

Gets what the first day of the week is; e.g., SUNDAY in the U.S., MONDAY in France

The following tested method uses modulus arithmetic to find the day of the month of the first Monday:

public static long getMondaysDay(int year, int month) {
    try {
        Date d = new SimpleDateFormat("d-M-yyyy").parse("1-" + month + "-" + year);
        long epochMillis = d.getTime() + TimeZone.getDefault().getOffset(d.getTime());
        return (12 - TimeUnit.MILLISECONDS.toDays(epochMillis) % 7) % 7;
    } catch (ParseException ignore) { return 0; } // Never going to happen
}

Knowing that the first day of the epoch was Thursday, this works by using modulus arithmetic to calculate the day of the epoch week, then how many days until the next Monday, then modulus again in case the first falls before Thursday. The magic number 12 is 4 (the number of days from Thursday to Monday) plus 1 because days of the month start from 1 plus 7 to ensure positive results after subtraction.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Considering the various ways that time can drift, I think using a `Calendar` would be more stable than converting the milliseconds since the epoch into a day. – Dave May 31 '14 at 15:42
  • @Dave not in our lifetime :) Besides, a) I like math, and b) I never use the Calendar class on principle – Bohemian May 31 '14 at 15:44
  • I tried your method but for the parameters 2014 and 1 it returns -2 – Jakob Abfalter May 31 '14 at 16:01
  • -1; in order for this to work the month and year must be padded to 2 and 4. – Octavia Togami May 31 '14 at 17:06
  • @JakobAbfalter Getting this to work correctly (which it does now) was actually trickier than I expected. – Bohemian Jun 01 '14 at 15:39
  • @ıɯɐƃoʇǝızuǝʞ Padding was the easy part to fix (to not need). Getting the calculation to work correctly (which it does now) was actually a lot trickier than I expected. Still, it was fun to do :) – Bohemian Jun 01 '14 at 15:41
  • I can't test this right now, but does `M` work for 10, 11, 12? – Octavia Togami Jun 01 '14 at 16:24
2

Joda-Time

The Joda-Time library offers a class, LocalDate, for when you need only a date without a time-of-day. The method getDayOfWeek returns a number you can compare to the constant MONDAY.

LocalDate localDate = new LocalDate( year, month, 1 );
while ( localDate.getDayOfWeek() != DateTimeConstants.MONDAY ) {
    localDate = localDate.plusDays( 1 );
}
int firstMonday = localDate.getDayOfMonth();

Immutable Syntax

For thread-safety, Joda-Time uses immutable objects. So rather than modify field values in an existing object, we create a new instance based on the original.

java.time

As another answer by Abhishek Mishra says, the new java.time package bundled with Java 8 also offers a LocalDate class similar to Joda-Time.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

The simplest way is:

LocalDate firstSundayOfNextMonth = LocalDate
              .now()
              .with(firstDayOfNextMonth())
              .with(nextOrSame(DayOfWeek.MONDAY));
KayV
  • 12,987
  • 11
  • 98
  • 148
1

Here is a general function to get the nth DAY_OF_WEEK of a given month. You can use it to get the first Monday of any given month.

import java.util.Calendar;

public class NthDayOfWeekOfMonth {

public static void main(String[] args) {
    // get first Monday of July 2019
    Calendar cal = getNthDayOfWeekOfMonth(2019,Calendar.JULY,1,Calendar.MONDAY);
    System.out.println(cal.getTime());

    // get first Monday of August 2019
    cal = getNthDayOfWeekOfMonth(2019,Calendar.AUGUST,1,Calendar.MONDAY);
    System.out.println(cal.getTime());

    // get third Friday of September 2019
    cal = getNthDayOfWeekOfMonth(2019,Calendar.SEPTEMBER,3,Calendar.FRIDAY);
    System.out.println(cal.getTime());
}

public static Calendar getNthDayOfWeekOfMonth(int year, int month, int n, int dayOfWeek) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.YEAR,year);
    cal.set(Calendar.MONTH,month);
    cal.set(Calendar.DAY_OF_MONTH,1);

    int dayDiff = dayOfWeek-cal.get(Calendar.DAY_OF_WEEK);
    if (dayDiff<0) {
        dayDiff+=7;
    }
    dayDiff+=7*(n-1);

    cal.add(Calendar.DATE, dayDiff); 
    return cal;
}

}

Output:

Mon Jul 01 00:00:00 EDT 2019
Mon Aug 05 00:00:00 EDT 2019
Fri Sep 20 00:00:00 EDT 2019
M. Franklin
  • 57
  • 1
  • 4
0

Lamma Date library is very good for this use case.

@Test
public void test() {
    assertEquals(new Date(2014, 1, 6), firstMonday(2014, 1));
    assertEquals(new Date(2014, 2, 3), firstMonday(2014, 2));
    assertEquals(new Date(2014, 3, 3), firstMonday(2014, 3));
    assertEquals(new Date(2014, 4, 7), firstMonday(2014, 4));
    assertEquals(new Date(2014, 5, 5), firstMonday(2014, 5));
    assertEquals(new Date(2014, 6, 2), firstMonday(2014, 6));
}

public Date firstMonday(int year, int month) {
    Date firstDayOfMonth = new Date(year, month, 1);
    return firstDayOfMonth.nextOrSame(DayOfWeek.MONDAY);
}
Max
  • 2,065
  • 24
  • 20
0
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("MMM/dd/YYYY");
        calendar.set(Calendar.MONTH,Calendar.JUNE);
        calendar.set(Calendar.DAY_OF_MONTH,1);          
        int day = (Calendar.TUESDAY-calendar.get(Calendar.DAY_OF_WEEK));            
        if(day<0){
          calendar.add(Calendar.DATE,7+(day));
        }else{
            calendar.add(Calendar.DATE,day);
        }
        System.out.println("First date is "+sdf.format(calendar.getTime()));
Sujan
  • 15
  • 3
0
Get the All Monday of a month


public class AllMonday {
public static void main(String[] args){

 System.out.println(weeksInCalendar(YearMonth.now()));  

}
public static List<LocalDate> weeksInCalendar(YearMonth month) {
        List<LocalDate> firstDaysOfWeeks = new ArrayList<>();
        for (LocalDate day = firstDayOfCalendar(month); 
            stillInCalendar(month, day); day = day.plusWeeks(1)) {
          firstDaysOfWeeks.add(day);
        }
        return firstDaysOfWeeks;
      }
  private static LocalDate firstDayOfCalendar(YearMonth month) {
    DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.of(1);
    System.out.println( month.atDay(1).with(FIRST_DAY_OF_WEEK));

    return month.atDay(1).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
  }

  private static boolean stillInCalendar(YearMonth yearMonth, LocalDate day) {
      System.out.println(!day.isAfter(yearMonth.atEndOfMonth()));
    return !day.isAfter(yearMonth.atEndOfMonth());
  }

}

Ganesh Giri
  • 1,135
  • 11
  • 18