EasterVariable extends AbstractSingleTsVariable implements IEasterVariable { @Override public void data(TsPeriod start, DataBlock data) { data.set(0); int freq = start.getFrequency().intValue(); if ((freq != 12 && freq != 4) || dur_ < 1 || dur_ > 25) { return; } int n = data.getLength(); int c = 12 / freq; int y0 = start.getYear(); int p0 = start.getPosition() * c; if (p0 > 3) { p0 -= 12; ++y0; } int idx = (3 - p0) / c; if (idx > n) { return; } double dur = dur_; GregorianCalendar easter = new GregorianCalendar(); for (int y = y0; idx <= n; ++y, idx += freq) { easter.setTime(Utilities.easter(y).getTime()); int day = easter.get(GregorianCalendar.DAY_OF_MONTH); int month = easter.get(GregorianCalendar.MONTH); if (!m_e) { --day; } else if (m_m) { if (day == 31) { day = 1; ++month; } else { ++day; } } double m = 0, a = 0; if (type_ == Correction.Simple) { if (month == 2 || day == 0) { m = .5; a = -.5; } else if (day >= dur_) { m = -.5; a = .5; } else { m = (dur - day) / dur - .5; a = -m; } } else { double m_av = 0, a_av = 0; if (type_ == Correction.PreComputed) { m_av = EMeans_Mar[25 - dur_]; a_av = EMeans_Apr[25 - dur_]; } else { m_av = (15 + dur) / (2 * Utilities.LUNARY); a_av = 1 - m_av; } if (month == 2) { m = 1 - m_av; a = -a_av; } else if (day >= dur_) { m = -m_av; a = 1 - a_av; } else { m = (dur - day) / dur - m_av; a = day / dur - a_av; } } if (idx - 1 >= 0) { data.set(idx - 1, m); } if (idx < n) { data.set(idx, a); } } } EasterVariable(); @Override int getDuration(); @Override void setDuration(int value); Correction getType(); void setType(Correction value); boolean hasEaster(); boolean hasEasterMonday(); void includeEaster(boolean included); void includeEasterMonday(boolean included); @Override String getDescription(TsFrequency context); @Override void data(TsPeriod start, DataBlock data); @Override boolean isSignificant(TsDomain domain);  }
@Test public void testShort() { EasterVariable var = new EasterVariable(); DataBlock x = new DataBlock(12), y = new DataBlock(12); TsPeriod start = new TsPeriod(TsFrequency.Monthly, 1980, 0); var.data(start, x); for (int i = 0; i < 12; ++i) { DataBlock yc = y.range(i, i+1); var.data(start, yc); start.move(1); } assertTrue(x.distance(y)==0); }