localdate获取几个月前,LocalDateTime Java-获取下个月的星期几

I have a date and a time of a month, for example 31/01/2020 at 14:00:00, this is the last friday of January. How can I get the date for the last Friday of Feb, March, etc.? It should be dynamic because any date can come in, like the second Tuesday of any month and so on.

I am trying with the following with no luck:

LocalDateTime startTime = LocalDateTime.of(2020, 1, 31, 14, 0, 0);

final Calendar calendar = Calendar.getInstance();

calendar.set(startTime.getYear(), startTime.getMonthValue() - 1, startTime.getDayOfMonth(), startTime.getHour(), startTime.getMinute(), startTime.getSecond());

int ordinal = calendar.get(Calendar.WEEK_OF_MONTH);

startTime = startTime.plusMonths(1).with(TemporalAdjusters.dayOfWeekInMonth(ordinal, startTime.getDayOfWeek();

System.out.println(startTime);

it's printing 06/03/2020 (six of march) at 14:00:00 which is wrong and should be 28/02/2020

What am I missing?

Thanks!

解决方案

As mentioned before, there is some ambiguity in which day of the week of the month you mean, that is, whether you mean the nth day of week or the last nth day of week of the month.

One such example is Monday, February 24th, 2020. It is the fourth and last Monday of February 2020. If you are going to try to determine this for March 2020, which Monday would you pick? The fourth Monday is 23 March, but the last Monday is 30 March.

So apparently, you'll need to distinguish between whether you count forward or backward.

You could, for instance, create a class which represents a certain day of week in a month. This holds three fields: a day-of-week, a position, and whether the position is backwards or not. E.g.

"The second Monday of the month" would have

dayOfWeek = DayOfWeek.MONDAY

position = 2

backwards = false

and

"The last Thursday of the month" would have

dayOfWeek = DayOfWeek.THURSDAY

position = 1

backwards = true

public class WeekdayInMonth {

private final boolean backwards;

private final DayOfWeek dayOfWeek;

private final int position;

private WeekdayInMonth(DayOfWeek dayOfWeek, int position, boolean backwards) {

if (position < 1 || position > 5) {

throw new DateTimeException("Position in month must be between 1 and 5 inclusive");

}

this.dayOfWeek = dayOfWeek;

this.position = position;

this.backwards = backwards;

}

}

We could add factory methods to create WeekdayInMonths from LocalDates:

public static WeekdayInMonth of(LocalDate date) {

int positionInMonth = (date.getDayOfMonth() - 1) / 7 + 1;

return new WeekdayInMonth(date.getDayOfWeek(), positionInMonth, false);

}

private static WeekdayInMonth ofReversing(LocalDate date) {

int lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();

int positionInMonth = (lastDayOfMonth - date.getDayOfMonth()) / 7 + 1;

return new WeekdayInMonth(date.getDayOfWeek(), positionInMonth, true);

}

At last, we add a method to get a LocalDate from a YearMonth adjusted to the WeekdayInMonth.

public LocalDate toLocalDate(YearMonth yearMonth) {

// Get a temporal adjuster to adjust a LocalDate to match a day-of-the-week

TemporalAdjuster adjuster = this.backwards ? TemporalAdjusters.lastInMonth(this.dayOfWeek) : TemporalAdjusters.firstInMonth(this.dayOfWeek);

int weeks = this.position - 1;

LocalDate date = yearMonth.atDay(1)

.with(adjuster)

.plusWeeks(this.backwards ? 0 - weeks : weeks);

if (!Objects.equals(yearMonth, YearMonth.from(date))) {

throw new DateTimeException(String.format("%s #%s in %s does not exist", this.dayOfWeek, this.position, yearMonth));

}

return date;

}

Working example

Addendum

I am getting errors like this if the initial date is Jan 1 2020: java.time.DateTimeException: FRIDAY #5 in 2020-02 does not exist. How could I get the previous weekday in case this happens? In this case, how would I get the previous Friday?

Well, then you need to adjust your LocalDate so that it falls within the specified yearmonth. Since every month has at least four day-of-the-weeks and no more than five of them, the difference is never more than a week. We could, after removing the throw new DateTimeException line, simply adjust the returned LocalDate using plusWeeks.

I've forked the abovementioned example and added the toAdjustingLocalDate method.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值