Reputation: 45
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.
Upvotes: 3
Views: 2601
Reputation: 338211
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.
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`.
Upvotes: 4
Reputation: 6075
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);
Upvotes: 0
Reputation: 1092
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.
Upvotes: 0