그래, 나는 일반 JostTime 라이브러리를 사용하여 소매/회계 (4-5-4) 일정을 구현하려고 시도했다. 나는 이미 내 회사에 대한 구체적인 사례를 찾았지만 일반적인 경우 (주로 시작 연도와 윤년을 결정할 때)가 살인자입니다. 예를 들어 1 ISO 연도 동안 2 회계 연도 (보통 364 일, 보통)가 시작되는 날짜 집합이 있습니다.생성자 종료 전에 최종 변수에 액세스
올해 시작 규칙을 결정하는 과정에서 나는 ISO 시작일의 어느 시점에 기초하는지에 따라 연도 시작을 결정하기위한 추상 클래스와 몇 가지 구체적인 클래스를 작성했습니다.
(깎았 다운) 추상 클래스 (범위의 1/7에 날짜 - 2/28)
private static abstract class SimpleFiscalYearEndPattern implements FiscalYearEndPattern {
protected final int leapYearCountOffset;
protected final int doomsdayOffset;
private final int startingDayOfWeek;
private final int yearOffset;
private final long millisFromEpochToFiscalYearStart;
private final long millisElapsedToEpochDividedByTwo;
/**
* Restricted constructor
* @param fiscalYear
* @param startingOn
* @param inFirstWeek
*/
protected SimpleFiscalYearEndPattern(final int fiscalYear, final LocalDate startingOn, final MonthDay inFirstWeek) {
this.yearOffset = fiscalYear - startingOn.getYear();
this.doomsdayOffset = getDoomsdayOffset(inFirstWeek);
this.startingDayOfWeek = startingOn.getDayOfWeek();
final int startingDoomsday = getDoomsdayOffset(new MonthDay(startingOn, REFERENCE_CHRONOLOGY));
// If the starting doomsday is a later day-of-week, it needs to become negative.
this.leapYearCountOffset = calculateLeapYearCountOffset(startingDoomsday : doomsdayOffset, doomsdayOffset);
final int leapYearsBefore = getPreviousLeapYears(fiscalYearBeforeEpoch);
}
}
(아래 깎았) 콘크리트 클래스 :
private static final class BeforeLeapYearEndPattern extends SimpleFiscalYearEndPattern {
private static final int FIRST_YEAR_LEAP_YEAR_OFFSET = -1;
private BeforeLeapYearEndPattern(final int fiscalYear, final LocalDate startingOn, final MonthDay onOrBefore) {
super(fiscalYear, startingOn, onOrBefore);
}
public static final BeforeLeapYearEndPattern create(final int fiscalYear, final LocalDate startingOn, final MonthDay onOrBefore) {
return new BeforeLeapYearEndPattern(fiscalYear, startingOn, onOrBefore);
}
/* (non-Javadoc)
* @see ext.site.time.chrono.FiscalYearEndPatternBuilder.SimpleFiscalYearEndPattern#getPreviousLeapYears(int)
*/
@Override
protected int getPreviousLeapYears(final int isoYear) {
// Formula gets count of leap years, including current, so subtract a year first.
final int previousYear = isoYear - 1;
// If the doomsday offset is -1, then the first year is a leap year.
return (previousYear + leapYearCountOffset + (previousYear/4) - (previousYear/100) + (previousYear/400))/7 + (leapYearCountOffset == FIRST_YEAR_LEAP_YEAR_OFFSET ? 1 : 0);
}
이 있을지 예를 들어, 추상 수퍼 클래스에서 (최종 변수로) getPreviousLeapYears()
에 정의되어있는 수퍼 클래스 생성자에서 호출 된 leapYearCountOffset
을 사용합니다. 수퍼 클래스 생성자에서 수식을 반복하고 싶지는 않습니다. 3/1-12/31 범위의 날짜에서는 다릅니다. 구체적인 하위 클래스에 인스턴스 변수를 배치하고 싶지는 않습니다. 다른 계산에는 여전히 leapYearCountOffset
이 필요합니다.
질문 : (하위 클래스) 메서드가 생성자에서 호출 될 때 leapYearCountOffset
의 상태는 무엇입니까? 그것은 어떤 방식 으로든 보장됩니까? 아니면 컴파일러의 어딘가에서 변할 수있는 무언가입니까? 그리고 그것을 어떻게 알아낼 수 있을까요? 나는 이미 컴파일러가 일부 문장을 자유롭게 배열 할 수 있다는 것을 알고 있지만, 여기서 일어날 것인가?
그러나 성능 고려 사항을 위해 (구현에 따라) 컴파일러가 배정을 재조정 할 수 있습니까? 그래서, 내 순서가 그 순서대로 평가되도록 보장 받는가? (내가 원하는 것을 잡을만큼 '똑똑하다')? 아니면 대신'0'으로 끝낼 수 있을까요? –
@ X-Zero, 컴파일러는 프로그램 의미를 변경하지 않는 재배정 만 허용됩니다. –
아, 그럼 나는 잘되어야합니다. @ Joni의 관심사도 생각하고 있습니다. –