3

I am trying to get day of week of first day in selected month. Main condition is use only java.time. I need smth like this:

DayOfWeek dayOfWeek = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).getDayOfWeek();

I already have YearMonth, which i got by entering numbers of year and month. How can i get dayOfWeek of first day in month ? I did it like this:

DayOfWeek dayOfWeek = yearMonth.atDay(1).getDayOfWeek();

but i got a commentary, that i have "magic numbers" that i need eliminate by correct using library java.time.

3 Answers 3

4

Magic number

i got a commentary, that i have "magic numbers" that i need eliminate by correct using library java.time.

No, you did not use a magic number; that commentary is incorrect. The author of that commentary jumped too fast upon seeing a hard-coded literal number being passed as an argument. Indeed, passing a literal number as an argument is suspicious as a possible “magic number”, and worthy of a second look, but in this case is quite appropriate.

The term magic number refers to the use of numbers whose purpose/meaning/role is not immediately obvious. Passing 1 to YearMonth.atDay() is quite obvious, meaning the first of the month.

Personally I do wish the YearMonth class offered a atFirstOfMonth like it has atEndOfMonth. My motivation is to avoid this very problem: Being sensitive to spotting hard-coded literal number passed as argument. But no big deal. Your code’s call to atDay( 1 ) is correct and clear. Using a TemporalAdjuster is correct as well, but is not as obvious.

One-liner, if you like short code (I do not):

YearMonth.of( year , month ).atDay( 1 ).getDayOfWeek()

Some discussion follows to elucidate this topic.

YearMonth

I already have YearMonth, which i got by entering numbers of year and month.

Java offers a class for this, to represent an entire month: YearMonth.

YearMonth ym = YearMonth.now() ;  // Capture the current year-month as seen through the wall-clock time used by the people of the JVM’s current default time zone.

I recommend passing objects of this class around your codebase rather than using mere integer numbers for year & month. Using objects provides type-safety, ensures valid values, and makes your code more self-documenting.

Time zone

Better to specify a time zone. For any given moment, the date varies around the globe by zone. Better to explicitly specify the desired/expected time zone than rely implicitly on the JVM’s current default which can change at any moment during runtime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  // Specify desired/expected time zone. Or explicitly ask for JVM’s current default: `ZoneId.systemDefault()`.
YearMonth ym = YearMonth.now( z ) ;  // Capture the current year-month as seen through the wall-clock time used by the people of a particular region (time zone).

LocalDate

Get the date of the first day of month as a LocalDate.

LocalDate ld = ym.atDay( 1 ) ;  // Get the first day of the month.

DayOfWeek

The DayOfWeek enum provides seven pre-existing objects, one for each day of the week. These are not mere strings, but are smart objects.

DayOfWeek dow = ld.getDayOfWeek() ;
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ;  // Generate a String representing the name of this day-of-week localized to the human language and cultural norms of a particular `Locale`. 
0

Here is a solution by just passing an LocalDate object:

public static String getFirstWeekDay(LocalDate date) {

        int day = 1;
        int month = date.getMonthValue();
        int year = date.getYear();

        LocalDate newDate = LocalDate.of(year, month, day);
        String dayOfWeek = newDate.getDayOfWeek().toString();

        return dayOfWeek;
}

Alternatively, you could use the method below to get the DayOfWeek Enum:

public static DayOfWeek getFirstWeekDay(LocalDate date){

        int day = 1;
        int month = date.getMonthValue();
        int year = date.getYear();

        LocalDate newDate = LocalDate.of(year, month, day);

        return newDate.getDayOfWeek();
}

I hope this helps.

0

If you have the month and the year and you just need the first day of the month I would do something like this:

DayOfWeek firstDay = LocalDate.of(year, month, 1).getDayOfWeek();

Basically, you build a date where the dayOfMonth param is 1.

Based on your solution for the first day of a month assuming yearMonth is a LocalDate this should work:

DayOfWeek dayOfWeek =yearMonth.with(TemporalAdjusters.firstDayOfMonth()).getDayOfWeek();
System.out.println(dayOfWeek);
4
  • why do i need current date for getting dayOfWeek of first day of (for example) january 1997 ? Commented Feb 12, 2017 at 16:46
  • @IlyaTomashenko you don't; I used now as an example Commented Feb 12, 2017 at 17:32
  • looks good, but, yearMonth.with(TemporalAdjusters.firstDayOfMonth()) return YearMonth and doesn't has .getDayOfWeek(), i wouldn't ask, if it was so easy. Thank you anyway. Commented Feb 13, 2017 at 14:24
  • @IlyaTomashenko are you importing yoda time instead of java; works for me and I just copied it from ide Commented Feb 13, 2017 at 14:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.