2

我没有看到将日期设置为一个月中某一周的某一天的好方法。 Joda-TimeLocalDate没有 withWeekOfMonth 方法。我可以看到一个可能的算法,但它似乎很复杂,所以我假设我错过了一些东西。我需要确定某人下一次付款的日期。如果他们在每月的第二个星期四支付,那是什么日期。

有人已经解决了这个问题吗?

好的,我能够想出这个,这似乎工作正常。

/**  
 * 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;  
}  
4

3 回答 3

7

我个人不知道有什么超级简单的方法,这就是我用来获取它的方法:

/**
 * 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);
}

例子:

System.out.println(nthWeekdayOfMonth(4, 1, 2012, 2));

输出:

2012-01-12
于 2012-10-23T15:19:47.723 回答
3

使用 Java-8 java.timeAPI的解决方案

使用 Java 的现代日期时间 API,您可以将TemporalAdjusters#dayOfWeekInMonth其作为参数传递LocalDate#with来实现此目的。

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)
        );
    }
}

输出:

2020-12-10

从Trail: Date Time了解 Java-8 日期时间 API 。

Java 6 或 7 用户的注意事项:

出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目工作并且您的 Android API 级别仍然不兼容 Java-8,请通过脱糖和How to use ThreeTenABP in Android Project检查可用的 Java 8+ API

于 2020-12-26T21:00:02.817 回答
0

示例如何检测第二个星期一

val DateTime.is2ndMonday
    get() = dayOfWeek == 1 && dayOfMonth > 7
于 2020-12-26T20:44:13.190 回答