001/* 002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos 003 * 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions are met: 008 * 009 * * Redistributions of source code must retain the above copyright notice, 010 * this list of conditions and the following disclaimer. 011 * 012 * * Redistributions in binary form must reproduce the above copyright notice, 013 * this list of conditions and the following disclaimer in the documentation 014 * and/or other materials provided with the distribution. 015 * 016 * * Neither the name of JSR-310 nor the names of its contributors 017 * may be used to endorse or promote products derived from this software 018 * without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 */ 032package org.threeten.bp.jdk8; 033 034import static org.threeten.bp.temporal.ChronoField.DAY_OF_MONTH; 035import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; 036import static org.threeten.bp.temporal.ChronoField.ERA; 037import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; 038import static org.threeten.bp.temporal.ChronoField.YEAR; 039import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA; 040 041import java.util.Objects; 042 043import org.threeten.bp.LocalTime; 044import org.threeten.bp.format.DateTimeFormatter; 045import org.threeten.bp.temporal.Chrono; 046import org.threeten.bp.temporal.ChronoField; 047import org.threeten.bp.temporal.ChronoLocalDate; 048import org.threeten.bp.temporal.ChronoLocalDateTime; 049import org.threeten.bp.temporal.Era; 050import org.threeten.bp.temporal.Temporal; 051import org.threeten.bp.temporal.TemporalAdder; 052import org.threeten.bp.temporal.TemporalAdjuster; 053import org.threeten.bp.temporal.TemporalField; 054import org.threeten.bp.temporal.TemporalQueries; 055import org.threeten.bp.temporal.TemporalQuery; 056import org.threeten.bp.temporal.TemporalSubtractor; 057import org.threeten.bp.temporal.TemporalUnit; 058 059/** 060 * A temporary class providing implementations that will become default interface 061 * methods once integrated into JDK 8. 062 * 063 * @param <C> the chronology of this date-time 064 */ 065public abstract class DefaultInterfaceChronoLocalDate<C extends Chrono<C>> 066 extends DefaultInterfaceTemporal 067 implements ChronoLocalDate<C> { 068 069 @Override 070 public Era<C> getEra() { 071 return getChrono().eraOf(get(ERA)); 072 } 073 074 @Override 075 public boolean isLeapYear() { 076 return getChrono().isLeapYear(getLong(YEAR)); 077 } 078 079 @Override 080 public int lengthOfYear() { 081 return (isLeapYear() ? 366 : 365); 082 } 083 084 @Override 085 public boolean isSupported(TemporalField field) { 086 if (field instanceof ChronoField) { 087 return ((ChronoField) field).isDateField(); 088 } 089 return field != null && field.doIsSupported(this); 090 } 091 092 //------------------------------------------------------------------------- 093 @Override 094 public ChronoLocalDate<C> with(TemporalAdjuster adjuster) { 095 return getChrono().ensureChronoLocalDate(super.with(adjuster)); 096 } 097 098 @Override 099 public ChronoLocalDate<C> plus(TemporalAdder adjuster) { 100 return getChrono().ensureChronoLocalDate(super.plus(adjuster)); 101 } 102 103 @Override 104 public ChronoLocalDate<C> minus(TemporalSubtractor adjuster) { 105 return getChrono().ensureChronoLocalDate(super.minus(adjuster)); 106 } 107 108 @Override 109 public ChronoLocalDate<C> minus(long amountToSubtract, TemporalUnit unit) { 110 return getChrono().ensureChronoLocalDate(super.minus(amountToSubtract, unit)); 111 } 112 113 //------------------------------------------------------------------------- 114 @Override 115 public Temporal adjustInto(Temporal temporal) { 116 return temporal.with(EPOCH_DAY, toEpochDay()); 117 } 118 119 @Override 120 public ChronoLocalDateTime<C> atTime(LocalTime localTime) { 121 return Chrono.dateTime(this, localTime); 122 } 123 124 @Override 125 public <R> R query(TemporalQuery<R> query) { 126 if (query == TemporalQueries.chrono()) { 127 return (R) getChrono(); 128 } 129 return super.query(query); 130 } 131 132 @Override 133 public long toEpochDay() { 134 return getLong(EPOCH_DAY); 135 } 136 137 //------------------------------------------------------------------------- 138 @Override 139 public int compareTo(ChronoLocalDate<?> other) { 140 int cmp = Long.compare(toEpochDay(), other.toEpochDay()); 141 if (cmp == 0) { 142 cmp = getChrono().compareTo(other.getChrono()); 143 } 144 return cmp; 145 } 146 147 @Override 148 public boolean isAfter(ChronoLocalDate<?> other) { 149 return this.toEpochDay() > other.toEpochDay(); 150 } 151 152 @Override 153 public boolean isBefore(ChronoLocalDate<?> other) { 154 return this.toEpochDay() < other.toEpochDay(); 155 } 156 157 @Override 158 public boolean isEqual(ChronoLocalDate<?> other) { 159 return this.toEpochDay() == other.toEpochDay(); 160 } 161 162 //------------------------------------------------------------------------- 163 @Override 164 public boolean equals(Object obj) { 165 if (this == obj) { 166 return true; 167 } 168 if (obj instanceof ChronoLocalDate) { 169 return compareTo((ChronoLocalDate<?>) obj) == 0; 170 } 171 return false; 172 } 173 174 @Override 175 public int hashCode() { 176 long epDay = toEpochDay(); 177 return getChrono().hashCode() ^ ((int) (epDay ^ (epDay >>> 32))); 178 } 179 180 //------------------------------------------------------------------------- 181 @Override 182 public String toString() { 183 // getLong() reduces chances of exceptions in toString() 184 long yoe = getLong(YEAR_OF_ERA); 185 long moy = getLong(MONTH_OF_YEAR); 186 long dom = getLong(DAY_OF_MONTH); 187 StringBuilder buf = new StringBuilder(30); 188 buf.append(getChrono().toString()) 189 .append(" ") 190 .append(getEra()) 191 .append(" ") 192 .append(yoe) 193 .append(moy < 10 ? "-0" : "-").append(moy) 194 .append(dom < 10 ? "-0" : "-").append(dom); 195 return buf.toString(); 196 } 197 198 @Override 199 public String toString(DateTimeFormatter formatter) { 200 Objects.requireNonNull(formatter, "formatter"); 201 return formatter.print(this); 202 } 203 204}