1

I need to get the first date of the current quarter as a java.util.Date object and the last date of the current quarter as a java.util.Date object.

I have found methods giving me quarter information, for instance

LocalDate.now().get(IsoFields.QUARTER_OF_YEAR)

but this assumes that Quarter 1 starts from January.

Can someone help me to get the first and last dates assuming that
Q1 = Aug, Sep, Oct
Q2 = Nov, Dec, Jan
Q3 = Feb, Mar, Apr
etc.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Rohit
  • 11
  • 2
  • *Why* are you using `Date`? – MC Emperor Jan 19 '22 at 10:09
  • At first there is an important difference between `LocalDate` and `Date`. You should use `LocalDate` because the old `Date` is seen as legacy code. For your first and last date requirement [this](https://stackoverflow.com/a/59790305/10899197) could fit perfectly if you manually set your 4 quarter start points and add 3 month for the end date. – Tr1monster Jan 19 '22 at 10:21
  • okay even if i will use LocalDate is there a simple way to get this done. Any code snippet will be helpful – Rohit Jan 19 '22 at 10:44

1 Answers1

2

Well, the first thing we do is writing a method which adjusts a given date into the start of a quarter. Below is an example which takes the current date and the month of the start of the 'year' (in your case August):

public static LocalDate toStartDateOfQuarter(LocalDate now, Month start) {
    int minusMonths = (start.getValue() + now.getMonthValue() - 1) % 3;
    return now.withDayOfMonth(1).minusMonths(minusMonths);
}

The we could use it like this:

Month startMonth = Month.AUGUST;
LocalDate now = LocalDate.now();
LocalDate startOfQuarter = toStartDateOfQuarter(now, startMonth);
LocalDate endOfQuarter = YearMonth.from(startOfQuarter).plusMonths(2).atEndOfMonth();

This is a different approach, but this abstracts away the implementation of the start-day-of-quarter or end-day-of-quarter implementations.

public class QuarterAdjusterFactory {

    private final Month startOfYear;

    public QuarterAdjusterFactory(Month startOfYear) {
        this.startOfYear = startOfYear;
    }

    private int minusMonths(Temporal temporal) {
        return (startOfYear.getValue() + temporal.get(ChronoField.MONTH_OF_YEAR) - 1) % 3;
    }

    public TemporalAdjuster startOfQuarter() {
        return temporal -> temporal
            .with(ChronoField.DAY_OF_MONTH, 1)
            .minus(minusMonths(temporal), ChronoUnit.MONTHS);
    }

    public TemporalAdjuster endOfQuarter() {
        return temporal -> YearMonth.from(temporal)
            .minus(minusMonths(temporal) - 2, ChronoUnit.MONTHS)
            .atEndOfMonth();
    }
}

Use it with just this:

QuarterAdjusterFactory factory = new QuarterAdjusterFactory(Month.AUGUST);
LocalDate start = date.with(factory.startOfQuarter());
LocalDate end = date.with(factory.endOfQuarter());
MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • But this doesn't work when quarter is of previous year. E.g today is 19th Jan 2022. 1st quarter is 01 Aug 2021 but this doesn't take care of that – Rohit Jan 19 '22 at 11:01
  • Sorry, haven't thought of that. I replaced the code with a simpler one. – MC Emperor Jan 19 '22 at 11:43