tl;dr
- You seem to conflate first-of-month with first-day-of-week.
- The
2
is a hard-coded constant representing Monday.
- Apparently your current default locale considers Monday to be the first day of the week.
- Use java.time instead.
For first day of the week:
LocalDate.now( ZoneId.of( "America/Montreal" ) )
.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) )
For first day of the month:
LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )
.with( ChronoField.DAY_OF_MONTH , 1L )
Details
getFirstDayOfWeek() to retrieve first day of every month
You seem to be confusing first of the week with first of the month.
The first of the month is always 1
of course.
The first of the week is a day-of-week such as Sunday or Monday etc. The definition of the first day of the week in the Calendar
class varies, depending on the Locale
. For example, in much of North America, the first day is Sunday commonly. In much of Europe, the first day of the week is Monday.
If you fail to specify a Locale
, the Calendar
class implicitly applies the JVM’s current default locale. Apparently in your default locale the first day of the week is Monday. I deduce that because you report the number 2
. If you explore the int
constant Calendar.MONDAY
, you find it is indeed a primitive int
of value 2
.
Avoid legacy date-time classes
The Calendar
class has many poor design decisions. I consider this varying definition of day-of-week to be one of them. One of many reasons to avoid these troublesome old date-time classes such as Calendar
and Date
. These classes are now legacy, supplanted by the java.time classes.
Using java.time
The LocalDate
class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
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" );
LocalDate today = LocalDate.now( z );
To get the first day of the week, (a) decide what is the first day of the week for you, (b) use a TemporalAdjuster
implementation defined in TemporalAdjusters
to get the date for a specific DayOfWeek
enum object.
DayOfWeek firstDow = DayOfWeek.MONDAY ;
LocalDate ld = today.with( TemporalAdjusters.previousOrSame( firstDow ) ) ;
To get a LocalDate
for a certain day of month, call the with
method and pass an enum object from ChronoField.DAY_OF_MONTH
.
LocalDate firstOfMonth = today.with( ChronoField.DAY_OF_MONTH , 1L ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?