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`.