Get the last Monday of the month
I have a problem with the correct date of the last Monday of the previous month. I think that there is absolutely no correct calculation of it, as in this question and want to abandon arithmetic operations with constants. This code works as expected:
public class mCalendar {
private int thisMonth;
private int prevMonth;
private int lstDayThisMonth;
private int lstDayPrevMonth;
private int weekOffset;
private int LstMnd;
public String monthLetter;
Locale locale = Locale.getDefault();
private Calendar mCal;
public mCalendar(){
this.mCal = Calendar.getInstance();
mCal.set(Calendar.MONTH,0);
this.thisMonth = mCal.get(Calendar.MONTH);
this.prevMonth = thisMonth - 1;
this.lstDayThisMonth = mCal.getActualMaximum(Calendar.DAY_OF_MONTH);
this.monthLetter = mCal.getDisplayName(Calendar.MONTH, Calendar.LONG, locale);
mCal.set(Calendar.MONTH,prevMonth);
this.lstDayPrevMonth = mCal.getActualMaximum(Calendar.DAY_OF_MONTH);
mCal.set(Calendar.DAY_OF_MONTH,lstDayPrevMonth);
this.LstMnd = mCal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
mCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
mCal.set(Calendar.DAY_OF_WEEK_IN_MONTH, LstMnd);
this.weekOffset = mCal.get(Calendar.DAY_OF_MONTH);
}
But when I set Calendar.MONTH
to 1 in the second statement of the constructor body Calendar.DAY_OF_MONTH
, we return frist on Monday February. I expect the function will return me on Jan 26, but it will return on Feb 2. I think this is happening because February 1st is Sunday, but for example, for March, the code works correctly.
Help me please, i'm confused)
source to share
TL; DR
date of the last Monday of the previous month
YearMonth.from( // Represent entire month as a whole.
LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) // Determine today’s date for a particular time zone.
)
.minusMonths( 1 ) // Move to prior `YearMonth`.
.atEndOfMonth() // Get the last day of that prior month as a `LocalDate`.
.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) ) // Move to another date for a Monday, or remain if already on a Monday.
java.time
The modern approach uses java.time classes rather than the difficult old class Calendar
.
LocalDate
The class LocalDate
represents a date value only with no time and no time zone.
The time zone is critical for determining the date. At any given moment, the date changes around the world by zone. For example, a few minutes after midnight in Paris France is a new day, while it is still "yesterday" in Montreal Quebec .
If no time zone is specified, the JVM implicitly applies the current default time zone. This default can change at any time, so your results may vary. Better to specify the desired / expected timezone explicitly as an argument.
Specify the name of the time zone in the format continent/region
, for example America/Montreal
, Africa/Casablanca
or Pacific/Auckland
. Never use the 3-4 letter abbreviation, for example EST
or IST
, as they are not real time zones and not standardized and not even unique (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the current JVMs timezone, ask for it and pass it as an argument. If this parameter is omitted, the default JVM is used implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or enter a date. You can set the month to the number, with the normal number 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use Month
predefined objects, one for each month of the year. Council. Use these objects Month
throughout your codebase, rather than just an integer, to make your code more self-documenting, provide valid values, and provide type safety .
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Get the whole month with YearMonth
class.
YearMonth thisMonth = YearMonth.from( ld ) ;
Move to the previous month.
YearMonth priorMonth = thisMonth.minusMonths( 1 ) ;
Get the last day of this previous month.
LocalDate endOfPriorMonth = priorMonth.atEndOfMonth() ;
Get the previous Monday relative to the end of this previous month, unless the end of the month becomes Monday. Do this with the TemporalAdjuster
implementation found in TemporalAdjusters
.
LocalDate lastMondayOfPriorMonth = endOfPriorMonth.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the nasty old legacy date classes such as java.util.Date
, Calendar
and . SimpleDateFormat
The Joda-Time project , now in maintenance mode , advise moving to the java.time classes .
To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification JSR 310 .
Where can I get the java.time classes?
- Java SE 8 , Java SE 9 and then
- Built in.
- Part of the standard Java API with a combined implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality goes back to Java 6 and 7 in ThreeTen-Backport .
- Android
- Later versions of the Android package implementations of the java.time classes.
- For earlier Android, the ThreeTenABP project adapts the ThreeTen-Backport (mentioned above). See. How to use ... ThreeTenABP .
The ThreeTen-Extra project extends java.time with additional classes. This project is proof of possible future additions to java.time. Here you can find useful classes, such as Interval
, YearWeek
, YearQuarter
and longer .
source to share