Reputation: 89
I'm not seeing a good way to set a date to a certain day of the week for a certain week of the month. Joda-Time's LocalDate does not have a withWeekOfMonth method. I can see a possible algorithm, but it seems way to complicated, so I'm going to assume I'm missing something. What I need is to determine the next date someone is paid. And if they are paid on the Second Thursday of the Month, what date is that.
Anyone already solved this problem?
Ok, I was able to come up with this, which seems to work fine.
/**
* Finds a date such as 2nd Tuesday of a month.
*/
public static LocalDate calcDayOfWeekOfMonth( final DayOfWeek pDayOfWeek, final int pWeekOfMonth, final LocalDate pStartDate )
{
LocalDate result = pStartDate;
int month = result.getMonthOfYear();
result = result.withDayOfMonth( 1 );
result = result.withDayOfWeek( pDayOfWeek.ordinal() );
if ( result.getMonthOfYear() != month )
{
result = result.plusWeeks( 1 );
}
result = result.plusWeeks( pWeekOfMonth - 1 );
return result;
}
Upvotes: 2
Views: 4970
Reputation: 79095
java.time
APIWith the modern date-time API of Java, you can pass TemporalAdjusters#dayOfWeekInMonth
as an argument to LocalDate#with
to achieve this.
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
public class Main {
public static void main(String[] args) {
// Test with today's date, 26-Dec-2020
System.out.println(
localDateOnNthDayOfWeekOfMonth(DayOfWeek.THURSDAY, 2, LocalDate.now())
);
}
public static LocalDate localDateOnNthDayOfWeekOfMonth
(
final DayOfWeek dayOfWeek,
final int ordinal,
final LocalDate startDate
) {
return startDate.with(
TemporalAdjusters.dayOfWeekInMonth(ordinal, dayOfWeek)
);
}
}
Output:
2020-12-10
Learn about Java-8 date-time API from Trail: Date Time.
Note for Java 6 or 7 users:
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 3
Reputation: 640
Example how to detect 2nd Monday
val DateTime.is2ndMonday
get() = dayOfWeek == 1 && dayOfMonth > 7
Upvotes: 0
Reputation: 2543
I personally don't know of any super-simple way of doing it, this is what I use to get it:
/**
* Calculates the nth occurrence of a day of the week, for a given month and
* year.
*
* @param dayOfWeek
* The day of the week to calculate the day for (In the range of
* [1,7], where 1 is Monday.
* @param month
* The month to calculate the day for.
* @param year
* The year to calculate the day for.
* @param n
* The occurrence of the weekday to calculate. (ie. 1st, 2nd,
* 3rd)
* @return A {@link LocalDate} with the nth occurrence of the day of week,
* for the given month and year.
*/
public static LocalDate nthWeekdayOfMonth(int dayOfWeek, int month, int year, int n) {
LocalDate start = new LocalDate(year, month, 1);
LocalDate date = start.withDayOfWeek(dayOfWeek);
return (date.isBefore(start)) ? date.plusWeeks(n) : date.plusWeeks(n - 1);
}
Example:
System.out.println(nthWeekdayOfMonth(4, 1, 2012, 2));
Output:
2012-01-12
Upvotes: 7