如何在Java中获取与01/01不同的日期开始的一年的上一个/当前季度和年份的开始和结束日期

Posted

技术标签:

【中文标题】如何在Java中获取与01/01不同的日期开始的一年的上一个/当前季度和年份的开始和结束日期【英文标题】:How to get previous/ current quarter and year start and end dates for a year that starts on a date different from 01/01 in Java 【发布时间】:2019-02-04 18:10:09 【问题描述】:

我正在尝试实现一种返回以下内容的方法:

当前季度日期 上一季度日期 当年 上一年

从 01/01 开始的典型年份,我能够通过以下方式弄清楚如何做到这一点:

      //Current quarter start and end date
      aCalendar.setTime(this.startdate);
    aCalendar.set(Calendar.MONTH, aCalendar.get(Calendar.MONTH) / 3 * 3);
    aCalendar.set(Calendar.DAY_OF_MONTH, 1);
    this.quarterStartDate = aCalendar.getTime();

    aCalendar.setTime(this.startdate);
    aCalendar.set(Calendar.MONTH, aCalendar.get(Calendar.MONTH) / 3 * 3 + 2);
    aCalendar.set(Calendar.DAY_OF_MONTH, aCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    this.quarterEndDate = aCalendar.getTime();
    if (this.quarterEndDate.getTime() > currentCalendar.getTimeInMillis())
        this.quarterEndDate = currentCalendar.getTime();

    // previous quarter
    aCalendar.setTime(this.startdate);
    aCalendar.add(Calendar.MONTH, -3);
    aCalendar.set(Calendar.MONTH, aCalendar.get(Calendar.MONTH) / 3 * 3 + 2);
    aCalendar.set(Calendar.DAY_OF_MONTH, aCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    this.previousQuarterEndDate = aCalendar.getTime();

    aCalendar.setTime(this.startdate);
    aCalendar.add(Calendar.MONTH, -3);
    aCalendar.set(Calendar.MONTH, aCalendar.get(Calendar.MONTH) / 3 * 3);
    aCalendar.set(Calendar.DAY_OF_MONTH, 1);
    this.previousQuarterStartDate = aCalendar.getTime();

    // current year
    aCalendar.setTime(this.startdate);
    aCalendar.set(Calendar.MONTH, 11); 
    aCalendar.set(Calendar.DAY_OF_MONTH, 31); 
    this.currentYearEndDate = aCalendar.getTime();

    if (this.currentYearEndDate.getTime() > currentCalendar.getTimeInMillis())
        this.currentYearEndDate = currentCalendar.getTime();

    aCalendar.setTime(this.startdate);
    aCalendar.set(Calendar.MONTH, 0); 
    aCalendar.set(Calendar.DAY_OF_MONTH, 1); 
    this.currentYearStartDate = aCalendar.getTime();

    // previous year
    aCalendar.setTime(this.currentYearEndDate);
    aCalendar.set(Calendar.YEAR, aCalendar.get(Calendar.YEAR) - 1);
    aCalendar.set(Calendar.MONTH, 11); // 
    aCalendar.set(Calendar.DAY_OF_MONTH, 31); 
    this.previousYearEndDate = aCalendar.getTime();

    aCalendar.setTime(this.currentYearStartDate);
    aCalendar.set(Calendar.YEAR, aCalendar.get(Calendar.YEAR) - 1);
    aCalendar.set(Calendar.MONTH, 0); // 
    aCalendar.set(Calendar.DAY_OF_MONTH, 1); 
    this.previousYearStartDate = aCalendar.getTime();

但是,我要解决的是,如果一年的开始日期与季度不同,例如 2018 年 3 月 1 日,那么

**Q1** = 03/01/2018 -05/31/2018
**Q2** = 06/01/2018- 08/30/2018
**Q3** = 09/01/2018 - 11/30/2018
**Q4** = 12/01/2018 - 02/28/2019

我的问题是如何返回当前/上一季度和年度的开始和结束日期。例如,假设今天的日期是 10/19/2018 应该返回以下内容:

当前季度:Start_Date = 9/1/2018 End_Date = 10/19/2018 上一季度:Start_Date = 6/1/2018 End_Date = 8/30/2018 当年:Start_Date = 3/1/2018 End_Date = 10/19/2018 上一年:Start_Date = 3/12017 End_Date = 2/28/2018

【问题讨论】:

我建议你不要使用Calendar。该课程设计不良且早已过时。而是使用来自java.time, the modern Java date and time API 的LocalDate 这真的是复制品吗?我看不出链接问题的三个答案中的任何一个如何考虑到这一年可能不会从 1 月 1 日开始。@mocodes,你有意见吗? 【参考方案1】:

java.time

    final Month yearStart = Month.MARCH;
    final int yearStartValue = yearStart.getValue();

    LocalDate currentDate = LocalDate.of(2018, Month.OCTOBER, 19);

    // Current quarter start and end date
    // First find 0-based month witin quarter; 0, 1 or 2 
    int monthInQuarter = (currentDate.getMonthValue() + 12 - yearStartValue) % 3;
    LocalDate currentQuarterStart
            = currentDate.withDayOfMonth(1).minusMonths(monthInQuarter);
    LocalDate currentQuarterEndInclusive
            = currentQuarterStart.plusMonths(3).minusDays(1);
    System.out.println("Current quarter:  " + currentQuarterStart
            + " through " + currentQuarterEndInclusive);

    // previous quarter
    LocalDate previousQuarterStart = currentQuarterStart.minusMonths(3);
    LocalDate previousQuarterEndInclusive = currentQuarterStart.minusDays(1);
    System.out.println("Previous quarter: " + previousQuarterStart
            + " through " + previousQuarterEndInclusive);

    // current year
    // Find 0-based month in year
    int monthInYear = (currentDate.getMonthValue() + 12 - yearStartValue) % 12;
    LocalDate currentYearStart
            = currentDate.withDayOfMonth(1).minusMonths(monthInYear);
    LocalDate currentYearEndInclusive
            = currentYearStart.plusYears(1).minusDays(1);
    System.out.println("Current year:     " + currentYearStart
            + " through " + currentYearEndInclusive);

    // previous year
    LocalDate previousYearStart = currentYearStart.minusYears(1);
    LocalDate previousYearEndInclusive = currentYearStart.minusDays(1);
    System.out.println("Previous year:    " + previousYearStart
            + " through " + previousYearEndInclusive);

从 3 月 1 日开始,当前日期为 2018 年 10 月 19 日,上述 sn-p 输出:

Current quarter:  2018-09-01 through 2018-11-30
Previous quarter: 2018-06-01 through 2018-08-31
Current year:     2018-03-01 through 2019-02-28
Previous year:    2017-03-01 through 2018-02-28

您不应该使用 Calendar 类。它有几个设计问题并且已经过时了。相反,我使用现代 Java 日期和时间 API java.time 中的LocalDate。与 Calendar 相反,LocalDate 表示没有时间和时区的日期,所以这是我们需要的。

由于时间间隔通常是半开的——从包含开始到不包含结束——我在结束日期变量的名称中添加了Inclusive,以明确我们在这里使用的是封闭间隔。

链接:Oracle tutorial: Date Time解释如何使用java.time

【讨论】:

以上是关于如何在Java中获取与01/01不同的日期开始的一年的上一个/当前季度和年份的开始和结束日期的主要内容,如果未能解决你的问题,请参考以下文章

我需要根据用户在odoo中选择的月份来获取月份的开始日期和结束日期

PHP获取一年中的每星期的开始日期和结束日期

PHP获取一年中的每星期的开始日期和结束日期

java中如何计算出两个日期之间相差多少天

更改 impala trunc() 返回的一周的开始日期

EXCEL 拆分日期后年份