首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从一个日期获得零售日历周(4-5-4)

如何从一个日期获得零售日历周(4-5-4)
EN

Stack Overflow用户
提问于 2018-03-19 17:20:33
回答 2查看 1.7K关注 0票数 5

我需要从日期中获得4-5-4日历周。对于4-5-4零售日历,Java中有像格鲁吉亚日历这样的实用工具吗?如果没有,我如何创建一个?所有的逻辑都需要什么?什么是第53周,如果是飞跃年?

例如,如果我传递一个日期(DD-MM-YYY) 04-03-2018作为输入,我应该得到March Week 1作为输出。或者,如果我给01-04-2018作为输入,我应该得到March Week 5作为输出。

请帮助我提供一种方法来构建这个实用程序。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-21 18:19:30

下面的课应该这样做:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
    System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.MARCH, 4)));
    System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.APRIL, 1)));

这将打印所需的内容:

代码语言:javascript
复制
March Week 1
March Week 5

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

计算月和月周的公式是神秘的.我并没有很好的理由来解释它们的作用,尽管这样的论点可能是可以建立起来的。我已经用所有相关的价值观测试过它们,您也可以这样做。除此之外,使用java.time (现代java.time和time )并不是太糟糕。

如果是我,我将在NrfMonthWeek构造函数中进行更好的验证,只允许在可能有5周的月份中的第5周。我把这个留给你。我会进行相当彻底的单元测试。

请检查我的理解是否与您的理解一致:如果我从示例日历中正确地理解了Bourque与在他的回答中的链接,NRF 4-5-4年从2月开始。每周从周日开始,一年中的第一周是包含至少4天2月的第一周。换句话说,包含2月4日的那一周。换句话说,从1月29日到2月4日间隔的一个星期日开始的一周。三月、六月、九月和十二月总是有五个星期。如果是53周,1月份也有5周。

票数 3
EN

Stack Overflow用户

发布于 2018-03-19 19:45:55

没有内置的支持

现代java.time类和遗留日期时类(Date/Calendar)都不直接支持全国零售联合会4-5-4日历

实现Chronology

我怀疑解决这个问题的最好方法是为Chronology框架实现一个java.time。

Java 8和更高版本捆绑了五个实现(HijrahChronologyIsoChronologyJapaneseChronologyMinguoChronologyThaiBuddhistChronology)。它们的源代码可以在OpenJDK项目中获得。

http://www.threeten.org/threeten-extra/项目提供十多个年表 (AccountingChronologyBritishCutoverChronologyCopticChronologyDiscordianChronologyEthiopicChronologyInternationalFixedChronologyJulianChronology、< code >D19、Symmetry010ChronologySymmetry454Chronology),源代码可能会有所帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49368843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档