@Override public Integer getValue(T context) { PlainDate date = context.get(CALENDAR_DATE); return Integer.valueOf(this.getCalendarWeek(date)); }
@Override public boolean isValid( T context, Integer value ) { if (value == null) { return false; } int v = value.intValue(); if ( this.owner.isYearRelated() && (v >= 1) && (v <= 52) ) { return true; } if (!this.owner.isYearRelated() || (v == 53)) { PlainDate date = context.get(CALENDAR_DATE); return ((v >= 1) && (v <= this.getMaxCalendarWeek(date))); } else { return false; } }
@Override public T withValue( T context, Integer value, boolean lenient ) { PlainDate date = context.get(CALENDAR_DATE); if ((value == null) || (!lenient && !this.isValid(context, value))) { throw new IllegalArgumentException( "Invalid value: " + value + " (context=" + context + ")"); } return context.with( CALENDAR_DATE, this.setCalendarWeek(date, value.intValue()) ); }
private int getCalendarWeek(PlainDate date) { int scaledDay = ( this.owner.isYearRelated() ? date.getDayOfYear() : date.getDayOfMonth()); int wCurrent = getFirstCalendarWeekAsDay(date, 0); if (wCurrent <= scaledDay) { int result = ((scaledDay - wCurrent) / 7) + 1; if ( (result >= 53) || (!this.owner.isYearRelated() && (result >= 5)) ) { int wNext = getFirstCalendarWeekAsDay(date, 1) + getLengthOfYM(date, 0); if (wNext <= scaledDay) { result = 1; } } return result; } else { int wPrevious = getFirstCalendarWeekAsDay(date, -1); int dayCurrent = scaledDay + getLengthOfYM(date, -1); return ((dayCurrent - wPrevious) / 7) + 1; } }
private int getMaxCalendarWeek(PlainDate date) { int scaledDay = ( this.owner.isYearRelated() ? date.getDayOfYear() : date.getDayOfMonth()); int wCurrent = getFirstCalendarWeekAsDay(date, 0); if (wCurrent <= scaledDay) { int wNext = getFirstCalendarWeekAsDay(date, 1) + getLengthOfYM(date, 0); if (wNext <= scaledDay) { // reference date points to next week cycle try { int wStart = getFirstCalendarWeekAsDay(date, 1); wNext = getFirstCalendarWeekAsDay(date, 2) + getLengthOfYM(date, 1); wCurrent = wStart; } catch (RuntimeException re) { wNext += 7; // theoretical rare edge case near the end of time axis } } return (wNext - wCurrent) / 7; } else { int wPrevious = getFirstCalendarWeekAsDay(date, -1); wCurrent = wCurrent + getLengthOfYM(date, -1); return (wCurrent - wPrevious) / 7; } }
private int getFirstCalendarWeekAsDay( PlainDate date, int shift // -1 = Vorjahr/-monat, 0 = aktuell, +1 = Folgejahr/-monat ) { Weekday wd = this.getWeekdayStart(date, shift); Weekmodel model = this.owner.getModel(); int dow = wd.getValue(model); return ( (dow <= 8 - model.getMinimalDaysInFirstWeek()) ? 2 - dow : 9 - dow ); }
@Override public ChronoElement<?> getChildAtFloor(T context) { return this.getChild(); }
@Override public ChronoElement<?> getChildAtCeiling(T context) { return this.getChild(); }
@Override public Integer getMaximum(T context) { PlainDate date = context.get(CALENDAR_DATE); return Integer.valueOf(this.getMaxCalendarWeek(date)); }
@Override protected <T extends ChronoEntity<T>> ElementRule<T, Integer> derive(Chronology<T> chronology) { if (chronology.isRegistered(CALENDAR_DATE)) { if (this.isBounded()) { return new BWRule<>(this); } else { return new CWRule<>(this); } } return null; }
private PlainDate setCalendarWeek( PlainDate date, int value ) { int old = this.getCalendarWeek(date); if (value == old) { return date; } else { int delta = 7 * (value - old); return date.withDaysSinceUTC(date.getDaysSinceUTC() + delta); } }