java 周历_java – 如何从日期获得零售(4-5-4)日历周

我需要从一个日期获得4-5-4个日历周.是否有像Java格鲁吉亚日历这样的实用程序用于4-5-4零售日历?

如果没有,我该如何创建一个?需要什么逻辑?在闰年的情况下,第53周是什么时候?

例如,如果我将日期(DD-MM-YYY)04-03-2018作为输入传递,我应该将3月第1周作为输出.

或者,如果我将01-04-2018作为输入,我应该将3月第5周作为输出.

请通过提供构建此实用程序的方法来帮助我.

解决方法:

以下类应该这样做:

public class NrfMonthWeek {

public static NrfMonthWeek getWeek(LocalDate date) {

// Determine NRF calendar year.

// The year begins on the Sunday in the interval Jan 29 through Feb 4.

LocalDate firstDayOfNrfYear = date.with(MonthDay.of(Month.JANUARY, 29))

.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));

if (date.isBefore(firstDayOfNrfYear)) { // previous NRF year

firstDayOfNrfYear = date.minusYears(1)

.with(MonthDay.of(Month.JANUARY, 29))

.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));

}

// 1-based week of NRF year

int weekOfNrfYear = (int) ChronoUnit.WEEKS.between(firstDayOfNrfYear, date) + 1;

assert 1 <= weekOfNrfYear && weekOfNrfYear <= 53 : weekOfNrfYear;

YearMonth firstMonthOfNrfYear = YearMonth.from(firstDayOfNrfYear)

.with(Month.FEBRUARY);

if (weekOfNrfYear == 53) {

// Special case: the last week of a 53 weeks year belongs to

// the last month, January; this makes it a 5 weeks month.

return new NrfMonthWeek(firstMonthOfNrfYear.plusMonths(11), 5);

} else {

// 1-based month of NRF year (1 = February through 12 = January).

// A little math trickery to make the 4-5-4 pattern real.

int monthOfNrfYear = (weekOfNrfYear * 3 + 11) / 13;

// Number of weeks before the NRF month: 0 for February, 4 for March, 9 for April, etc.

int weeksBeforeMonth = (monthOfNrfYear * 13 - 12) / 3;

int weekOfMonth = weekOfNrfYear - weeksBeforeMonth;

return new NrfMonthWeek(

firstMonthOfNrfYear.plusMonths(monthOfNrfYear - 1), weekOfMonth);

}

}

private YearMonth month;

/** 1 through 5 */

private int weekOfMonth;

public NrfMonthWeek(YearMonth month, int weekOfMonth) {

this.month = Objects.requireNonNull(month);

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

throw new IllegalArgumentException("Incorrect week number " + weekOfMonth);

}

this.weekOfMonth = weekOfMonth;

}

@Override

public String toString() {

return month.getMonth().getDisplayName(TextStyle.FULL, Locale.US)

+ " Week " + weekOfMonth;

}

}

我们来试试吧.在这里,我将您问题中的两个日期传递给getWeek方法:

System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.MARCH, 4)));

System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.APRIL, 1)));

这打印出所需的:

March Week 1

March Week 5

虽然只打印了月份和周,但是年份也包含在getWeek返回的对象中.

计算月份和周数的公式是神秘的.我没有真正好的论据,为什么他们的工作,虽然这样的论点可能会被构建.我已经用所有相关值测试了它们,你可以自由地做同样的事情.除此之外,使用java.time,现代Java日期和时间API,它也不算太糟糕.

如果那是我,我会在NrfMonthWeek构造函数中进行更精细的验证,只允许在可能有5周的月份中进行第5周.我把它留给你.我会有一个非常彻底的单元测试.

请检查我的理解是否与您的理解一致:如果我从example calendars中正确理解了Basil Bourque与in his answer相关联,则NRF 4-5-4岁从2月开始.它的周数从星期日开始,一年的第一周是包含2月至少4天的第一周.换句话说,包含2月4日的那一周.换句话说,从1月29日到2月4日的间隔周日开始的一周.3月,6月,9月和12月的月份总是有5周.在53周的情况下,1月也有5周.

标签:java,calendar

来源: https://codeday.me/bug/20190522/1153103.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值