1 /* 2 * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * * Neither the name of JSR-310 nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.threeten.bp.chrono; 33 34 import static org.threeten.bp.temporal.ChronoField.ERA; 35 36 import java.io.DataInput; 37 import java.io.DataOutput; 38 import java.io.IOException; 39 import java.util.Locale; 40 41 import org.threeten.bp.DateTimeException; 42 import org.threeten.bp.format.DateTimeFormatterBuilder; 43 import org.threeten.bp.format.TextStyle; 44 import org.threeten.bp.temporal.ChronoField; 45 import org.threeten.bp.temporal.ChronoUnit; 46 import org.threeten.bp.temporal.Temporal; 47 import org.threeten.bp.temporal.TemporalField; 48 import org.threeten.bp.temporal.TemporalQueries; 49 import org.threeten.bp.temporal.TemporalQuery; 50 import org.threeten.bp.temporal.UnsupportedTemporalTypeException; 51 import org.threeten.bp.temporal.ValueRange; 52 53 /** 54 * An era in the Hijrah calendar system. 55 * <p> 56 * The Hijrah calendar system has two eras. 57 * The date {@code 0001-01-01 (Hijrah)} is {@code 622-06-19 (ISO)}. 58 * <p> 59 * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code HijrahEra}. 60 * Use {@code getValue()} instead.</b> 61 * 62 * <h3>Specification for implementors</h3> 63 * This is an immutable and thread-safe enum. 64 */ 65 public enum HijrahEra implements Era { 66 67 /** 68 * The singleton instance for the era before the current one, 'Before Anno Hegirae', 69 * which has the value 0. 70 */ 71 BEFORE_AH, 72 /** 73 * The singleton instance for the current era, 'Anno Hegirae', which has the value 1. 74 */ 75 AH; 76 77 //----------------------------------------------------------------------- 78 /** 79 * Obtains an instance of {@code HijrahEra} from a value. 80 * <p> 81 * The current era (from ISO date 622-06-19 onwards) has the value 1 82 * The previous era has the value 0. 83 * 84 * @param hijrahEra the era to represent, from 0 to 1 85 * @return the HijrahEra singleton, never null 86 * @throws DateTimeException if the era is invalid 87 */ of(int hijrahEra)88 public static HijrahEra of(int hijrahEra) { 89 switch (hijrahEra) { 90 case 0: 91 return BEFORE_AH; 92 case 1: 93 return AH; 94 default: 95 throw new DateTimeException("HijrahEra not valid"); 96 } 97 } 98 99 //----------------------------------------------------------------------- 100 /** 101 * Gets the era numeric value. 102 * <p> 103 * The current era (from ISO date 622-06-19 onwards) has the value 1. 104 * The previous era has the value 0. 105 * 106 * @return the era value, from 0 (BEFORE_AH) to 1 (AH) 107 */ 108 @Override getValue()109 public int getValue() { 110 return ordinal(); 111 } 112 113 //----------------------------------------------------------------------- 114 @Override isSupported(TemporalField field)115 public boolean isSupported(TemporalField field) { 116 if (field instanceof ChronoField) { 117 return field == ERA; 118 } 119 return field != null && field.isSupportedBy(this); 120 } 121 122 @Override range(TemporalField field)123 public ValueRange range(TemporalField field) { 124 if (field == ERA) { 125 return ValueRange.of(1, 1); 126 } else if (field instanceof ChronoField) { 127 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 128 } 129 return field.rangeRefinedBy(this); 130 } 131 132 @Override get(TemporalField field)133 public int get(TemporalField field) { 134 if (field == ERA) { 135 return getValue(); 136 } 137 return range(field).checkValidIntValue(getLong(field), field); 138 } 139 140 @Override getLong(TemporalField field)141 public long getLong(TemporalField field) { 142 if (field == ERA) { 143 return getValue(); 144 } else if (field instanceof ChronoField) { 145 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 146 } 147 return field.getFrom(this); 148 } 149 150 //------------------------------------------------------------------------- 151 @Override adjustInto(Temporal temporal)152 public Temporal adjustInto(Temporal temporal) { 153 return temporal.with(ERA, getValue()); 154 } 155 156 @SuppressWarnings("unchecked") 157 @Override query(TemporalQuery<R> query)158 public <R> R query(TemporalQuery<R> query) { 159 if (query == TemporalQueries.precision()) { 160 return (R) ChronoUnit.ERAS; 161 } 162 if (query == TemporalQueries.chronology() || query == TemporalQueries.zone() || 163 query == TemporalQueries.zoneId() || query == TemporalQueries.offset() || 164 query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) { 165 return null; 166 } 167 return query.queryFrom(this); 168 } 169 170 //----------------------------------------------------------------------- 171 @Override getDisplayName(TextStyle style, Locale locale)172 public String getDisplayName(TextStyle style, Locale locale) { 173 return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).format(this); 174 } 175 176 /** 177 * Returns the proleptic year from this era and year of era. 178 * 179 * @param yearOfEra the year of Era 180 * @return the computed prolepticYear 181 */ prolepticYear(int yearOfEra)182 int prolepticYear(int yearOfEra) { 183 return (this == HijrahEra.AH ? yearOfEra : 1 - yearOfEra); 184 } 185 186 //----------------------------------------------------------------------- writeReplace()187 private Object writeReplace() { 188 return new Ser(Ser.HIJRAH_ERA_TYPE, this); 189 } 190 writeExternal(DataOutput out)191 void writeExternal(DataOutput out) throws IOException { 192 out.writeByte(this.getValue()); 193 } 194 readExternal(DataInput in)195 static HijrahEra readExternal(DataInput in) throws IOException { 196 byte eraValue = in.readByte(); 197 return HijrahEra.of(eraValue); 198 } 199 200 } 201