Created
May 1, 2020 18:42
-
-
Save bdkosher/109b6f3a428b81d684077618a03eb952 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.time.temporal.*; | |
import static java.time.Month.OCTOBER; | |
import static java.time.temporal.ChronoField.MONTH_OF_YEAR; | |
import static java.time.temporal.ChronoField.YEAR; | |
/** | |
* Temporal fields that are commonly used within the Federal government. | |
* | |
* More fields may be added in the future (e.g. Leave Year, Bi-Weekly Pay Period) | |
*/ | |
public enum FederalField implements TemporalField { | |
/** | |
* The fiscal year is the accounting period for the federal government which begins on October 1 and ends on | |
* September 30. The fiscal year is designated by the calendar year in which it ends; for example, fiscal year 2013 | |
* begins on October 1, 2012 and ends on September 30, 2013. | |
*/ | |
FISCAL_YEAR { | |
@Override | |
public TemporalUnit getBaseUnit() { | |
return YEAR.getBaseUnit(); | |
} | |
@Override | |
public TemporalUnit getRangeUnit() { | |
return YEAR.getRangeUnit(); | |
} | |
@Override | |
public ValueRange range() { | |
return YEAR.range(); | |
} | |
@Override | |
public boolean isSupportedBy(TemporalAccessor temporalAccessor) { | |
return YEAR.isSupportedBy(temporalAccessor); | |
} | |
@Override | |
public ValueRange rangeRefinedBy(TemporalAccessor temporalAccessor) { | |
return YEAR.rangeRefinedBy(temporalAccessor); | |
} | |
@Override | |
public long getFrom(TemporalAccessor temporalAccessor) { | |
long year = temporalAccessor.get(YEAR); | |
long month = temporalAccessor.get(MONTH_OF_YEAR); | |
return month >= OCTOBER.getValue() ? year + 1 : year; | |
} | |
@Override | |
public <R extends Temporal> R adjustInto(R temporal, long newFiscalYear) { | |
long newYear = temporal.get(MONTH_OF_YEAR) >= OCTOBER.getValue() ? newFiscalYear - 1 : newFiscalYear; | |
return (R) temporal.with(YEAR, newYear); | |
} | |
}, | |
/** | |
* As with calendar years, the fiscal year is also divided into quarters. Quarter 1 of each Fiscal Year begins | |
* Oct 1st. Quarter 2 starts January 1st. Quarter 3 on April 1st (no joke). And Quarter 4 begins on August 1st. | |
*/ | |
FISCAL_QUARTER { | |
@Override | |
public TemporalUnit getBaseUnit() { | |
return IsoFields.QUARTER_OF_YEAR.getBaseUnit(); | |
} | |
@Override | |
public TemporalUnit getRangeUnit() { | |
return IsoFields.QUARTER_OF_YEAR.getRangeUnit(); | |
} | |
@Override | |
public ValueRange range() { | |
return IsoFields.QUARTER_OF_YEAR.range(); | |
} | |
@Override | |
public boolean isSupportedBy(TemporalAccessor temporalAccessor) { | |
return IsoFields.QUARTER_OF_YEAR.isSupportedBy(temporalAccessor); | |
} | |
@Override | |
public ValueRange rangeRefinedBy(TemporalAccessor temporalAccessor) { | |
return IsoFields.QUARTER_OF_YEAR.rangeRefinedBy(temporalAccessor); | |
} | |
@Override | |
public long getFrom(TemporalAccessor temporalAccessor) { | |
long actualQuarter = temporalAccessor.get(IsoFields.QUARTER_OF_YEAR); | |
return actualQuarter % 4 + 1; | |
} | |
@Override | |
public <R extends Temporal> R adjustInto(R temporal, long newFyQuarter) { | |
long newQuarter = newFyQuarter == 1 ? 4 : newFyQuarter - 1; | |
return (R) temporal.with(IsoFields.QUARTER_OF_YEAR, newQuarter); | |
} | |
}; | |
/** | |
* Always returns true as the fields enumerated are all date based. | |
* | |
* @return true | |
*/ | |
@Override | |
public boolean isDateBased() { | |
return true; | |
} | |
/** | |
* Always returns false as the fields enumerated are all date based. | |
* | |
* @return false | |
*/ | |
@Override | |
public boolean isTimeBased() { | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.jupiter.api.Test; | |
import java.time.LocalDate; | |
import java.time.Month; | |
import java.time.YearMonth; | |
import java.time.temporal.IsoFields; | |
import java.util.stream.IntStream; | |
import java.util.stream.Stream; | |
import static java.time.Month.*; | |
import static org.assertj.core.api.Assertions.assertThat; | |
public class FederalFieldTest { | |
@Test | |
void fiscal_year_on_the_first_for_every_month() { | |
final int year = 2018; | |
IntStream.rangeClosed(JANUARY.getValue(), SEPTEMBER.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
}); | |
IntStream.rangeClosed(OCTOBER.getValue(), DECEMBER.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
}); | |
} | |
@Test | |
void fiscal_year_transitions() { | |
final int year = 2016; | |
assertThat(LocalDate.of(year, SEPTEMBER, 28).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
assertThat(LocalDate.of(year, SEPTEMBER, 30).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
assertThat(LocalDate.of(year, OCTOBER, 1).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
assertThat(LocalDate.of(year, OCTOBER, 2).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
assertThat(LocalDate.of(year, DECEMBER, 30).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
assertThat(LocalDate.of(year, DECEMBER, 31).get(FederalField.FISCAL_YEAR)).isEqualTo(year + 1); | |
assertThat(LocalDate.of(year, JANUARY, 1).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
assertThat(LocalDate.of(year, JANUARY, 2).get(FederalField.FISCAL_YEAR)).isEqualTo(year); | |
} | |
@Test | |
void adjusting_into_fiscal_year_no_change() { | |
LocalDate oct1 = LocalDate.of(2018, OCTOBER, 1); | |
LocalDate oct1fy19 = oct1.with(FederalField.FISCAL_YEAR, 2019); | |
assertThat(oct1fy19).isEqualTo(oct1); | |
LocalDate dec31 = LocalDate.of(2018, DECEMBER, 31); | |
LocalDate dec31fy19 = dec31.with(FederalField.FISCAL_YEAR, 2019); | |
assertThat(dec31fy19).isEqualTo(dec31); | |
} | |
@Test | |
void adjusting_into_fiscal_year_changes_year() { | |
LocalDate sep30 = LocalDate.of(2018, SEPTEMBER, 30); | |
LocalDate sep30fy19 = sep30.with(FederalField.FISCAL_YEAR, 2019); | |
assertThat(sep30fy19).isEqualTo(LocalDate.of(2019, SEPTEMBER, 30)); | |
LocalDate jan1 = LocalDate.of(2018, JANUARY, 1); | |
LocalDate jan1fy19 = jan1.with(FederalField.FISCAL_YEAR, 2019); | |
assertThat(jan1fy19).isEqualTo(LocalDate.of(2019, JANUARY, 1)); | |
} | |
@Test | |
void fiscal_year_quarter_on_the_first_for_every_month() { | |
final int year = 2018; | |
IntStream.rangeClosed(JANUARY.getValue(), MARCH.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
}); | |
IntStream.rangeClosed(APRIL.getValue(), JUNE.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
}); | |
IntStream.rangeClosed(JULY.getValue(), SEPTEMBER.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
}); | |
IntStream.rangeClosed(OCTOBER.getValue(), DECEMBER.getValue()).mapToObj(Month::of).forEachOrdered(month -> { | |
assertThat(LocalDate.of(year, month, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
assertThat(YearMonth.of(year, month).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
}); | |
} | |
@Test | |
void fiscal_year_quarter_transitions() { | |
final int year = 2016; | |
assertThat(LocalDate.of(year, SEPTEMBER, 28).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
assertThat(LocalDate.of(year, SEPTEMBER, 30).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
assertThat(LocalDate.of(year, OCTOBER, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
assertThat(LocalDate.of(year, OCTOBER, 2).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
assertThat(LocalDate.of(year, DECEMBER, 30).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
assertThat(LocalDate.of(year, DECEMBER, 31).get(FederalField.FISCAL_QUARTER)).isEqualTo(1); | |
assertThat(LocalDate.of(year, JANUARY, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
assertThat(LocalDate.of(year, JANUARY, 2).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
assertThat(LocalDate.of(year, MARCH, 30).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
assertThat(LocalDate.of(year, MARCH, 31).get(FederalField.FISCAL_QUARTER)).isEqualTo(2); | |
assertThat(LocalDate.of(year, APRIL, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
assertThat(LocalDate.of(year, APRIL, 2).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
assertThat(LocalDate.of(year, JUNE, 29).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
assertThat(LocalDate.of(year, JUNE, 30).get(FederalField.FISCAL_QUARTER)).isEqualTo(3); | |
assertThat(LocalDate.of(year, JULY, 1).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
assertThat(LocalDate.of(year, JULY, 2).get(FederalField.FISCAL_QUARTER)).isEqualTo(4); | |
} | |
@Test | |
void adjusting_into_fiscal_quarter_no_change() { | |
final int year = 2017; | |
LocalDate oct1 = LocalDate.of(year, OCTOBER, 1); | |
LocalDate oct1q1 = oct1.with(FederalField.FISCAL_QUARTER, 1); | |
assertThat(oct1q1).isEqualTo(oct1); | |
LocalDate dec31 = LocalDate.of(year, DECEMBER, 31); | |
LocalDate dec31q1 = dec31.with(FederalField.FISCAL_QUARTER, 1); | |
assertThat(dec31q1).isEqualTo(dec31); | |
LocalDate jan1 = LocalDate.of(year, JANUARY, 1); | |
LocalDate jan1q2 = jan1.with(FederalField.FISCAL_QUARTER, 2); | |
assertThat(jan1q2).isEqualTo(jan1q2); | |
LocalDate mar31 = LocalDate.of(year, MARCH, 31); | |
LocalDate mar31q2 = mar31.with(FederalField.FISCAL_QUARTER, 2); | |
assertThat(mar31q2).isEqualTo(mar31); | |
LocalDate apr1 = LocalDate.of(year, APRIL, 1); | |
LocalDate apr1q3 = apr1.with(FederalField.FISCAL_QUARTER, 3); | |
assertThat(apr1q3).isEqualTo(apr1); | |
LocalDate jun30 = LocalDate.of(year, JUNE, 30); | |
LocalDate jun30q3 = jun30.with(FederalField.FISCAL_QUARTER, 3); | |
assertThat(jun30q3).isEqualTo(jun30); | |
LocalDate jul1 = LocalDate.of(year, JULY, 1); | |
LocalDate jul1q4 = jul1.with(FederalField.FISCAL_QUARTER, 4); | |
assertThat(jul1q4).isEqualTo(jul1); | |
LocalDate sep30 = LocalDate.of(year, SEPTEMBER, 30); | |
LocalDate sep30q4 = sep30.with(FederalField.FISCAL_QUARTER, 4); | |
assertThat(sep30q4).isEqualTo(sep30); | |
} | |
@Test | |
void adjusting_into_fiscal_quarter_changes_month() { | |
final int year = 2018; | |
assertThat(YearMonth.of(year, JANUARY).with(FederalField.FISCAL_QUARTER, 1)) | |
.isEqualTo(YearMonth.of(year, OCTOBER)); | |
assertThat(YearMonth.of(year, FEBRUARY).with(FederalField.FISCAL_QUARTER, 1)) | |
.isEqualTo(YearMonth.of(year, NOVEMBER)); | |
assertThat(YearMonth.of(year, MARCH).with(FederalField.FISCAL_QUARTER, 1)) | |
.isEqualTo(YearMonth.of(year, DECEMBER)); | |
assertThat(YearMonth.of(year, OCTOBER).with(FederalField.FISCAL_QUARTER, 4)) | |
.isEqualTo(YearMonth.of(year, JULY)); | |
assertThat(YearMonth.of(year, NOVEMBER).with(FederalField.FISCAL_QUARTER, 4)) | |
.isEqualTo(YearMonth.of(year, AUGUST)); | |
assertThat(YearMonth.of(year, DECEMBER).with(FederalField.FISCAL_QUARTER, 4)) | |
.isEqualTo(YearMonth.of(year, SEPTEMBER)); | |
assertThat(YearMonth.of(year, JANUARY).with(FederalField.FISCAL_QUARTER, 3)) | |
.isEqualTo(YearMonth.of(year, APRIL)); | |
assertThat(YearMonth.of(year, FEBRUARY).with(FederalField.FISCAL_QUARTER, 3)) | |
.isEqualTo(YearMonth.of(year, MAY)); | |
assertThat(YearMonth.of(year, MARCH).with(FederalField.FISCAL_QUARTER, 3)) | |
.isEqualTo(YearMonth.of(year, JUNE)); | |
assertThat(YearMonth.of(year, OCTOBER).with(FederalField.FISCAL_QUARTER, 2)) | |
.isEqualTo(YearMonth.of(year, JANUARY)); | |
assertThat(YearMonth.of(year, NOVEMBER).with(FederalField.FISCAL_QUARTER, 2)) | |
.isEqualTo(YearMonth.of(year, FEBRUARY)); | |
assertThat(YearMonth.of(year, DECEMBER).with(FederalField.FISCAL_QUARTER, 2)) | |
.isEqualTo(YearMonth.of(year, MARCH)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment