I'm working on some accounting logic. The logic is that an accounting that happened in the first month of a quarter year must have a value date that is at the end of the preceding quarter year. I know that I can represent the month as a period. But I have no idea how to represent the recurring period of a quarter year.
I'm able to do the calculation using joda-time classes that would give me the value date at the end of the preceding quarter year. However I would like to represent "first month of each quarter year" as a single value that I use in my calculations.
So is there some API in joda-time that is well suitable for representing this kind of recurring period?
Some example dates are:
date of invoce | value date
2013-01-01 | 2012-12-31
2013-01-31 | 2012-12-31
2013-02-01 | 2013-02-01
2013-03-31 | 2013-03-31
2013-04-01 | 2013-03-31
OK, here is more explanative example as requested in comments: The accounting logic is about a kind of pension funds you have to apply for. You apply for the pensions of 2012 in the succeeding year, exactly on 1st of January 2013. It will be granted to you on the 15th of April 2013. Since April is the first month of the quarter year, the granting will have its value date set to the 31st of March. All pensions that are accounted within one quarter year are paid 1 month and 5 days after that quarter year has ended. So even if you have been granted your pension in April, you will still get it paid on 5th of May. Otherwise you would have to wait for it to be payed until 5th of September.
But I don't really know how this example should help. This question really is about modeling "every first month of each quarter year" with joda-time classes or even implementing some API of joda-time.
I had to implement this too. Here is an implementation that seems ok at first glance.
public class QuarterPeriods {
public static LocalDate quarterStartFor(LocalDate date) {
return date.withDayOfMonth(1).withMonthOfYear((((date.getMonthOfYear() - 1) / 3) * 3) + 1);
}
public static LocalDate quarterEndFor(LocalDate date) {
return quarterStartFor(date).plusMonths(3).minusDays(1);
}
}
public class QuarterPeriodsTest {
@Test
public void startOfQuarter() throws Exception {
assertThat(quarterStartFor(StubDates.dateOf("2011/02/02")), equalTo(StubDates.dateOf("2011/01/01")));
assertThat(quarterStartFor(StubDates.dateOf("2011/01/01")), equalTo(StubDates.dateOf("2011/01/01")));
assertThat(quarterStartFor(StubDates.dateOf("2011/02/02")), equalTo(StubDates.dateOf("2011/01/01")));
assertThat(quarterStartFor(StubDates.dateOf("2011/04/01")), equalTo(StubDates.dateOf("2011/04/01")));
assertThat(quarterStartFor(StubDates.dateOf("2011/07/01")), equalTo(StubDates.dateOf("2011/07/01")));
assertThat(quarterStartFor(StubDates.dateOf("2011/12/19")), equalTo(StubDates.dateOf("2011/10/01")));
}
@Test
public void endOfQuarter() throws Exception {
assertThat(quarterEndFor(StubDates.dateOf("2011/02/02")), equalTo(StubDates.dateOf("2011/03/31")));
assertThat(quarterEndFor(StubDates.dateOf("2011/01/01")), equalTo(StubDates.dateOf("2011/03/31")));
assertThat(quarterEndFor(StubDates.dateOf("2011/02/02")), equalTo(StubDates.dateOf("2011/03/31")));
assertThat(quarterEndFor(StubDates.dateOf("2011/04/01")), equalTo(StubDates.dateOf("2011/06/30")));
assertThat(quarterEndFor(StubDates.dateOf("2011/07/01")), equalTo(StubDates.dateOf("2011/09/30")));
assertThat(quarterEndFor(StubDates.dateOf("2011/12/19")), equalTo(StubDates.dateOf("2011/12/31")));
}
}
public class StubDates {
public static LocalDate dateOf(String date) {
return DateTimeFormat.forPattern("yyyy/MM/dd").withZone(DateTimeZone.UTC).parseDateTime(date).toLocalDate();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With