37 * this list of conditions and the following disclaimer in the documentation 38 * and/or other materials provided with the distribution. 39 * 40 * * Neither the name of JSR-310 nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 48 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 49 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 50 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 54 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 package tck.java.time.calendar; 58 59 import static java.time.temporal.ChronoField.EPOCH_DAY; 60 61 import java.io.Serializable; 62 import java.util.Arrays; 63 import java.util.List; 64 import java.util.Locale; 65 66 import java.time.DateTimeException; 67 import java.time.temporal.ChronoField; 68 import java.time.temporal.TemporalAccessor; 69 import java.time.temporal.ValueRange; 70 import java.time.temporal.Chrono; 71 import java.time.temporal.ChronoLocalDate; 72 import java.time.temporal.Era; 73 74 /** 75 * The Coptic calendar system. 76 * <p> 77 * This chronology defines the rules of the Coptic calendar system. 78 * This calendar system is primarily used in Christian Egypt. 79 * Dates are aligned such that {@code 0001AM-01-01 (Coptic)} is {@code 0284-08-29 (ISO)}. 80 * <p> 81 * The fields are defined as follows: 82 * <p><ul> 83 * <li>era - There are two eras, the current 'Era of the Martyrs' (AM) and the previous era (ERA_ERA_BEFORE_AM). 84 * <li>year-of-era - The year-of-era for the current era increases uniformly from the epoch at year one. 85 * For the previous era the year increases from one as time goes backwards. 86 * <li>proleptic-year - The proleptic year is the same as the year-of-era for the 87 * current era. For the previous era, years have zero, then negative values. 88 * <li>month-of-year - There are 13 months in a Coptic year, numbered from 1 to 13. 89 * <li>day-of-month - There are 30 days in each of the first 12 Coptic months, numbered 1 to 30. 90 * The 13th month has 5 days, or 6 in a leap year, numbered 1 to 5 or 1 to 6. 91 * <li>day-of-year - There are 365 days in a standard Coptic year and 366 in a leap year. 92 * The days are numbered from 1 to 365 or 1 to 366. 93 * <li>leap-year - Leap years occur every 4 years. 94 * </ul><p> 95 * 96 * <h4>Implementation notes</h4> 97 * This class is immutable and thread-safe. 98 */ 99 public final class CopticChrono extends Chrono<CopticChrono> implements Serializable { 100 101 /** 102 * Singleton instance of the Coptic chronology. 103 */ 104 public static final CopticChrono INSTANCE = new CopticChrono(); 105 /** 106 * The singleton instance for the era BEFORE_AM. 107 * This has the numeric value of {@code 0}. 108 */ 109 public static final Era<CopticChrono> ERA_BEFORE_AM = CopticEra.BEFORE_AM; 110 /** 111 * The singleton instance for the era AM - 'Era of the Martyrs'. 112 * This has the numeric value of {@code 1}. 113 */ 114 public static final Era<CopticChrono> ERA_AM = CopticEra.AM; 115 116 /** 117 * Serialization version. 118 */ 119 private static final long serialVersionUID = 7291205177830286973L; 120 /** 121 * Range of months. 122 */ 123 static final ValueRange MOY_RANGE = ValueRange.of(1, 13); 124 /** 125 * Range of days. 126 */ 127 static final ValueRange DOM_RANGE = ValueRange.of(1, 5, 30); 128 /** 129 * Range of days. 130 */ 131 static final ValueRange DOM_RANGE_NONLEAP = ValueRange.of(1, 5); 132 /** 133 * Range of days. 134 */ 135 static final ValueRange DOM_RANGE_LEAP = ValueRange.of(1, 6); 136 137 /** 138 * Public Constructor to be instantiated by the ServiceLoader 139 */ 140 public CopticChrono() { 141 } 142 143 /** 144 * Resolve singleton. 145 * 146 * @return the singleton instance, not null 147 */ 148 private Object readResolve() { 149 return INSTANCE; 150 } 151 152 //----------------------------------------------------------------------- 153 /** 154 * Gets the ID of the chronology - 'Coptic'. 155 * <p> 156 * The ID uniquely identifies the {@code Chrono}. 157 * It can be used to lookup the {@code Chrono} using {@link #of(String)}. 158 * 159 * @return the chronology ID - 'Coptic' 160 * @see #getCalendarType() 161 */ 162 @Override 163 public String getId() { 164 return "Coptic"; 165 } 166 167 /** 168 * Gets the calendar type of the underlying calendar system - 'coptic'. 169 * <p> 170 * The calendar type is an identifier defined by the 171 * <em>Unicode Locale Data Markup Language (LDML)</em> specification. 172 * It can be used to lookup the {@code Chrono} using {@link #of(String)}. 173 * It can also be used as part of a locale, accessible via 174 * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'. 175 * 176 * @return the calendar system type - 'coptic' 177 * @see #getId() 178 */ 179 @Override 180 public String getCalendarType() { 181 return "coptic"; 182 } 183 184 //----------------------------------------------------------------------- 185 @Override 186 public ChronoLocalDate<CopticChrono> date(int prolepticYear, int month, int dayOfMonth) { 187 return new CopticDate(prolepticYear, month, dayOfMonth); 188 } 189 190 @Override 191 public ChronoLocalDate<CopticChrono> dateYearDay(int prolepticYear, int dayOfYear) { 192 return new CopticDate(prolepticYear, (dayOfYear - 1) / 30 + 1, (dayOfYear - 1) % 30 + 1); 193 } 194 195 @Override 196 public ChronoLocalDate<CopticChrono> date(TemporalAccessor dateTime) { 197 if (dateTime instanceof CopticDate) { 198 return (CopticDate) dateTime; 199 } 200 return CopticDate.ofEpochDay(dateTime.getLong(EPOCH_DAY)); 201 } 202 203 //----------------------------------------------------------------------- 204 /** 205 * Checks if the specified year is a leap year. 206 * <p> 207 * A Coptic proleptic-year is leap if the remainder after division by four equals three. 208 * This method does not validate the year passed in, and only has a 209 * well-defined result for years in the supported range. 210 * 211 * @param prolepticYear the proleptic-year to check, not validated for range 212 * @return true if the year is a leap year 213 */ 214 @Override 215 public boolean isLeapYear(long prolepticYear) { 216 return Math.floorMod(prolepticYear, 4) == 3; 217 } 218 219 @Override 220 public int prolepticYear(Era<CopticChrono> era, int yearOfEra) { 221 if (era instanceof CopticEra == false) { 222 throw new DateTimeException("Era must be CopticEra"); 223 } 224 return (era == CopticEra.AM ? yearOfEra : 1 - yearOfEra); 225 } 226 227 @Override 228 public Era<CopticChrono> eraOf(int eraValue) { 229 return CopticEra.of(eraValue); 230 } 231 232 @Override 233 public List<Era<CopticChrono>> eras() { 234 return Arrays.<Era<CopticChrono>>asList(CopticEra.values()); 235 } 236 237 //----------------------------------------------------------------------- 238 @Override 239 public ValueRange range(ChronoField field) { 240 switch (field) { 241 case DAY_OF_MONTH: return ValueRange.of(1, 5, 30); 242 case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, 1, 5); 243 case MONTH_OF_YEAR: return ValueRange.of(1, 13); 244 case EPOCH_MONTH: return ValueRange.of(-1000, 1000); // TODO 245 case YEAR_OF_ERA: return ValueRange.of(1, 999, 1000); // TODO 246 case YEAR: return ValueRange.of(-1000, 1000); // TODO 247 } 248 return field.range(); 249 } 250 251 } | 37 * this list of conditions and the following disclaimer in the documentation 38 * and/or other materials provided with the distribution. 39 * 40 * * Neither the name of JSR-310 nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 48 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 49 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 50 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 54 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 package tck.java.time.chrono; 58 59 import static java.time.temporal.ChronoField.EPOCH_DAY; 60 61 import java.io.Serializable; 62 import java.util.Arrays; 63 import java.util.List; 64 import java.util.Locale; 65 66 import java.time.DateTimeException; 67 import java.time.temporal.ChronoField; 68 import java.time.temporal.TemporalAccessor; 69 import java.time.temporal.ValueRange; 70 import java.time.chrono.Chronology; 71 import java.time.chrono.ChronoLocalDate; 72 import java.time.chrono.Era; 73 74 /** 75 * The Coptic calendar system. 76 * <p> 77 * This chronology defines the rules of the Coptic calendar system. 78 * This calendar system is primarily used in Christian Egypt. 79 * Dates are aligned such that {@code 0001AM-01-01 (Coptic)} is {@code 0284-08-29 (ISO)}. 80 * <p> 81 * The fields are defined as follows: 82 * <p><ul> 83 * <li>era - There are two eras, the current 'Era of the Martyrs' (AM) and the previous era (ERA_ERA_BEFORE_AM). 84 * <li>year-of-era - The year-of-era for the current era increases uniformly from the epoch at year one. 85 * For the previous era the year increases from one as time goes backwards. 86 * <li>proleptic-year - The proleptic year is the same as the year-of-era for the 87 * current era. For the previous era, years have zero, then negative values. 88 * <li>month-of-year - There are 13 months in a Coptic year, numbered from 1 to 13. 89 * <li>day-of-month - There are 30 days in each of the first 12 Coptic months, numbered 1 to 30. 90 * The 13th month has 5 days, or 6 in a leap year, numbered 1 to 5 or 1 to 6. 91 * <li>day-of-year - There are 365 days in a standard Coptic year and 366 in a leap year. 92 * The days are numbered from 1 to 365 or 1 to 366. 93 * <li>leap-year - Leap years occur every 4 years. 94 * </ul><p> 95 * 96 * <h4>Implementation notes</h4> 97 * This class is immutable and thread-safe. 98 */ 99 public final class CopticChronology extends Chronology implements Serializable { 100 101 /** 102 * Singleton instance of the Coptic chronology. 103 */ 104 public static final CopticChronology INSTANCE = new CopticChronology(); 105 /** 106 * The singleton instance for the era BEFORE_AM. 107 * This has the numeric value of {@code 0}. 108 */ 109 public static final Era ERA_BEFORE_AM = CopticEra.BEFORE_AM; 110 /** 111 * The singleton instance for the era AM - 'Era of the Martyrs'. 112 * This has the numeric value of {@code 1}. 113 */ 114 public static final Era ERA_AM = CopticEra.AM; 115 116 /** 117 * Serialization version. 118 */ 119 private static final long serialVersionUID = 7291205177830286973L; 120 /** 121 * Range of months. 122 */ 123 static final ValueRange MOY_RANGE = ValueRange.of(1, 13); 124 /** 125 * Range of days. 126 */ 127 static final ValueRange DOM_RANGE = ValueRange.of(1, 5, 30); 128 /** 129 * Range of days. 130 */ 131 static final ValueRange DOM_RANGE_NONLEAP = ValueRange.of(1, 5); 132 /** 133 * Range of days. 134 */ 135 static final ValueRange DOM_RANGE_LEAP = ValueRange.of(1, 6); 136 137 /** 138 * Public Constructor to be instantiated by the ServiceLoader 139 */ 140 public CopticChronology() { 141 } 142 143 /** 144 * Resolve singleton. 145 * 146 * @return the singleton instance, not null 147 */ 148 private Object readResolve() { 149 return INSTANCE; 150 } 151 152 //----------------------------------------------------------------------- 153 /** 154 * Gets the ID of the chronology - 'Coptic'. 155 * <p> 156 * The ID uniquely identifies the {@code Chronology}. 157 * It can be used to lookup the {@code Chronology} using {@link #of(String)}. 158 * 159 * @return the chronology ID - 'Coptic' 160 * @see #getCalendarType() 161 */ 162 @Override 163 public String getId() { 164 return "Coptic"; 165 } 166 167 /** 168 * Gets the calendar type of the underlying calendar system - 'coptic'. 169 * <p> 170 * The calendar type is an identifier defined by the 171 * <em>Unicode Locale Data Markup Language (LDML)</em> specification. 172 * It can be used to lookup the {@code Chronology} using {@link #of(String)}. 173 * It can also be used as part of a locale, accessible via 174 * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'. 175 * 176 * @return the calendar system type - 'coptic' 177 * @see #getId() 178 */ 179 @Override 180 public String getCalendarType() { 181 return "coptic"; 182 } 183 184 //----------------------------------------------------------------------- 185 @Override 186 public CopticDate date(int prolepticYear, int month, int dayOfMonth) { 187 return new CopticDate(prolepticYear, month, dayOfMonth); 188 } 189 190 @Override 191 public CopticDate dateYearDay(int prolepticYear, int dayOfYear) { 192 return new CopticDate(prolepticYear, (dayOfYear - 1) / 30 + 1, (dayOfYear - 1) % 30 + 1); 193 } 194 195 @Override 196 public CopticDate date(TemporalAccessor dateTime) { 197 if (dateTime instanceof CopticDate) { 198 return (CopticDate) dateTime; 199 } 200 return CopticDate.ofEpochDay(dateTime.getLong(EPOCH_DAY)); 201 } 202 203 //----------------------------------------------------------------------- 204 /** 205 * Checks if the specified year is a leap year. 206 * <p> 207 * A Coptic proleptic-year is leap if the remainder after division by four equals three. 208 * This method does not validate the year passed in, and only has a 209 * well-defined result for years in the supported range. 210 * 211 * @param prolepticYear the proleptic-year to check, not validated for range 212 * @return true if the year is a leap year 213 */ 214 @Override 215 public boolean isLeapYear(long prolepticYear) { 216 return Math.floorMod(prolepticYear, 4) == 3; 217 } 218 219 @Override 220 public int prolepticYear(Era era, int yearOfEra) { 221 if (era instanceof CopticEra == false) { 222 throw new DateTimeException("Era must be CopticEra"); 223 } 224 return (era == CopticEra.AM ? yearOfEra : 1 - yearOfEra); 225 } 226 227 @Override 228 public Era eraOf(int eraValue) { 229 return CopticEra.of(eraValue); 230 } 231 232 @Override 233 public List<Era> eras() { 234 return Arrays.<Era>asList(CopticEra.values()); 235 } 236 237 //----------------------------------------------------------------------- 238 @Override 239 public ValueRange range(ChronoField field) { 240 switch (field) { 241 case DAY_OF_MONTH: return ValueRange.of(1, 5, 30); 242 case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, 1, 5); 243 case MONTH_OF_YEAR: return ValueRange.of(1, 13); 244 case EPOCH_MONTH: return ValueRange.of(-1000, 1000); // TODO 245 case YEAR_OF_ERA: return ValueRange.of(1, 999, 1000); // TODO 246 case YEAR: return ValueRange.of(-1000, 1000); // TODO 247 } 248 return field.range(); 249 } 250 251 } |