package org.ripple.power.timer; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public class Quarter extends RegularTimer implements Serializable { /** * */ private static final long serialVersionUID = 1L; public static final int FIRST_QUARTER = 1; public static final int LAST_QUARTER = 4; public static final int[] FIRST_MONTH_IN_QUARTER = { 0, MonthConstants.JANUARY, MonthConstants.APRIL, MonthConstants.JULY, MonthConstants.OCTOBER }; public static final int[] LAST_MONTH_IN_QUARTER = { 0, MonthConstants.MARCH, MonthConstants.JUNE, MonthConstants.SEPTEMBER, MonthConstants.DECEMBER }; private short year; private byte quarter; private long firstMillisecond; private long lastMillisecond; public Quarter() { this(new Date()); } public Quarter(int quarter, int year) { if ((quarter < FIRST_QUARTER) || (quarter > LAST_QUARTER)) { throw new IllegalArgumentException("Quarter outside valid range."); } this.year = (short) year; this.quarter = (byte) quarter; peg(Calendar.getInstance()); } public Quarter(int quarter, Year year) { if ((quarter < FIRST_QUARTER) || (quarter > LAST_QUARTER)) { throw new IllegalArgumentException("Quarter outside valid range."); } this.year = (short) year.getYear(); this.quarter = (byte) quarter; peg(Calendar.getInstance()); } public Quarter(Date time) { this(time, TimeZone.getDefault()); } public Quarter(Date time, TimeZone zone) { this(time, zone, Locale.getDefault()); } public Quarter(Date time, TimeZone zone, Locale locale) { Calendar calendar = Calendar.getInstance(zone, locale); calendar.setTime(time); int month = calendar.get(Calendar.MONTH) + 1; this.quarter = (byte) SerialDate.monthCodeToQuarter(month); this.year = (short) calendar.get(Calendar.YEAR); peg(calendar); } public int getQuarter() { return this.quarter; } public Year getYear() { return new Year(this.year); } public int getYearValue() { return this.year; } @Override public long getFirstMillisecond() { return this.firstMillisecond; } @Override public long getLastMillisecond() { return this.lastMillisecond; } @Override public void peg(Calendar calendar) { this.firstMillisecond = getFirstMillisecond(calendar); this.lastMillisecond = getLastMillisecond(calendar); } @Override public RegularTimer previous() { Quarter result; if (this.quarter > FIRST_QUARTER) { result = new Quarter(this.quarter - 1, this.year); } else { if (this.year > 1900) { result = new Quarter(LAST_QUARTER, this.year - 1); } else { result = null; } } return result; } @Override public RegularTimer next() { Quarter result; if (this.quarter < LAST_QUARTER) { result = new Quarter(this.quarter + 1, this.year); } else { if (this.year < 9999) { result = new Quarter(FIRST_QUARTER, this.year + 1); } else { result = null; } } return result; } @Override public long getSerialIndex() { return this.year * 4L + this.quarter; } @Override public boolean equals(Object obj) { if (obj != null) { if (obj instanceof Quarter) { Quarter target = (Quarter) obj; return (this.quarter == target.getQuarter() && (this.year == target .getYearValue())); } else { return false; } } else { return false; } } @Override public int hashCode() { int result = 17; result = 37 * result + this.quarter; result = 37 * result + this.year; return result; } @Override public int compareTo(Object o1) { int result; if (o1 instanceof Quarter) { Quarter q = (Quarter) o1; result = this.year - q.getYearValue(); if (result == 0) { result = this.quarter - q.getQuarter(); } } else if (o1 instanceof RegularTimer) { result = 0; } else { result = 1; } return result; } @Override public String toString() { return "Q" + this.quarter + "/" + this.year; } @Override public long getFirstMillisecond(Calendar calendar) { int month = Quarter.FIRST_MONTH_IN_QUARTER[this.quarter]; calendar.set(this.year, month - 1, 1, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } @Override public long getLastMillisecond(Calendar calendar) { int month = Quarter.LAST_MONTH_IN_QUARTER[this.quarter]; int eom = SerialDate.lastDayOfMonth(month, this.year); calendar.set(this.year, month - 1, eom, 23, 59, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } public static Quarter parseQuarter(String s) { int i = s.indexOf("Q"); if (i == -1) { throw new RuntimeException("Missing Q."); } if (i == s.length() - 1) { throw new RuntimeException("Q found at end of string."); } String qstr = s.substring(i + 1, i + 2); int quarter = Integer.parseInt(qstr); String remaining = s.substring(0, i) + s.substring(i + 2, s.length()); remaining = remaining.replace('/', ' '); remaining = remaining.replace(',', ' '); remaining = remaining.replace('-', ' '); Year year = Year.parseYear(remaining.trim()); Quarter result = new Quarter(quarter, year); return result; } }