java.time: format code according to checkstyle rules

This commit is contained in:
Alexey Andreev 2021-03-17 12:45:30 +03:00
parent 2924af963d
commit 1b31d6da9a
90 changed files with 2399 additions and 2500 deletions

View File

@ -55,7 +55,6 @@
<option name="m_reportAllNonLibraryCalls" value="false" /> <option name="m_reportAllNonLibraryCalls" value="false" />
<option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.math.BigInteger,.*,java.math.BigDecimal,.*,java.net.InetAddress,.*,java.net.URI,.*,java.util.UUID,.*,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparantBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*" /> <option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.math.BigInteger,.*,java.math.BigDecimal,.*,java.net.InetAddress,.*,java.net.URI,.*,java.util.UUID,.*,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparantBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*" />
</inspection_tool> </inspection_tool>
<inspection_tool class="JSConstructorReturnsPrimitive" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSReferencingArgumentsOutsideOfFunction" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="JSReferencingArgumentsOutsideOfFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JSUnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="JSUnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnusedGlobalSymbols" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="JSUnusedGlobalSymbols" enabled="false" level="WARNING" enabled_by_default="false" />
@ -106,7 +105,6 @@
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" /> <option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PackageAccessibility" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="PackageAccessibility" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="RawUseOfParameterizedType" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantFieldInitialization" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="RedundantFieldInitialization" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="RedundantThrows" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantThrows" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SameParameterValue" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="SameParameterValue" enabled="true" level="WARNING" enabled_by_default="true">
@ -123,7 +121,6 @@
<option name="reportMethodParameters" value="true" /> <option name="reportMethodParameters" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="UndesirableClassUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="UndesirableClassUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryBoxing" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySemicolon" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="UnnecessarySemicolon" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="UnregisteredActivator" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="UnregisteredActivator" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="UnusedAssignment" enabled="true" level="WEAK WARNING" enabled_by_default="true"> <inspection_tool class="UnusedAssignment" enabled="true" level="WEAK WARNING" enabled_by_default="true">

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,11 +48,9 @@ package org.threeten.bp;
import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE; import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE;
import static org.threeten.bp.LocalTime.NANOS_PER_SECOND; import static org.threeten.bp.LocalTime.NANOS_PER_SECOND;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import org.threeten.bp.jdk8.Jdk8Methods; import org.threeten.bp.jdk8.Jdk8Methods;
/** /**

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,9 +48,7 @@ package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoField.DAY_OF_WEEK; import static org.threeten.bp.temporal.ChronoField.DAY_OF_WEEK;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -169,8 +182,8 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
try { try {
return of(temporal.get(DAY_OF_WEEK)); return of(temporal.get(DAY_OF_WEEK));
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain DayOfWeek from TemporalAccessor: " + throw new DateTimeException("Unable to obtain DayOfWeek from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName(), ex); + temporal + ", type " + temporal.getClass().getName(), ex);
} }
} }
@ -179,7 +192,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* Gets the day-of-week {@code int} value. * Gets the day-of-week {@code int} value.
* <p> * <p>
* The values are numbered following the ISO-8601 standard, from 1 (Monday) to 7 (Sunday). * The values are numbered following the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).
* See {@link WeekFields#dayOfWeek} for localized week-numbering. * See {@link WeekFields#dayOfWeek()} for localized week-numbering.
* *
* @return the day-of-week, from 1 (Monday) to 7 (Sunday) * @return the day-of-week, from 1 (Monday) to 7 (Sunday)
*/ */
@ -382,8 +395,12 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
public <R> R query(TemporalQuery<R> query) { public <R> R query(TemporalQuery<R> query) {
if (query == TemporalQueries.precision()) { if (query == TemporalQueries.precision()) {
return (R) DAYS; return (R) DAYS;
} else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || query == TemporalQueries.chronology() || } else if (query == TemporalQueries.localDate()
query == TemporalQueries.zone() || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { || query == TemporalQueries.localTime()
|| query == TemporalQueries.chronology()
|| query == TemporalQueries.zone()
|| query == TemporalQueries.zoneId()
|| query == TemporalQueries.offset()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);
@ -398,7 +415,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
* passing {@link ChronoField#DAY_OF_WEEK} as the field. * passing {@link ChronoField#DAY_OF_WEEK} as the field.
* Note that this adjusts forwards or backwards within a Monday to Sunday week. * Note that this adjusts forwards or backwards within a Monday to Sunday week.
* See {@link WeekFields#dayOfWeek} for localized week start days. * See {@link WeekFields#dayOfWeek()} for localized week start days.
* See {@link TemporalAdjusters} for other adjusters * See {@link TemporalAdjusters} for other adjusters
* with more control, such as {@code next(MONDAY)}. * with more control, such as {@code next(MONDAY)}.
* <p> * <p>

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -38,7 +53,6 @@ import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import static org.threeten.bp.temporal.ChronoUnit.SECONDS; import static org.threeten.bp.temporal.ChronoUnit.SECONDS;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -49,7 +63,6 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
import org.threeten.bp.jdk8.Jdk8Methods; import org.threeten.bp.jdk8.Jdk8Methods;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -108,9 +121,10 @@ public final class Duration
/** /**
* The pattern for parsing. * The pattern for parsing.
*/ */
// TODO: get rid of regexp
private final static Pattern PATTERN = private final static Pattern PATTERN =
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" + Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?"
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?", + "(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
Pattern.CASE_INSENSITIVE); Pattern.CASE_INSENSITIVE);
/** /**
@ -328,7 +342,7 @@ public final class Duration
} else if (secs == 0 && nanos != 0) { } else if (secs == 0 && nanos != 0) {
// two possible meanings for result, so recalculate secs // two possible meanings for result, so recalculate secs
Temporal adjustedEnd = endExclusive.with(NANO_OF_SECOND, startNos); Temporal adjustedEnd = endExclusive.with(NANO_OF_SECOND, startNos);
secs = startInclusive.until(adjustedEnd, SECONDS);; secs = startInclusive.until(adjustedEnd, SECONDS);
} }
} catch (DateTimeException | ArithmeticException ex2) { } catch (DateTimeException | ArithmeticException ex2) {
// ignore and only use seconds // ignore and only use seconds
@ -387,7 +401,7 @@ public final class Duration
Matcher matcher = PATTERN.matcher(text); Matcher matcher = PATTERN.matcher(text);
if (matcher.matches()) { if (matcher.matches()) {
// check for letter T but no time sections // check for letter T but no time sections
if ("T".equals(matcher.group(3)) == false) { if (!"T".equals(matcher.group(3))) {
boolean negate = "-".equals(matcher.group(1)); boolean negate = "-".equals(matcher.group(1));
String dayMatch = matcher.group(2); String dayMatch = matcher.group(2);
String hourMatch = matcher.group(4); String hourMatch = matcher.group(4);
@ -404,7 +418,7 @@ public final class Duration
try { try {
return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos); return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
} catch (ArithmeticException ex) { } catch (ArithmeticException ex) {
throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: overflow", text, 0).initCause(ex); throw new DateTimeParseException("Text cannot be parsed to a Duration: overflow", text, 0, ex);
} }
} }
} }
@ -441,8 +455,10 @@ public final class Duration
} }
} }
private static Duration create(boolean negate, long daysAsSecs, long hoursAsSecs, long minsAsSecs, long secs, int nanos) { private static Duration create(boolean negate, long daysAsSecs, long hoursAsSecs, long minsAsSecs,
long seconds = Jdk8Methods.safeAdd(daysAsSecs, Jdk8Methods.safeAdd(hoursAsSecs, Jdk8Methods.safeAdd(minsAsSecs, secs))); long secs, int nanos) {
long seconds = Jdk8Methods.safeAdd(daysAsSecs, Jdk8Methods.safeAdd(hoursAsSecs,
Jdk8Methods.safeAdd(minsAsSecs, secs)));
if (negate) { if (negate) {
return ofSeconds(seconds, nanos).negated(); return ofSeconds(seconds, nanos).negated();
} }
@ -631,10 +647,15 @@ public final class Duration
} }
if (unit instanceof ChronoUnit) { if (unit instanceof ChronoUnit) {
switch ((ChronoUnit) unit) { switch ((ChronoUnit) unit) {
case NANOS: return plusNanos(amountToAdd); case NANOS:
case MICROS: return plusSeconds((amountToAdd / (1000000L * 1000)) * 1000).plusNanos((amountToAdd % (1000000L * 1000)) * 1000); return plusNanos(amountToAdd);
case MILLIS: return plusMillis(amountToAdd); case MICROS:
case SECONDS: return plusSeconds(amountToAdd); return plusSeconds((amountToAdd / (1000000L * 1000)) * 1000)
.plusNanos((amountToAdd % (1000000L * 1000)) * 1000);
case MILLIS:
return plusMillis(amountToAdd);
case SECONDS:
return plusSeconds(amountToAdd);
} }
return plusSeconds(Jdk8Methods.safeMultiply(unit.getDuration().seconds, amountToAdd)); return plusSeconds(Jdk8Methods.safeMultiply(unit.getDuration().seconds, amountToAdd));
} }
@ -777,7 +798,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minus(long amountToSubtract, TemporalUnit unit) { public Duration minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -791,7 +814,7 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusDays(long daysToSubtract) { public Duration minusDays(long daysToSubtract) {
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract)); return daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract);
} }
/** /**
@ -804,7 +827,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusHours(long hoursToSubtract) { public Duration minusHours(long hoursToSubtract) {
return (hoursToSubtract == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hoursToSubtract)); return hoursToSubtract == Long.MIN_VALUE
? plusHours(Long.MAX_VALUE).plusHours(1)
: plusHours(-hoursToSubtract);
} }
/** /**
@ -817,7 +842,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusMinutes(long minutesToSubtract) { public Duration minusMinutes(long minutesToSubtract) {
return (minutesToSubtract == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutesToSubtract)); return minutesToSubtract == Long.MIN_VALUE
? plusMinutes(Long.MAX_VALUE).plusMinutes(1)
: plusMinutes(-minutesToSubtract);
} }
/** /**
@ -830,7 +857,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusSeconds(long secondsToSubtract) { public Duration minusSeconds(long secondsToSubtract) {
return (secondsToSubtract == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-secondsToSubtract)); return secondsToSubtract == Long.MIN_VALUE
? plusSeconds(Long.MAX_VALUE).plusSeconds(1)
: plusSeconds(-secondsToSubtract);
} }
/** /**
@ -843,7 +872,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusMillis(long millisToSubtract) { public Duration minusMillis(long millisToSubtract) {
return (millisToSubtract == Long.MIN_VALUE ? plusMillis(Long.MAX_VALUE).plusMillis(1) : plusMillis(-millisToSubtract)); return millisToSubtract == Long.MIN_VALUE
? plusMillis(Long.MAX_VALUE).plusMillis(1)
: plusMillis(-millisToSubtract);
} }
/** /**
@ -856,7 +887,9 @@ public final class Duration
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Duration minusNanos(long nanosToSubtract) { public Duration minusNanos(long nanosToSubtract) {
return (nanosToSubtract == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanosToSubtract)); return nanosToSubtract == Long.MIN_VALUE
? plusNanos(Long.MAX_VALUE).plusNanos(1)
: plusNanos(-nanosToSubtract);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1140,8 +1173,7 @@ public final class Duration
} }
if (otherDuration instanceof Duration) { if (otherDuration instanceof Duration) {
Duration other = (Duration) otherDuration; Duration other = (Duration) otherDuration;
return this.seconds == other.seconds && return this.seconds == other.seconds && this.nanos == other.nanos;
this.nanos == other.nanos;
} }
return false; return false;
} }
@ -1222,6 +1254,4 @@ public final class Duration
buf.append('S'); buf.append('S');
return buf.toString(); return buf.toString();
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -40,10 +55,8 @@ import static org.threeten.bp.temporal.ChronoField.MILLI_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND; import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
import org.threeten.bp.jdk8.Jdk8Methods; import org.threeten.bp.jdk8.Jdk8Methods;
@ -331,8 +344,8 @@ public final class Instant
int nanoOfSecond = temporal.get(NANO_OF_SECOND); int nanoOfSecond = temporal.get(NANO_OF_SECOND);
return Instant.ofEpochSecond(instantSecs, nanoOfSecond); return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain Instant from TemporalAccessor: " + throw new DateTimeException("Unable to obtain Instant from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName(), ex); + temporal + ", type " + temporal.getClass().getName(), ex);
} }
} }
@ -412,7 +425,8 @@ public final class Instant
@Override @Override
public boolean isSupported(TemporalField field) { public boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return field == INSTANT_SECONDS || field == NANO_OF_SECOND || field == MICRO_OF_SECOND || field == MILLI_OF_SECOND; return field == INSTANT_SECONDS || field == NANO_OF_SECOND || field == MICRO_OF_SECOND
|| field == MILLI_OF_SECOND;
} }
return field != null && field.isSupportedBy(this); return field != null && field.isSupportedBy(this);
} }
@ -627,14 +641,16 @@ public final class Instant
switch (f) { switch (f) {
case MILLI_OF_SECOND: { case MILLI_OF_SECOND: {
int nval = (int) newValue * NANOS_PER_MILLI; int nval = (int) newValue * NANOS_PER_MILLI;
return (nval != nanos ? create(seconds, nval) : this); return nval != nanos ? create(seconds, nval) : this;
} }
case MICRO_OF_SECOND: { case MICRO_OF_SECOND: {
int nval = (int) newValue * 1000; int nval = (int) newValue * 1000;
return (nval != nanos ? create(seconds, nval) : this); return nval != nanos ? create(seconds, nval) : this;
} }
case NANO_OF_SECOND: return (newValue != nanos ? create(seconds, (int) newValue) : this); case NANO_OF_SECOND:
case INSTANT_SECONDS: return (newValue != seconds ? create(newValue, nanos) : this); return newValue != nanos ? create(seconds, (int) newValue) : this;
case INSTANT_SECONDS:
return newValue != seconds ? create(newValue, nanos) : this;
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -797,7 +813,9 @@ public final class Instant
*/ */
@Override @Override
public Instant minus(long amountToSubtract, TemporalUnit unit) { public Instant minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -878,9 +896,9 @@ public final class Instant
return (R) NANOS; return (R) NANOS;
} }
// inline TemporalAccessor.super.query(query) as an optimization // inline TemporalAccessor.super.query(query) as an optimization
if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime()
query == TemporalQueries.chronology() || query == TemporalQueries.zoneId() || || query == TemporalQueries.chronology() || query == TemporalQueries.zoneId()
query == TemporalQueries.zone() || query == TemporalQueries.offset()) { || query == TemporalQueries.zone() || query == TemporalQueries.offset()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);
@ -970,7 +988,7 @@ public final class Instant
case MINUTES: return secondsUntil(end) / SECONDS_PER_MINUTE; case MINUTES: return secondsUntil(end) / SECONDS_PER_MINUTE;
case HOURS: return secondsUntil(end) / SECONDS_PER_HOUR; case HOURS: return secondsUntil(end) / SECONDS_PER_HOUR;
case HALF_DAYS: return secondsUntil(end) / (12 * SECONDS_PER_HOUR); case HALF_DAYS: return secondsUntil(end) / (12 * SECONDS_PER_HOUR);
case DAYS: return secondsUntil(end) / (SECONDS_PER_DAY); case DAYS: return secondsUntil(end) / SECONDS_PER_DAY;
} }
throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
} }
@ -1057,7 +1075,7 @@ public final class Instant
// that way we always stay in the valid long range // that way we always stay in the valid long range
// seconds + 1 can not overflow because it is negative // seconds + 1 can not overflow because it is negative
long millis = Jdk8Methods.safeMultiply(seconds + 1, MILLIS_PER_SEC); long millis = Jdk8Methods.safeMultiply(seconds + 1, MILLIS_PER_SEC);
return Jdk8Methods.safeSubtract(millis, (MILLIS_PER_SEC - nanos / NANOS_PER_MILLI)); return Jdk8Methods.safeSubtract(millis, MILLIS_PER_SEC - nanos / NANOS_PER_MILLI);
} }
} }
@ -1123,8 +1141,7 @@ public final class Instant
} }
if (otherInstant instanceof Instant) { if (otherInstant instanceof Instant) {
Instant other = (Instant) otherInstant; Instant other = (Instant) otherInstant;
return this.seconds == other.seconds && return this.seconds == other.seconds && this.nanos == other.nanos;
this.nanos == other.nanos;
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -43,10 +58,8 @@ import static org.threeten.bp.temporal.ChronoField.ERA;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import static org.threeten.bp.temporal.ChronoField.PROLEPTIC_MONTH; import static org.threeten.bp.temporal.ChronoField.PROLEPTIC_MONTH;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.ChronoLocalDate; import org.threeten.bp.chrono.ChronoLocalDate;
import org.threeten.bp.chrono.Era; import org.threeten.bp.chrono.Era;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
@ -238,7 +251,7 @@ public final class LocalDate
YEAR.checkValidValue(year); YEAR.checkValidValue(year);
DAY_OF_YEAR.checkValidValue(dayOfYear); DAY_OF_YEAR.checkValidValue(dayOfYear);
boolean leap = IsoChronology.INSTANCE.isLeapYear(year); boolean leap = IsoChronology.INSTANCE.isLeapYear(year);
if (dayOfYear == 366 && leap == false) { if (dayOfYear == 366 && !leap) {
throw new DateTimeException("Invalid date 'DayOfYear 366' as '" + year + "' is not a leap year"); throw new DateTimeException("Invalid date 'DayOfYear 366' as '" + year + "' is not a leap year");
} }
Month moy = Month.of((dayOfYear - 1) / 31 + 1); Month moy = Month.of((dayOfYear - 1) / 31 + 1);
@ -314,8 +327,8 @@ public final class LocalDate
public static LocalDate from(TemporalAccessor temporal) { public static LocalDate from(TemporalAccessor temporal) {
LocalDate date = temporal.query(TemporalQueries.localDate()); LocalDate date = temporal.query(TemporalQueries.localDate());
if (date == null) { if (date == null) {
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
return date; return date;
} }
@ -477,11 +490,16 @@ public final class LocalDate
ChronoField f = (ChronoField) field; ChronoField f = (ChronoField) field;
if (f.isDateBased()) { if (f.isDateBased()) {
switch (f) { switch (f) {
case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth()); case DAY_OF_MONTH:
case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear()); return ValueRange.of(1, lengthOfMonth());
case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, getMonth() == Month.FEBRUARY && isLeapYear() == false ? 4 : 5); case DAY_OF_YEAR:
return ValueRange.of(1, lengthOfYear());
case ALIGNED_WEEK_OF_MONTH:
return ValueRange.of(1, getMonth() == Month.FEBRUARY && !isLeapYear() ? 4 : 5);
case YEAR_OF_ERA: case YEAR_OF_ERA:
return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE)); return getYear() <= 0
? ValueRange.of(1, Year.MAX_VALUE + 1)
: ValueRange.of(1, Year.MAX_VALUE);
} }
return field.range(); return field.range();
} }
@ -570,9 +588,9 @@ public final class LocalDate
case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1; case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
case MONTH_OF_YEAR: return month; case MONTH_OF_YEAR: return month;
case PROLEPTIC_MONTH: throw new DateTimeException("Field too large for an int: " + field); case PROLEPTIC_MONTH: throw new DateTimeException("Field too large for an int: " + field);
case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year); case YEAR_OF_ERA: return year >= 1 ? year : 1 - year;
case YEAR: return year; case YEAR: return year;
case ERA: return (year >= 1 ? 1 : 0); case ERA: return year >= 1 ? 1 : 0;
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -739,7 +757,7 @@ public final class LocalDate
public int lengthOfMonth() { public int lengthOfMonth() {
switch (month) { switch (month) {
case 2: case 2:
return (isLeapYear() ? 29 : 28); return isLeapYear() ? 29 : 28;
case 4: case 4:
case 6: case 6:
case 9: case 9:
@ -759,7 +777,7 @@ public final class LocalDate
*/ */
@Override // override for Javadoc and performance @Override // override for Javadoc and performance
public int lengthOfYear() { public int lengthOfYear() {
return (isLeapYear() ? 366 : 365); return isLeapYear() ? 366 : 365;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -928,7 +946,7 @@ public final class LocalDate
case PROLEPTIC_MONTH: return plusMonths(newValue - getLong(PROLEPTIC_MONTH)); case PROLEPTIC_MONTH: return plusMonths(newValue - getLong(PROLEPTIC_MONTH));
case YEAR_OF_ERA: return withYear((int) (year >= 1 ? newValue : 1 - newValue)); case YEAR_OF_ERA: return withYear((int) (year >= 1 ? newValue : 1 - newValue));
case YEAR: return withYear((int) newValue); case YEAR: return withYear((int) newValue);
case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); case ERA: return getLong(ERA) == newValue ? this : withYear(1 - year);
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -1205,7 +1223,9 @@ public final class LocalDate
*/ */
@Override @Override
public LocalDate minus(long amountToSubtract, TemporalUnit unit) { public LocalDate minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1230,7 +1250,9 @@ public final class LocalDate
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDate minusYears(long yearsToSubtract) { public LocalDate minusYears(long yearsToSubtract) {
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); return yearsToSubtract == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-yearsToSubtract);
} }
/** /**
@ -1254,7 +1276,9 @@ public final class LocalDate
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDate minusMonths(long monthsToSubtract) { public LocalDate minusMonths(long monthsToSubtract) {
return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract)); return monthsToSubtract == Long.MIN_VALUE
? plusMonths(Long.MAX_VALUE).plusMonths(1)
: plusMonths(-monthsToSubtract);
} }
/** /**
@ -1273,7 +1297,9 @@ public final class LocalDate
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDate minusWeeks(long weeksToSubtract) { public LocalDate minusWeeks(long weeksToSubtract) {
return (weeksToSubtract == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeksToSubtract)); return weeksToSubtract == Long.MIN_VALUE
? plusWeeks(Long.MAX_VALUE).plusWeeks(1)
: plusWeeks(-weeksToSubtract);
} }
/** /**
@ -1292,7 +1318,9 @@ public final class LocalDate
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDate minusDays(long daysToSubtract) { public LocalDate minusDays(long daysToSubtract) {
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract)); return daysToSubtract == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-daysToSubtract);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1602,7 +1630,7 @@ public final class LocalDate
// need to handle case where there is a gap from 11:30 to 00:30 // need to handle case where there is a gap from 11:30 to 00:30
// standard ZDT factory would result in 01:00 rather than 00:30 // standard ZDT factory would result in 01:00 rather than 00:30
LocalDateTime ldt = atTime(LocalTime.MIDNIGHT); LocalDateTime ldt = atTime(LocalTime.MIDNIGHT);
if (zone instanceof ZoneOffset == false) { if (!(zone instanceof ZoneOffset)) {
ZoneRules rules = zone.getRules(); ZoneRules rules = zone.getRules();
ZoneOffsetTransition trans = rules.getTransition(ldt); ZoneOffsetTransition trans = rules.getTransition(ldt);
if (trans != null && trans.isGap()) { if (trans != null && trans.isGap()) {
@ -1624,11 +1652,11 @@ public final class LocalDate
} else { } else {
total -= y / -4 - y / -100 + y / -400; total -= y / -4 - y / -100 + y / -400;
} }
total += ((367 * m - 362) / 12); total += (367 * m - 362) / 12;
total += day - 1; total += day - 1;
if (m > 2) { if (m > 2) {
total--; total--;
if (isLeapYear() == false) { if (!isLeapYear()) {
total--; total--;
} }
} }
@ -1659,11 +1687,11 @@ public final class LocalDate
} }
int compareTo0(LocalDate otherDate) { int compareTo0(LocalDate otherDate) {
int cmp = (year - otherDate.year); int cmp = year - otherDate.year;
if (cmp == 0) { if (cmp == 0) {
cmp = (month - otherDate.month); cmp = month - otherDate.month;
if (cmp == 0) { if (cmp == 0) {
cmp = (day - otherDate.day); cmp = day - otherDate.day;
} }
} }
return cmp; return cmp;
@ -1790,7 +1818,7 @@ public final class LocalDate
int yearValue = year; int yearValue = year;
int monthValue = month; int monthValue = month;
int dayValue = day; int dayValue = day;
return (yearValue & 0xFFFFF800) ^ ((yearValue << 11) + (monthValue << 6) + (dayValue)); return (yearValue & 0xFFFFF800) ^ ((yearValue << 11) + (monthValue << 6) + dayValue);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -40,10 +55,8 @@ import static org.threeten.bp.LocalTime.NANOS_PER_HOUR;
import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE; import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE;
import static org.threeten.bp.LocalTime.NANOS_PER_SECOND; import static org.threeten.bp.LocalTime.NANOS_PER_SECOND;
import static org.threeten.bp.LocalTime.SECONDS_PER_DAY; import static org.threeten.bp.LocalTime.SECONDS_PER_DAY;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.ChronoLocalDateTime; import org.threeten.bp.chrono.ChronoLocalDateTime;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
@ -230,7 +243,8 @@ public final class LocalDateTime
* @throws DateTimeException if the value of any field is out of range * @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month-year * @throws DateTimeException if the day-of-month is invalid for the month-year
*/ */
public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) { public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second,
int nanoOfSecond) {
LocalDate date = LocalDate.of(year, month, dayOfMonth); LocalDate date = LocalDate.of(year, month, dayOfMonth);
LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond); LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond);
return new LocalDateTime(date, time); return new LocalDateTime(date, time);
@ -299,7 +313,8 @@ public final class LocalDateTime
* @throws DateTimeException if the value of any field is out of range * @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month-year * @throws DateTimeException if the day-of-month is invalid for the month-year
*/ */
public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) { public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute,
int second, int nanoOfSecond) {
LocalDate date = LocalDate.of(year, month, dayOfMonth); LocalDate date = LocalDate.of(year, month, dayOfMonth);
LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond); LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond);
return new LocalDateTime(date, time); return new LocalDateTime(date, time);
@ -391,8 +406,8 @@ public final class LocalDateTime
LocalTime time = LocalTime.from(temporal); LocalTime time = LocalTime.from(temporal);
return new LocalDateTime(date, time); return new LocalDateTime(date, time);
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " + throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -544,7 +559,7 @@ public final class LocalDateTime
@Override @Override
public ValueRange range(TemporalField field) { public ValueRange range(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.range(field) : date.range(field)); return field.isTimeBased() ? time.range(field) : date.range(field);
} }
return field.rangeRefinedBy(this); return field.rangeRefinedBy(this);
} }
@ -577,7 +592,7 @@ public final class LocalDateTime
@Override @Override
public int get(TemporalField field) { public int get(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.get(field) : date.get(field)); return field.isTimeBased() ? time.get(field) : date.get(field);
} }
return super.get(field); return super.get(field);
} }
@ -607,7 +622,7 @@ public final class LocalDateTime
@Override @Override
public long getLong(TemporalField field) { public long getLong(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.getLong(field) : date.getLong(field)); return field.isTimeBased() ? time.getLong(field) : date.getLong(field);
} }
return field.getFrom(this); return field.getFrom(this);
} }
@ -1018,13 +1033,21 @@ public final class LocalDateTime
if (unit instanceof ChronoUnit) { if (unit instanceof ChronoUnit) {
ChronoUnit f = (ChronoUnit) unit; ChronoUnit f = (ChronoUnit) unit;
switch (f) { switch (f) {
case NANOS: return plusNanos(amountToAdd); case NANOS:
case MICROS: return plusDays(amountToAdd / MICROS_PER_DAY).plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); return plusNanos(amountToAdd);
case MILLIS: return plusDays(amountToAdd / MILLIS_PER_DAY).plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000000); case MICROS:
case SECONDS: return plusSeconds(amountToAdd); return plusDays(amountToAdd / MICROS_PER_DAY).plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);
case MINUTES: return plusMinutes(amountToAdd); case MILLIS:
case HOURS: return plusHours(amountToAdd); return plusDays(amountToAdd / MILLIS_PER_DAY).plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000000);
case HALF_DAYS: return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12); // no overflow (256 is multiple of 2) case SECONDS:
return plusSeconds(amountToAdd);
case MINUTES:
return plusMinutes(amountToAdd);
case HOURS:
return plusHours(amountToAdd);
case HALF_DAYS:
// no overflow (256 is multiple of 2)
return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12);
} }
return with(date.plus(amountToAdd, unit), time); return with(date.plus(amountToAdd, unit), time);
} }
@ -1214,7 +1237,9 @@ public final class LocalDateTime
*/ */
@Override @Override
public LocalDateTime minus(long amountToSubtract, TemporalUnit unit) { public LocalDateTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1239,7 +1264,9 @@ public final class LocalDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDateTime minusYears(long years) { public LocalDateTime minusYears(long years) {
return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years)); return years == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-years);
} }
/** /**
@ -1263,7 +1290,9 @@ public final class LocalDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDateTime minusMonths(long months) { public LocalDateTime minusMonths(long months) {
return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months)); return months == Long.MIN_VALUE
? plusMonths(Long.MAX_VALUE).plusMonths(1)
: plusMonths(-months);
} }
/** /**
@ -1282,7 +1311,9 @@ public final class LocalDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDateTime minusWeeks(long weeks) { public LocalDateTime minusWeeks(long weeks) {
return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks)); return weeks == Long.MIN_VALUE
? plusWeeks(Long.MAX_VALUE).plusWeeks(1)
: plusWeeks(-weeks);
} }
/** /**
@ -1301,7 +1332,9 @@ public final class LocalDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public LocalDateTime minusDays(long days) { public LocalDateTime minusDays(long days) {
return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days)); return days == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-days);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1371,7 +1404,8 @@ public final class LocalDateTime
* @param sign the sign to determine add or subtract * @param sign the sign to determine add or subtract
* @return the combined result, not null * @return the combined result, not null
*/ */
private LocalDateTime plusWithOverflow(LocalDate newDate, long hours, long minutes, long seconds, long nanos, int sign) { private LocalDateTime plusWithOverflow(LocalDate newDate, long hours, long minutes, long seconds,
long nanos, int sign) {
// 9223372036854775808 long, 2147483648 int // 9223372036854775808 long, 2147483648 int
if ((hours | minutes | seconds | nanos) == 0) { if ((hours | minutes | seconds | nanos) == 0) {
return with(newDate, time); return with(newDate, time);
@ -1389,7 +1423,7 @@ public final class LocalDateTime
totNanos = totNanos * sign + curNoD; // total 432000000000000 totNanos = totNanos * sign + curNoD; // total 432000000000000
totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY); totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY);
long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY); long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY);
LocalTime newTime = (newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD)); LocalTime newTime = newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD);
return with(newDate.plusDays(totDays), newTime); return with(newDate.plusDays(totDays), newTime);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -39,10 +54,8 @@ import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_DAY; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -389,8 +402,8 @@ public final class LocalTime
public static LocalTime from(TemporalAccessor temporal) { public static LocalTime from(TemporalAccessor temporal) {
LocalTime time = temporal.query(TemporalQueries.localTime()); LocalTime time = temporal.query(TemporalQueries.localTime());
if (time == null) { if (time == null) {
throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
return time; return time;
} }
@ -620,9 +633,9 @@ public final class LocalTime
case MINUTE_OF_HOUR: return minute; case MINUTE_OF_HOUR: return minute;
case MINUTE_OF_DAY: return hour * 60 + minute; case MINUTE_OF_DAY: return hour * 60 + minute;
case HOUR_OF_AMPM: return hour % 12; case HOUR_OF_AMPM: return hour % 12;
case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return (ham % 12 == 0 ? 12 : ham); case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return ham % 12 == 0 ? 12 : ham;
case HOUR_OF_DAY: return hour; case HOUR_OF_DAY: return hour;
case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour); case CLOCK_HOUR_OF_DAY: return hour == 0 ? 24 : hour;
case AMPM_OF_DAY: return hour / 12; case AMPM_OF_DAY: return hour / 12;
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
@ -1024,8 +1037,7 @@ public final class LocalTime
if (secondstoAdd == 0) { if (secondstoAdd == 0) {
return this; return this;
} }
int sofd = hour * SECONDS_PER_HOUR + int sofd = hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
minute * SECONDS_PER_MINUTE + second;
int newSofd = ((int) (secondstoAdd % SECONDS_PER_DAY) + sofd + SECONDS_PER_DAY) % SECONDS_PER_DAY; int newSofd = ((int) (secondstoAdd % SECONDS_PER_DAY) + sofd + SECONDS_PER_DAY) % SECONDS_PER_DAY;
if (sofd == newSofd) { if (sofd == newSofd) {
return this; return this;
@ -1089,7 +1101,8 @@ public final class LocalTime
* Returns a copy of this time with the specified period subtracted. * Returns a copy of this time with the specified period subtracted.
* <p> * <p>
* This method returns a new time based on this time with the specified period subtracted. * This method returns a new time based on this time with the specified period subtracted.
* This can be used to subtract any period that is defined by a unit, for example to subtract hours, minutes or seconds. * This can be used to subtract any period that is defined by a unit, for example to subtract hours,
* minutes or seconds.
* The unit is responsible for the details of the calculation, including the resolution * The unit is responsible for the details of the calculation, including the resolution
* of any edge cases in the calculation. * of any edge cases in the calculation.
* <p> * <p>
@ -1102,7 +1115,9 @@ public final class LocalTime
*/ */
@Override @Override
public LocalTime minus(long amountToSubtract, TemporalUnit unit) { public LocalTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1194,9 +1209,9 @@ public final class LocalTime
return (R) this; return (R) this;
} }
// inline TemporalAccessor.super.query(query) as an optimization // inline TemporalAccessor.super.query(query) as an optimization
if (query == TemporalQueries.chronology() || query == TemporalQueries.zoneId() || if (query == TemporalQueries.chronology() || query == TemporalQueries.zoneId()
query == TemporalQueries.zone() || query == TemporalQueries.offset() || || query == TemporalQueries.zone() || query == TemporalQueries.offset()
query == TemporalQueries.localDate()) { || query == TemporalQueries.localDate()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);
@ -1420,8 +1435,7 @@ public final class LocalTime
} }
if (obj instanceof LocalTime) { if (obj instanceof LocalTime) {
LocalTime other = (LocalTime) obj; LocalTime other = (LocalTime) obj;
return hour == other.hour && minute == other.minute && return hour == other.hour && minute == other.minute && second == other.second && nano == other.nano;
second == other.second && nano == other.nano;
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,9 +48,7 @@ package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
@ -190,13 +203,13 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
return (Month) temporal; return (Month) temporal;
} }
try { try {
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { if (!IsoChronology.INSTANCE.equals(Chronology.from(temporal))) {
temporal = LocalDate.from(temporal); temporal = LocalDate.from(temporal);
} }
return of(temporal.get(MONTH_OF_YEAR)); return of(temporal.get(MONTH_OF_YEAR));
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " + throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " + temporal
temporal + ", type " + temporal.getClass().getName(), ex); + ", type " + temporal.getClass().getName(), ex);
} }
} }
@ -400,7 +413,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
public int length(boolean leapYear) { public int length(boolean leapYear) {
switch (this) { switch (this) {
case FEBRUARY: case FEBRUARY:
return (leapYear ? 29 : 28); return leapYear ? 29 : 28;
case APRIL: case APRIL:
case JUNE: case JUNE:
case SEPTEMBER: case SEPTEMBER:
@ -540,8 +553,9 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
return (R) IsoChronology.INSTANCE; return (R) IsoChronology.INSTANCE;
} else if (query == TemporalQueries.precision()) { } else if (query == TemporalQueries.precision()) {
return (R) MONTHS; return (R) MONTHS;
} else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || } else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime()
query == TemporalQueries.zone() || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { || query == TemporalQueries.zone() || query == TemporalQueries.zoneId()
|| query == TemporalQueries.offset()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);
@ -584,7 +598,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
*/ */
@Override @Override
public Temporal adjustInto(Temporal temporal) { public Temporal adjustInto(Temporal temporal) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) { if (!Chronology.from(temporal).equals(IsoChronology.INSTANCE)) {
throw new DateTimeException("Adjustment only supported on ISO date-time"); throw new DateTimeException("Adjustment only supported on ISO date-time");
} }
return temporal.with(MONTH_OF_YEAR, getValue()); return temporal.with(MONTH_OF_YEAR, getValue());

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,10 +48,8 @@ package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoField.DAY_OF_MONTH; import static org.threeten.bp.temporal.ChronoField.DAY_OF_MONTH;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
@ -170,8 +183,8 @@ public final class MonthDay
Objects.requireNonNull(month, "month"); Objects.requireNonNull(month, "month");
DAY_OF_MONTH.checkValidValue(dayOfMonth); DAY_OF_MONTH.checkValidValue(dayOfMonth);
if (dayOfMonth > month.maxLength()) { if (dayOfMonth > month.maxLength()) {
throw new DateTimeException("Illegal value for DayOfMonth field, value " + dayOfMonth + throw new DateTimeException("Illegal value for DayOfMonth field, value " + dayOfMonth
" is not valid for month " + month.name()); + " is not valid for month " + month.name());
} }
return new MonthDay(month.getValue(), dayOfMonth); return new MonthDay(month.getValue(), dayOfMonth);
} }
@ -219,13 +232,13 @@ public final class MonthDay
return (MonthDay) temporal; return (MonthDay) temporal;
} }
try { try {
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { if (!IsoChronology.INSTANCE.equals(Chronology.from(temporal))) {
temporal = LocalDate.from(temporal); temporal = LocalDate.from(temporal);
} }
return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH)); return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH));
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: " + throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -453,7 +466,7 @@ public final class MonthDay
* @see Year#isValidMonthDay(MonthDay) * @see Year#isValidMonthDay(MonthDay)
*/ */
public boolean isValidYear(int year) { public boolean isValidYear(int year) {
return (day == 29 && month == 2 && Year.isLeap(year) == false) == false; return !(day == 29 && month == 2 && !Year.isLeap(year));
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -572,7 +585,7 @@ public final class MonthDay
*/ */
@Override @Override
public Temporal adjustInto(Temporal temporal) { public Temporal adjustInto(Temporal temporal) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) { if (!Chronology.from(temporal).equals(IsoChronology.INSTANCE)) {
throw new DateTimeException("Adjustment only supported on ISO date-time"); throw new DateTimeException("Adjustment only supported on ISO date-time");
} }
temporal = temporal.with(MONTH_OF_YEAR, month); temporal = temporal.with(MONTH_OF_YEAR, month);
@ -608,10 +621,11 @@ public final class MonthDay
* @param other the other month-day to compare to, not null * @param other the other month-day to compare to, not null
* @return the comparator value, negative if less, positive if greater * @return the comparator value, negative if less, positive if greater
*/ */
@Override
public int compareTo(MonthDay other) { public int compareTo(MonthDay other) {
int cmp = (month - other.month); int cmp = month - other.month;
if (cmp == 0) { if (cmp == 0) {
cmp = (day - other.day); cmp = day - other.day;
} }
return cmp; return cmp;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -36,11 +51,9 @@ import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY; import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
@ -303,8 +316,8 @@ public final class OffsetDateTime
return OffsetDateTime.ofInstant(instant, offset); return OffsetDateTime.ofInstant(instant, offset);
} }
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " + throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -1206,7 +1219,9 @@ public final class OffsetDateTime
*/ */
@Override @Override
public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) { public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1231,7 +1246,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusYears(long years) { public OffsetDateTime minusYears(long years) {
return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years)); return years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years);
} }
/** /**
@ -1255,7 +1270,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusMonths(long months) { public OffsetDateTime minusMonths(long months) {
return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months)); return months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months);
} }
/** /**
@ -1274,7 +1289,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusWeeks(long weeks) { public OffsetDateTime minusWeeks(long weeks) {
return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks)); return weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks);
} }
/** /**
@ -1293,7 +1308,9 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusDays(long days) { public OffsetDateTime minusDays(long days) {
return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days)); return days == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-days);
} }
/** /**
@ -1306,7 +1323,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusHours(long hours) { public OffsetDateTime minusHours(long hours) {
return (hours == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hours)); return hours == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hours);
} }
/** /**
@ -1319,7 +1336,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusMinutes(long minutes) { public OffsetDateTime minusMinutes(long minutes) {
return (minutes == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutes)); return minutes == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutes);
} }
/** /**
@ -1332,7 +1349,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusSeconds(long seconds) { public OffsetDateTime minusSeconds(long seconds) {
return (seconds == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-seconds)); return seconds == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-seconds);
} }
/** /**
@ -1345,7 +1362,7 @@ public final class OffsetDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public OffsetDateTime minusNanos(long nanos) { public OffsetDateTime minusNanos(long nanos) {
return (nanos == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanos)); return nanos == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanos);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1665,8 +1682,8 @@ public final class OffsetDateTime
public boolean isAfter(OffsetDateTime other) { public boolean isAfter(OffsetDateTime other) {
long thisEpochSec = toEpochSecond(); long thisEpochSec = toEpochSecond();
long otherEpochSec = other.toEpochSecond(); long otherEpochSec = other.toEpochSecond();
return thisEpochSec > otherEpochSec || return thisEpochSec > otherEpochSec
(thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano()); || (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano());
} }
/** /**
@ -1682,8 +1699,8 @@ public final class OffsetDateTime
public boolean isBefore(OffsetDateTime other) { public boolean isBefore(OffsetDateTime other) {
long thisEpochSec = toEpochSecond(); long thisEpochSec = toEpochSecond();
long otherEpochSec = other.toEpochSecond(); long otherEpochSec = other.toEpochSecond();
return thisEpochSec < otherEpochSec || return thisEpochSec < otherEpochSec
(thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano()); || (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano());
} }
/** /**
@ -1697,8 +1714,8 @@ public final class OffsetDateTime
* @return true if the instant equals the instant of the specified date-time * @return true if the instant equals the instant of the specified date-time
*/ */
public boolean isEqual(OffsetDateTime other) { public boolean isEqual(OffsetDateTime other) {
return toEpochSecond() == other.toEpochSecond() && return toEpochSecond() == other.toEpochSecond()
toLocalTime().getNano() == other.toLocalTime().getNano(); && toLocalTime().getNano() == other.toLocalTime().getNano();
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -38,10 +53,8 @@ import static org.threeten.bp.LocalTime.SECONDS_PER_DAY;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY; import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -252,8 +265,8 @@ public final class OffsetTime
ZoneOffset offset = ZoneOffset.from(temporal); ZoneOffset offset = ZoneOffset.from(temporal);
return new OffsetTime(time, offset); return new OffsetTime(time, offset);
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: " + throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -868,7 +881,8 @@ public final class OffsetTime
* Returns a copy of this time with the specified period subtracted. * Returns a copy of this time with the specified period subtracted.
* <p> * <p>
* This method returns a new time based on this time with the specified period subtracted. * This method returns a new time based on this time with the specified period subtracted.
* This can be used to subtract any period that is defined by a unit, for example to subtract hours, minutes or seconds. * This can be used to subtract any period that is defined by a unit, for example to subtract hours,
* minutes or seconds.
* The unit is responsible for the details of the calculation, including the resolution * The unit is responsible for the details of the calculation, including the resolution
* of any edge cases in the calculation. * of any edge cases in the calculation.
* The offset is not part of the calculation and will be unchanged in the result. * The offset is not part of the calculation and will be unchanged in the result.
@ -882,7 +896,9 @@ public final class OffsetTime
*/ */
@Override @Override
public OffsetTime minus(long amountToSubtract, TemporalUnit unit) { public OffsetTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -974,7 +990,8 @@ public final class OffsetTime
return (R) getOffset(); return (R) getOffset();
} else if (query == TemporalQueries.localTime()) { } else if (query == TemporalQueries.localTime()) {
return (R) time; return (R) time;
} else if (query == TemporalQueries.chronology() || query == TemporalQueries.localDate() || query == TemporalQueries.zoneId()) { } else if (query == TemporalQueries.chronology() || query == TemporalQueries.localDate()
|| query == TemporalQueries.zoneId()) {
return null; return null;
} }
return Temporal.super.query(query); return Temporal.super.query(query);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -42,7 +56,6 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.threeten.bp.chrono.ChronoLocalDate; import org.threeten.bp.chrono.ChronoLocalDate;
import org.threeten.bp.chrono.ChronoPeriod; import org.threeten.bp.chrono.ChronoPeriod;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
@ -101,7 +114,8 @@ public final class Period
* The pattern for parsing. * The pattern for parsing.
*/ */
private final static Pattern PATTERN = private final static Pattern PATTERN =
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?",
Pattern.CASE_INSENSITIVE);
/** /**
* The number of years. * The number of years.
@ -209,7 +223,7 @@ public final class Period
return (Period) amount; return (Period) amount;
} }
if (amount instanceof ChronoPeriod) { if (amount instanceof ChronoPeriod) {
if (IsoChronology.INSTANCE.equals(((ChronoPeriod) amount).getChronology()) == false) { if (!IsoChronology.INSTANCE.equals(((ChronoPeriod) amount).getChronology())) {
throw new DateTimeException("Period requires ISO chronology: " + amount); throw new DateTimeException("Period requires ISO chronology: " + amount);
} }
} }
@ -300,7 +314,7 @@ public final class Period
Objects.requireNonNull(text, "text"); Objects.requireNonNull(text, "text");
Matcher matcher = PATTERN.matcher(text); Matcher matcher = PATTERN.matcher(text);
if (matcher.matches()) { if (matcher.matches()) {
int negate = ("-".equals(matcher.group(1)) ? -1 : 1); int negate = "-".equals(matcher.group(1)) ? -1 : 1;
String yearMatch = matcher.group(2); String yearMatch = matcher.group(2);
String monthMatch = matcher.group(3); String monthMatch = matcher.group(3);
String weekMatch = matcher.group(4); String weekMatch = matcher.group(4);
@ -314,7 +328,7 @@ public final class Period
days = Jdk8Methods.safeAdd(days, Jdk8Methods.safeMultiply(weeks, 7)); days = Jdk8Methods.safeAdd(days, Jdk8Methods.safeMultiply(weeks, 7));
return create(years, months, days); return create(years, months, days);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex);
} }
} }
} }
@ -329,7 +343,7 @@ public final class Period
try { try {
return Jdk8Methods.safeMultiply(val, negate); return Jdk8Methods.safeMultiply(val, negate);
} catch (ArithmeticException ex) { } catch (ArithmeticException ex) {
throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex);
} }
} }
@ -406,8 +420,9 @@ public final class Period
* *
* @return true if this period is zero-length * @return true if this period is zero-length
*/ */
@Override
public boolean isZero() { public boolean isZero() {
return (this == ZERO); return this == ZERO;
} }
/** /**
@ -417,6 +432,7 @@ public final class Period
* *
* @return true if any unit of this period is negative * @return true if any unit of this period is negative
*/ */
@Override
public boolean isNegative() { public boolean isNegative() {
return years < 0 || months < 0 || days < 0; return years < 0 || months < 0 || days < 0;
} }
@ -542,6 +558,7 @@ public final class Period
* @return a {@code Period} based on this period with the requested period added, not null * @return a {@code Period} based on this period with the requested period added, not null
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
@Override
public Period plus(TemporalAmount amountToAdd) { public Period plus(TemporalAmount amountToAdd) {
Period amount = Period.from(amountToAdd); Period amount = Period.from(amountToAdd);
return create( return create(
@ -626,6 +643,7 @@ public final class Period
* @return a {@code Period} based on this period with the requested period subtracted, not null * @return a {@code Period} based on this period with the requested period subtracted, not null
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
@Override
public Period minus(TemporalAmount amountToSubtract) { public Period minus(TemporalAmount amountToSubtract) {
Period amount = Period.from(amountToSubtract); Period amount = Period.from(amountToSubtract);
return create( return create(
@ -648,7 +666,9 @@ public final class Period
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Period minusYears(long yearsToSubtract) { public Period minusYears(long yearsToSubtract) {
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); return yearsToSubtract == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-yearsToSubtract);
} }
/** /**
@ -665,7 +685,9 @@ public final class Period
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Period minusMonths(long monthsToSubtract) { public Period minusMonths(long monthsToSubtract) {
return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract)); return monthsToSubtract == Long.MIN_VALUE
? plusMonths(Long.MAX_VALUE).plusMonths(1)
: plusMonths(-monthsToSubtract);
} }
/** /**
@ -682,7 +704,9 @@ public final class Period
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public Period minusDays(long daysToSubtract) { public Period minusDays(long daysToSubtract) {
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract)); return daysToSubtract == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-daysToSubtract);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -697,6 +721,7 @@ public final class Period
* @return a {@code Period} based on this period with the amounts multiplied by the scalar, not null * @return a {@code Period} based on this period with the amounts multiplied by the scalar, not null
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
@Override
public Period multipliedBy(int scalar) { public Period multipliedBy(int scalar) {
if (this == ZERO || scalar == 1) { if (this == ZERO || scalar == 1) {
return this; return this;
@ -713,6 +738,7 @@ public final class Period
* @return a {@code Period} based on this period with the amounts negated, not null * @return a {@code Period} based on this period with the amounts negated, not null
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
@Override
public Period negated() { public Period negated() {
return multipliedBy(-1); return multipliedBy(-1);
} }
@ -738,6 +764,7 @@ public final class Period
* @return a {@code Period} based on this period with excess months normalized to years, not null * @return a {@code Period} based on this period with excess months normalized to years, not null
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
@Override
public Period normalized() { public Period normalized() {
long totalMonths = toTotalMonths(); long totalMonths = toTotalMonths();
long splitYears = totalMonths / 12; long splitYears = totalMonths / 12;
@ -878,9 +905,7 @@ public final class Period
} }
if (obj instanceof Period) { if (obj instanceof Period) {
Period other = (Period) obj; Period other = (Period) obj;
return years == other.years && return years == other.years && months == other.months && days == other.days;
months == other.months &&
days == other.days;
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -39,10 +54,8 @@ import static org.threeten.bp.temporal.ChronoUnit.DECADES;
import static org.threeten.bp.temporal.ChronoUnit.ERAS; import static org.threeten.bp.temporal.ChronoUnit.ERAS;
import static org.threeten.bp.temporal.ChronoUnit.MILLENNIA; import static org.threeten.bp.temporal.ChronoUnit.MILLENNIA;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
@ -358,7 +371,7 @@ public final class Year
@Override @Override
public ValueRange range(TemporalField field) { public ValueRange range(TemporalField field) {
if (field == YEAR_OF_ERA) { if (field == YEAR_OF_ERA) {
return (year <= 0 ? ValueRange.of(1, MAX_VALUE + 1) : ValueRange.of(1, MAX_VALUE)); return year <= 0 ? ValueRange.of(1, MAX_VALUE + 1) : ValueRange.of(1, MAX_VALUE);
} }
return Temporal.super.range(field); return Temporal.super.range(field);
} }
@ -417,9 +430,9 @@ public final class Year
public long getLong(TemporalField field) { public long getLong(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
switch ((ChronoField) field) { switch ((ChronoField) field) {
case YEAR_OF_ERA: return (year < 1 ? 1 - year : year); case YEAR_OF_ERA: return year < 1 ? 1 - year : year;
case YEAR: return year; case YEAR: return year;
case ERA: return (year < 1 ? 0 : 1); case ERA: return year < 1 ? 0 : 1;
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -543,7 +556,7 @@ public final class Year
switch (f) { switch (f) {
case YEAR_OF_ERA: return Year.of((int) (year < 1 ? 1 - newValue : newValue)); case YEAR_OF_ERA: return Year.of((int) (year < 1 ? 1 - newValue : newValue));
case YEAR: return Year.of((int) newValue); case YEAR: return Year.of((int) newValue);
case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year)); case ERA: return getLong(ERA) == newValue ? this : Year.of(1 - year);
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -637,7 +650,9 @@ public final class Year
*/ */
@Override @Override
public Year minus(long amountToSubtract, TemporalUnit unit) { public Year minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
/** /**
@ -650,7 +665,9 @@ public final class Year
* @throws DateTimeException if the result exceeds the supported year range * @throws DateTimeException if the result exceeds the supported year range
*/ */
public Year minusYears(long yearsToSubtract) { public Year minusYears(long yearsToSubtract) {
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); return yearsToSubtract == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-yearsToSubtract);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -679,8 +696,9 @@ public final class Year
return (R) IsoChronology.INSTANCE; return (R) IsoChronology.INSTANCE;
} else if (query == TemporalQueries.precision()) { } else if (query == TemporalQueries.precision()) {
return (R) YEARS; return (R) YEARS;
} else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || } else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime()
query == TemporalQueries.zone() || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { || query == TemporalQueries.zone() || query == TemporalQueries.zoneId()
|| query == TemporalQueries.offset()) {
return null; return null;
} }
return Temporal.super.query(query); return Temporal.super.query(query);
@ -714,7 +732,7 @@ public final class Year
*/ */
@Override @Override
public Temporal adjustInto(Temporal temporal) { public Temporal adjustInto(Temporal temporal) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) { if (!Chronology.from(temporal).equals(IsoChronology.INSTANCE)) {
throw new DateTimeException("Adjustment only supported on ISO date-time"); throw new DateTimeException("Adjustment only supported on ISO date-time");
} }
return temporal.with(YEAR, year); return temporal.with(YEAR, year);
@ -859,6 +877,7 @@ public final class Year
* @param other the other year to compare to, not null * @param other the other year to compare to, not null
* @return the comparator value, negative if less, positive if greater * @return the comparator value, negative if less, positive if greater
*/ */
@Override
public int compareTo(Year other) { public int compareTo(Year other) {
return year - other.year; return year - other.year;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -42,10 +57,8 @@ import static org.threeten.bp.temporal.ChronoUnit.ERAS;
import static org.threeten.bp.temporal.ChronoUnit.MILLENNIA; import static org.threeten.bp.temporal.ChronoUnit.MILLENNIA;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
import org.threeten.bp.chrono.IsoChronology; import org.threeten.bp.chrono.IsoChronology;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
@ -88,6 +101,7 @@ import org.threeten.bp.temporal.ValueRange;
*/ */
public final class YearMonth public final class YearMonth
implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable, TemporalAccessor { implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable, TemporalAccessor {
/** /**
* Parser. * Parser.
*/ */
@ -206,13 +220,13 @@ public final class YearMonth
return (YearMonth) temporal; return (YearMonth) temporal;
} }
try { try {
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { if (!IsoChronology.INSTANCE.equals(Chronology.from(temporal))) {
temporal = LocalDate.from(temporal); temporal = LocalDate.from(temporal);
} }
return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR)); return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " + throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -306,8 +320,8 @@ public final class YearMonth
@Override @Override
public boolean isSupported(TemporalField field) { public boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return field == YEAR || field == MONTH_OF_YEAR || return field == YEAR || field == MONTH_OF_YEAR
field == PROLEPTIC_MONTH || field == YEAR_OF_ERA || field == ERA; || field == PROLEPTIC_MONTH || field == YEAR_OF_ERA || field == ERA;
} }
return field != null && field.isSupportedBy(this); return field != null && field.isSupportedBy(this);
} }
@ -315,7 +329,8 @@ public final class YearMonth
@Override @Override
public boolean isSupported(TemporalUnit unit) { public boolean isSupported(TemporalUnit unit) {
if (unit instanceof ChronoUnit) { if (unit instanceof ChronoUnit) {
return unit == MONTHS || unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS; return unit == MONTHS || unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA
|| unit == ERAS;
} }
return unit != null && unit.isSupportedBy(this); return unit != null && unit.isSupportedBy(this);
} }
@ -345,7 +360,7 @@ public final class YearMonth
@Override @Override
public ValueRange range(TemporalField field) { public ValueRange range(TemporalField field) {
if (field == YEAR_OF_ERA) { if (field == YEAR_OF_ERA) {
return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE)); return getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE);
} }
return Temporal.super.range(field); return Temporal.super.range(field);
} }
@ -407,9 +422,9 @@ public final class YearMonth
switch ((ChronoField) field) { switch ((ChronoField) field) {
case MONTH_OF_YEAR: return month; case MONTH_OF_YEAR: return month;
case PROLEPTIC_MONTH: return getProlepticMonth(); case PROLEPTIC_MONTH: return getProlepticMonth();
case YEAR_OF_ERA: return (year < 1 ? 1 - year : year); case YEAR_OF_ERA: return year < 1 ? 1 - year : year;
case YEAR: return year; case YEAR: return year;
case ERA: return (year < 1 ? 0 : 1); case ERA: return year < 1 ? 0 : 1;
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -518,7 +533,7 @@ public final class YearMonth
* @return 366 if the year is leap, 365 otherwise * @return 366 if the year is leap, 365 otherwise
*/ */
public int lengthOfYear() { public int lengthOfYear() {
return (isLeapYear() ? 366 : 365); return isLeapYear() ? 366 : 365;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -606,7 +621,7 @@ public final class YearMonth
case PROLEPTIC_MONTH: return plusMonths(newValue - getLong(PROLEPTIC_MONTH)); case PROLEPTIC_MONTH: return plusMonths(newValue - getLong(PROLEPTIC_MONTH));
case YEAR_OF_ERA: return withYear((int) (year < 1 ? 1 - newValue : newValue)); case YEAR_OF_ERA: return withYear((int) (year < 1 ? 1 - newValue : newValue));
case YEAR: return withYear((int) newValue); case YEAR: return withYear((int) newValue);
case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); case ERA: return getLong(ERA) == newValue ? this : withYear(1 - year);
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -751,7 +766,9 @@ public final class YearMonth
*/ */
@Override @Override
public YearMonth minus(long amountToSubtract, TemporalUnit unit) { public YearMonth minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
/** /**
@ -764,7 +781,9 @@ public final class YearMonth
* @throws DateTimeException if the result exceeds the supported range * @throws DateTimeException if the result exceeds the supported range
*/ */
public YearMonth minusYears(long yearsToSubtract) { public YearMonth minusYears(long yearsToSubtract) {
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); return yearsToSubtract == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-yearsToSubtract);
} }
/** /**
@ -777,7 +796,9 @@ public final class YearMonth
* @throws DateTimeException if the result exceeds the supported range * @throws DateTimeException if the result exceeds the supported range
*/ */
public YearMonth minusMonths(long monthsToSubtract) { public YearMonth minusMonths(long monthsToSubtract) {
return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract)); return monthsToSubtract == Long.MIN_VALUE
? plusMonths(Long.MAX_VALUE).plusMonths(1)
: plusMonths(-monthsToSubtract);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -806,8 +827,9 @@ public final class YearMonth
return (R) IsoChronology.INSTANCE; return (R) IsoChronology.INSTANCE;
} else if (query == TemporalQueries.precision()) { } else if (query == TemporalQueries.precision()) {
return (R) MONTHS; return (R) MONTHS;
} else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || } else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime()
query == TemporalQueries.zone() || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { || query == TemporalQueries.zone() || query == TemporalQueries.zoneId()
|| query == TemporalQueries.offset()) {
return null; return null;
} }
return Temporal.super.query(query); return Temporal.super.query(query);
@ -841,7 +863,7 @@ public final class YearMonth
*/ */
@Override @Override
public Temporal adjustInto(Temporal temporal) { public Temporal adjustInto(Temporal temporal) {
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) { if (!Chronology.from(temporal).equals(IsoChronology.INSTANCE)) {
throw new DateTimeException("Adjustment only supported on ISO date-time"); throw new DateTimeException("Adjustment only supported on ISO date-time");
} }
return temporal.with(PROLEPTIC_MONTH, getProlepticMonth()); return temporal.with(PROLEPTIC_MONTH, getProlepticMonth());
@ -960,9 +982,9 @@ public final class YearMonth
*/ */
@Override @Override
public int compareTo(YearMonth other) { public int compareTo(YearMonth other) {
int cmp = (year - other.year); int cmp = year - other.year;
if (cmp == 0) { if (cmp == 0) {
cmp = (month - other.month); cmp = month - other.month;
} }
return cmp; return cmp;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -40,7 +55,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
import org.threeten.bp.temporal.TemporalAccessor; import org.threeten.bp.temporal.TemporalAccessor;
@ -275,7 +289,7 @@ public abstract class ZoneId implements Serializable {
Objects.requireNonNull(zoneId, "zoneId"); Objects.requireNonNull(zoneId, "zoneId");
Objects.requireNonNull(aliasMap, "aliasMap"); Objects.requireNonNull(aliasMap, "aliasMap");
String id = aliasMap.get(zoneId); String id = aliasMap.get(zoneId);
id = (id != null ? id : zoneId); id = id != null ? id : zoneId;
return of(id); return of(id);
} }
@ -333,8 +347,8 @@ public abstract class ZoneId implements Serializable {
if (zoneId.equals("UTC") || zoneId.equals("GMT") || zoneId.equals("UT")) { if (zoneId.equals("UTC") || zoneId.equals("GMT") || zoneId.equals("UT")) {
return new ZoneRegion(zoneId, ZoneOffset.UTC.getRules()); return new ZoneRegion(zoneId, ZoneOffset.UTC.getRules());
} }
if (zoneId.startsWith("UTC+") || zoneId.startsWith("GMT+") || if (zoneId.startsWith("UTC+") || zoneId.startsWith("GMT+")
zoneId.startsWith("UTC-") || zoneId.startsWith("GMT-")) { || zoneId.startsWith("UTC-") || zoneId.startsWith("GMT-")) {
ZoneOffset offset = ZoneOffset.of(zoneId.substring(3)); ZoneOffset offset = ZoneOffset.of(zoneId.substring(3));
if (offset.getTotalSeconds() == 0) { if (offset.getTotalSeconds() == 0) {
return new ZoneRegion(zoneId.substring(0, 3), offset.getRules()); return new ZoneRegion(zoneId.substring(0, 3), offset.getRules());
@ -399,8 +413,8 @@ public abstract class ZoneId implements Serializable {
public static ZoneId from(TemporalAccessor temporal) { public static ZoneId from(TemporalAccessor temporal) {
ZoneId obj = temporal.query(TemporalQueries.zone()); ZoneId obj = temporal.query(TemporalQueries.zone());
if (obj == null) { if (obj == null) {
throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: " + throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
return obj; return obj;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,12 +47,10 @@
package org.threeten.bp; package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
import org.threeten.bp.temporal.Temporal; import org.threeten.bp.temporal.Temporal;
import org.threeten.bp.temporal.TemporalAccessor; import org.threeten.bp.temporal.TemporalAccessor;
@ -169,7 +182,9 @@ public final class ZoneOffset
} }
// parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss // parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss
final int hours, minutes, seconds; final int hours;
final int minutes;
final int seconds;
switch (offsetId.length()) { switch (offsetId.length()) {
case 2: case 2:
offsetId = offsetId.charAt(0) + "0" + offsetId.charAt(1); // fallthru offsetId = offsetId.charAt(0) + "0" + offsetId.charAt(1); // fallthru
@ -300,8 +315,8 @@ public final class ZoneOffset
public static ZoneOffset from(TemporalAccessor temporal) { public static ZoneOffset from(TemporalAccessor temporal) {
ZoneOffset offset = temporal.query(TemporalQueries.offset()); ZoneOffset offset = temporal.query(TemporalQueries.offset());
if (offset == null) { if (offset == null) {
throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
return offset; return offset;
} }
@ -317,27 +332,29 @@ public final class ZoneOffset
*/ */
private static void validate(int hours, int minutes, int seconds) { private static void validate(int hours, int minutes, int seconds) {
if (hours < -18 || hours > 18) { if (hours < -18 || hours > 18) {
throw new DateTimeException("Zone offset hours not in valid range: value " + hours + throw new DateTimeException("Zone offset hours not in valid range: value "
" is not in the range -18 to 18"); + hours + " is not in the range -18 to 18");
} }
if (hours > 0) { if (hours > 0) {
if (minutes < 0 || seconds < 0) { if (minutes < 0 || seconds < 0) {
throw new DateTimeException("Zone offset minutes and seconds must be positive because hours is positive"); throw new DateTimeException("Zone offset minutes and seconds must be positive because hours"
+ " is positive");
} }
} else if (hours < 0) { } else if (hours < 0) {
if (minutes > 0 || seconds > 0) { if (minutes > 0 || seconds > 0) {
throw new DateTimeException("Zone offset minutes and seconds must be negative because hours is negative"); throw new DateTimeException("Zone offset minutes and seconds must be negative because hours "
+ "is negative");
} }
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) { } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
throw new DateTimeException("Zone offset minutes and seconds must have the same sign"); throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
} }
if (Math.abs(minutes) > 59) { if (Math.abs(minutes) > 59) {
throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " + throw new DateTimeException("Zone offset minutes not in valid range: abs(value) "
Math.abs(minutes) + " is not in the range 0 to 59"); + Math.abs(minutes) + " is not in the range 0 to 59");
} }
if (Math.abs(seconds) > 59) { if (Math.abs(seconds) > 59) {
throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " + throw new DateTimeException("Zone offset seconds not in valid range: abs(value) "
Math.abs(seconds) + " is not in the range 0 to 59"); + Math.abs(seconds) + " is not in the range 0 to 59");
} }
if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) { if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
@ -608,8 +625,9 @@ public final class ZoneOffset
public <R> R query(TemporalQuery<R> query) { public <R> R query(TemporalQuery<R> query) {
if (query == TemporalQueries.offset() || query == TemporalQueries.zone()) { if (query == TemporalQueries.offset() || query == TemporalQueries.zone()) {
return (R) this; return (R) this;
} else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime() || } else if (query == TemporalQueries.localDate() || query == TemporalQueries.localTime()
query == TemporalQueries.precision() || query == TemporalQueries.chronology() || query == TemporalQueries.zoneId()) { || query == TemporalQueries.precision() || query == TemporalQueries.chronology()
|| query == TemporalQueries.zoneId()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,7 +48,6 @@ package org.threeten.bp;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.threeten.bp.zone.ZoneRules; import org.threeten.bp.zone.ZoneRules;
import org.threeten.bp.zone.ZoneRulesException; import org.threeten.bp.zone.ZoneRulesException;
@ -96,8 +110,8 @@ final class ZoneRegion extends ZoneId implements Serializable {
if (zoneId.equals("UTC") || zoneId.equals("GMT") || zoneId.equals("UT")) { if (zoneId.equals("UTC") || zoneId.equals("GMT") || zoneId.equals("UT")) {
return new ZoneRegion(zoneId, ZoneOffset.UTC.getRules()); return new ZoneRegion(zoneId, ZoneOffset.UTC.getRules());
} }
if (zoneId.startsWith("UTC+") || zoneId.startsWith("GMT+") || if (zoneId.startsWith("UTC+") || zoneId.startsWith("GMT+")
zoneId.startsWith("UTC-") || zoneId.startsWith("GMT-")) { || zoneId.startsWith("UTC-") || zoneId.startsWith("GMT-")) {
ZoneOffset offset = ZoneOffset.of(zoneId.substring(3)); ZoneOffset offset = ZoneOffset.of(zoneId.substring(3));
if (offset.getTotalSeconds() == 0) { if (offset.getTotalSeconds() == 0) {
return new ZoneRegion(zoneId.substring(0, 3), offset.getRules()); return new ZoneRegion(zoneId.substring(0, 3), offset.getRules());
@ -165,6 +179,6 @@ final class ZoneRegion extends ZoneId implements Serializable {
public ZoneRules getRules() { public ZoneRules getRules() {
// additional query for group provider when null allows for possibility // additional query for group provider when null allows for possibility
// that the provider was added after the ZoneId was created // that the provider was added after the ZoneId was created
return (rules != null ? rules : ZoneRulesProvider.getRules(id, false)); return rules != null ? rules : ZoneRulesProvider.getRules(id, false);
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,11 +49,9 @@ package org.threeten.bp;
import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS; import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND; import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.chrono.ChronoZonedDateTime; import org.threeten.bp.chrono.ChronoZonedDateTime;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException; import org.threeten.bp.format.DateTimeParseException;
@ -397,7 +410,8 @@ public final class ZonedDateTime
*/ */
private static ZonedDateTime create(long epochSecond, int nanoOfSecond, ZoneId zone) { private static ZonedDateTime create(long epochSecond, int nanoOfSecond, ZoneId zone) {
ZoneRules rules = zone.getRules(); ZoneRules rules = zone.getRules();
Instant instant = Instant.ofEpochSecond(epochSecond, nanoOfSecond); // TODO: rules should be queryable by epochSeconds // TODO: rules should be queryable by epochSeconds
Instant instant = Instant.ofEpochSecond(epochSecond, nanoOfSecond);
ZoneOffset offset = rules.getOffset(instant); ZoneOffset offset = rules.getOffset(instant);
LocalDateTime ldt = LocalDateTime.ofEpochSecond(epochSecond, nanoOfSecond, offset); LocalDateTime ldt = LocalDateTime.ofEpochSecond(epochSecond, nanoOfSecond, offset);
return new ZonedDateTime(ldt, offset, zone); return new ZonedDateTime(ldt, offset, zone);
@ -422,17 +436,17 @@ public final class ZonedDateTime
Objects.requireNonNull(offset, "offset"); Objects.requireNonNull(offset, "offset");
Objects.requireNonNull(zone, "zone"); Objects.requireNonNull(zone, "zone");
ZoneRules rules = zone.getRules(); ZoneRules rules = zone.getRules();
if (rules.isValidOffset(localDateTime, offset) == false) { if (!rules.isValidOffset(localDateTime, offset)) {
ZoneOffsetTransition trans = rules.getTransition(localDateTime); ZoneOffsetTransition trans = rules.getTransition(localDateTime);
if (trans != null && trans.isGap()) { if (trans != null && trans.isGap()) {
// error message says daylight savings for simplicity // error message says daylight savings for simplicity
// even though there are other kinds of gaps // even though there are other kinds of gaps
throw new DateTimeException("LocalDateTime '" + localDateTime + throw new DateTimeException("LocalDateTime '" + localDateTime
"' does not exist in zone '" + zone + + "' does not exist in zone '" + zone
"' due to a gap in the local time-line, typically caused by daylight savings"); + "' due to a gap in the local time-line, typically caused by daylight savings");
} }
throw new DateTimeException("ZoneOffset '" + offset + "' is not valid for LocalDateTime '" + throw new DateTimeException("ZoneOffset '" + offset + "' is not valid for LocalDateTime '"
localDateTime + "' in zone '" + zone + "'"); + localDateTime + "' in zone '" + zone + "'");
} }
return new ZonedDateTime(localDateTime, offset, zone); return new ZonedDateTime(localDateTime, offset, zone);
} }
@ -462,7 +476,7 @@ public final class ZonedDateTime
Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(localDateTime, "localDateTime");
Objects.requireNonNull(offset, "offset"); Objects.requireNonNull(offset, "offset");
Objects.requireNonNull(zone, "zone"); Objects.requireNonNull(zone, "zone");
if (zone instanceof ZoneOffset && offset.equals(zone) == false) { if (zone instanceof ZoneOffset && !offset.equals(zone)) {
throw new IllegalArgumentException("ZoneId must match ZoneOffset"); throw new IllegalArgumentException("ZoneId must match ZoneOffset");
} }
return new ZonedDateTime(localDateTime, offset, zone); return new ZonedDateTime(localDateTime, offset, zone);
@ -506,8 +520,8 @@ public final class ZonedDateTime
LocalDateTime ldt = LocalDateTime.from(temporal); LocalDateTime ldt = LocalDateTime.from(temporal);
return of(ldt, zone); return of(ldt, zone);
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " + throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: "
temporal + ", type " + temporal.getClass().getName()); + temporal + ", type " + temporal.getClass().getName());
} }
} }
@ -585,7 +599,7 @@ public final class ZonedDateTime
* @return the zoned date-time, not null * @return the zoned date-time, not null
*/ */
private ZonedDateTime resolveOffset(ZoneOffset offset) { private ZonedDateTime resolveOffset(ZoneOffset offset) {
if (offset.equals(this.offset) == false && zone.getRules().isValidOffset(dateTime, offset)) { if (!offset.equals(this.offset) && zone.getRules().isValidOffset(dateTime, offset)) {
return new ZonedDateTime(dateTime, offset, zone); return new ZonedDateTime(dateTime, offset, zone);
} }
return this; return this;
@ -794,7 +808,7 @@ public final class ZonedDateTime
ZoneOffsetTransition trans = getZone().getRules().getTransition(dateTime); ZoneOffsetTransition trans = getZone().getRules().getTransition(dateTime);
if (trans != null && trans.isOverlap()) { if (trans != null && trans.isOverlap()) {
ZoneOffset earlierOffset = trans.getOffsetBefore(); ZoneOffset earlierOffset = trans.getOffsetBefore();
if (earlierOffset.equals(offset) == false) { if (!earlierOffset.equals(offset)) {
return new ZonedDateTime(dateTime, earlierOffset, zone); return new ZonedDateTime(dateTime, earlierOffset, zone);
} }
} }
@ -822,7 +836,7 @@ public final class ZonedDateTime
ZoneOffsetTransition trans = getZone().getRules().getTransition(toLocalDateTime()); ZoneOffsetTransition trans = getZone().getRules().getTransition(toLocalDateTime());
if (trans != null) { if (trans != null) {
ZoneOffset laterOffset = trans.getOffsetAfter(); ZoneOffset laterOffset = trans.getOffsetAfter();
if (laterOffset.equals(offset) == false) { if (!laterOffset.equals(offset)) {
return new ZonedDateTime(dateTime, laterOffset, zone); return new ZonedDateTime(dateTime, laterOffset, zone);
} }
} }
@ -891,8 +905,7 @@ public final class ZonedDateTime
@Override @Override
public ZonedDateTime withZoneSameInstant(ZoneId zone) { public ZonedDateTime withZoneSameInstant(ZoneId zone) {
Objects.requireNonNull(zone, "zone"); Objects.requireNonNull(zone, "zone");
return this.zone.equals(zone) ? this : return this.zone.equals(zone) ? this : create(dateTime.toEpochSecond(offset), dateTime.getNano(), zone);
create(dateTime.toEpochSecond(offset), dateTime.getNano(), zone);
} }
/** /**
@ -1676,7 +1689,9 @@ public final class ZonedDateTime
*/ */
@Override @Override
public ZonedDateTime minus(long amountToSubtract, TemporalUnit unit) { public ZonedDateTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); return amountToSubtract == Long.MIN_VALUE
? plus(Long.MAX_VALUE, unit).plus(1, unit)
: plus(-amountToSubtract, unit);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1699,7 +1714,7 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusYears(long years) { public ZonedDateTime minusYears(long years) {
return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years)); return years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years);
} }
/** /**
@ -1721,7 +1736,7 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusMonths(long months) { public ZonedDateTime minusMonths(long months) {
return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months)); return months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months);
} }
/** /**
@ -1743,7 +1758,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusWeeks(long weeks) { public ZonedDateTime minusWeeks(long weeks) {
return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks)); return weeks == Long.MIN_VALUE
? plusWeeks(Long.MAX_VALUE).plusWeeks(1)
: plusWeeks(-weeks);
} }
/** /**
@ -1765,7 +1782,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusDays(long days) { public ZonedDateTime minusDays(long days) {
return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days)); return days == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-days);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1794,7 +1813,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusHours(long hours) { public ZonedDateTime minusHours(long hours) {
return (hours == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hours)); return hours == Long.MIN_VALUE
? plusHours(Long.MAX_VALUE).plusHours(1)
: plusHours(-hours);
} }
/** /**
@ -1812,7 +1833,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusMinutes(long minutes) { public ZonedDateTime minusMinutes(long minutes) {
return (minutes == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutes)); return minutes == Long.MIN_VALUE
? plusMinutes(Long.MAX_VALUE).plusMinutes(1)
: plusMinutes(-minutes);
} }
/** /**
@ -1830,7 +1853,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusSeconds(long seconds) { public ZonedDateTime minusSeconds(long seconds) {
return (seconds == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-seconds)); return seconds == Long.MIN_VALUE
? plusSeconds(Long.MAX_VALUE).plusSeconds(1)
: plusSeconds(-seconds);
} }
/** /**
@ -1848,7 +1873,9 @@ public final class ZonedDateTime
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
public ZonedDateTime minusNanos(long nanos) { public ZonedDateTime minusNanos(long nanos) {
return (nanos == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanos)); return nanos == Long.MIN_VALUE
? plusNanos(Long.MAX_VALUE).plusNanos(1)
: plusNanos(-nanos);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -2024,9 +2051,9 @@ public final class ZonedDateTime
} }
if (obj instanceof ZonedDateTime) { if (obj instanceof ZonedDateTime) {
ZonedDateTime other = (ZonedDateTime) obj; ZonedDateTime other = (ZonedDateTime) obj;
return dateTime.equals(other.dateTime) && return dateTime.equals(other.dateTime)
offset.equals(other.offset) && && offset.equals(other.offset)
zone.equals(other.zone); && zone.equals(other.zone);
} }
return false; return false;
} }
@ -2075,6 +2102,4 @@ public final class ZonedDateTime
public String format(DateTimeFormatter formatter) { public String format(DateTimeFormatter formatter) {
return super.format(formatter); return super.format(formatter);
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,7 +47,6 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import java.io.Serializable; import java.io.Serializable;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalTime; import org.threeten.bp.LocalTime;
@ -98,7 +112,7 @@ import org.threeten.bp.temporal.TemporalUnit;
* {@code Chronology} must be registered as a Service implementing the {@code Chronology} interface * {@code Chronology} must be registered as a Service implementing the {@code Chronology} interface
* in the {@code META-INF/Services} file as per the specification of {@link java.util.ServiceLoader}. * in the {@code META-INF/Services} file as per the specification of {@link java.util.ServiceLoader}.
* The subclass must function according to the {@code Chronology} class description and must provide its * The subclass must function according to the {@code Chronology} class description and must provide its
* {@link Chronology#getID calendar name} and * {@link Chronology#getId()} calendar name} and
* {@link Chronology#getCalendarType() calendar type}. </p> * {@link Chronology#getCalendarType() calendar type}. </p>
* *
* <h3>Specification for implementors</h3> * <h3>Specification for implementors</h3>
@ -132,7 +146,8 @@ abstract class ChronoDateImpl<D extends ChronoLocalDate>
case DECADES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 10)); case DECADES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 10));
case CENTURIES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 100)); case CENTURIES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 100));
case MILLENNIA: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 1000)); case MILLENNIA: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 1000));
// case ERAS: throw new DateTimeException("Unable to add era, standard calendar system only has one era"); // case ERAS: throw new DateTimeException("Unable to add era,
// standard calendar system only has one era");
// case FOREVER: return (period == 0 ? this : (period > 0 ? LocalDate.MAX_DATE : LocalDate.MIN_DATE)); // case FOREVER: return (period == 0 ? this : (period > 0 ? LocalDate.MAX_DATE : LocalDate.MIN_DATE));
} }
throw new DateTimeException(unit + " not valid for chronology " + getChronology().getId()); throw new DateTimeException(unit + " not valid for chronology " + getChronology().getId());
@ -223,7 +238,9 @@ abstract class ChronoDateImpl<D extends ChronoLocalDate>
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
ChronoDateImpl<D> minusYears(long yearsToSubtract) { ChronoDateImpl<D> minusYears(long yearsToSubtract) {
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); return yearsToSubtract == Long.MIN_VALUE
? plusYears(Long.MAX_VALUE).plusYears(1)
: plusYears(-yearsToSubtract);
} }
/** /**
@ -243,7 +260,9 @@ abstract class ChronoDateImpl<D extends ChronoLocalDate>
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
ChronoDateImpl<D> minusMonths(long monthsToSubtract) { ChronoDateImpl<D> minusMonths(long monthsToSubtract) {
return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract)); return monthsToSubtract == Long.MIN_VALUE
? plusMonths(Long.MAX_VALUE).plusMonths(1)
: plusMonths(-monthsToSubtract);
} }
/** /**
@ -262,7 +281,9 @@ abstract class ChronoDateImpl<D extends ChronoLocalDate>
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
ChronoDateImpl<D> minusWeeks(long weeksToSubtract) { ChronoDateImpl<D> minusWeeks(long weeksToSubtract) {
return (weeksToSubtract == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeksToSubtract)); return weeksToSubtract == Long.MIN_VALUE
? plusWeeks(Long.MAX_VALUE).plusWeeks(1)
: plusWeeks(-weeksToSubtract);
} }
/** /**
@ -279,7 +300,9 @@ abstract class ChronoDateImpl<D extends ChronoLocalDate>
* @throws DateTimeException if the result exceeds the supported date range * @throws DateTimeException if the result exceeds the supported date range
*/ */
ChronoDateImpl<D> minusDays(long daysToSubtract) { ChronoDateImpl<D> minusDays(long daysToSubtract) {
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract)); return daysToSubtract == Long.MIN_VALUE
? plusDays(Long.MAX_VALUE).plusDays(1)
: plusDays(-daysToSubtract);
} }
@Override @Override

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -37,7 +52,6 @@ import static org.threeten.bp.temporal.ChronoField.ERA;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA; import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
@ -338,7 +352,7 @@ public abstract class ChronoLocalDate
* @return the length of the year in days * @return the length of the year in days
*/ */
public int lengthOfYear() { public int lengthOfYear() {
return (isLeapYear() ? 366 : 365); return isLeapYear() ? 366 : 365;
} }
@Override @Override
@ -395,8 +409,8 @@ public abstract class ChronoLocalDate
return (R) ChronoUnit.DAYS; return (R) ChronoUnit.DAYS;
} else if (query == TemporalQueries.localDate()) { } else if (query == TemporalQueries.localDate()) {
return (R) LocalDate.ofEpochDay(toEpochDay()); return (R) LocalDate.ofEpochDay(toEpochDay());
} else if (query == TemporalQueries.localTime() || query == TemporalQueries.zone() || } else if (query == TemporalQueries.localTime() || query == TemporalQueries.zone()
query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) {
return null; return null;
} }
return Temporal.super.query(query); return Temporal.super.query(query);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,10 +49,8 @@ package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY; import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -169,7 +182,7 @@ public abstract class ChronoLocalDateTime<D extends ChronoLocalDate>
* *
* @return the date part of this date-time, not null * @return the date part of this date-time, not null
*/ */
public abstract D toLocalDate() ; public abstract D toLocalDate();
/** /**
* Gets the local time part of this date-time. * Gets the local time part of this date-time.
@ -221,7 +234,8 @@ public abstract class ChronoLocalDateTime<D extends ChronoLocalDate>
return (R) LocalDate.ofEpochDay(toLocalDate().toEpochDay()); return (R) LocalDate.ofEpochDay(toLocalDate().toEpochDay());
} else if (query == TemporalQueries.localTime()) { } else if (query == TemporalQueries.localTime()) {
return (R) toLocalTime(); return (R) toLocalTime();
} else if (query == TemporalQueries.zone() || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()) { } else if (query == TemporalQueries.zone() || query == TemporalQueries.zoneId()
|| query == TemporalQueries.offset()) {
return null; return null;
} }
return Temporal.super.query(query); return Temporal.super.query(query);
@ -367,8 +381,8 @@ public abstract class ChronoLocalDateTime<D extends ChronoLocalDate>
public boolean isAfter(ChronoLocalDateTime<?> other) { public boolean isAfter(ChronoLocalDateTime<?> other) {
long thisEpDay = this.toLocalDate().toEpochDay(); long thisEpDay = this.toLocalDate().toEpochDay();
long otherEpDay = other.toLocalDate().toEpochDay(); long otherEpDay = other.toLocalDate().toEpochDay();
return thisEpDay > otherEpDay || return thisEpDay > otherEpDay
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() > other.toLocalTime().toNanoOfDay()); || (thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() > other.toLocalTime().toNanoOfDay());
} }
/** /**
@ -385,8 +399,8 @@ public abstract class ChronoLocalDateTime<D extends ChronoLocalDate>
public boolean isBefore(ChronoLocalDateTime<?> other) { public boolean isBefore(ChronoLocalDateTime<?> other) {
long thisEpDay = this.toLocalDate().toEpochDay(); long thisEpDay = this.toLocalDate().toEpochDay();
long otherEpDay = other.toLocalDate().toEpochDay(); long otherEpDay = other.toLocalDate().toEpochDay();
return thisEpDay < otherEpDay || return thisEpDay < otherEpDay
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() < other.toLocalTime().toNanoOfDay()); || (thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() < other.toLocalTime().toNanoOfDay());
} }
/** /**
@ -402,8 +416,8 @@ public abstract class ChronoLocalDateTime<D extends ChronoLocalDate>
*/ */
public boolean isEqual(ChronoLocalDateTime<?> other) { public boolean isEqual(ChronoLocalDateTime<?> other) {
// Do the time check first, it is cheaper than computing EPOCH day. // Do the time check first, it is cheaper than computing EPOCH day.
return this.toLocalTime().toNanoOfDay() == other.toLocalTime().toNanoOfDay() && return this.toLocalTime().toNanoOfDay() == other.toLocalTime().toNanoOfDay()
this.toLocalDate().toEpochDay() == other.toLocalDate().toEpochDay(); && this.toLocalDate().toEpochDay() == other.toLocalDate().toEpochDay();
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,10 +47,8 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.LocalTime; import org.threeten.bp.LocalTime;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
import org.threeten.bp.jdk8.Jdk8Methods; import org.threeten.bp.jdk8.Jdk8Methods;
@ -198,7 +211,7 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
@Override @Override
public ValueRange range(TemporalField field) { public ValueRange range(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.range(field) : date.range(field)); return field.isTimeBased() ? time.range(field) : date.range(field);
} }
return field.rangeRefinedBy(this); return field.rangeRefinedBy(this);
} }
@ -206,7 +219,7 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
@Override @Override
public int get(TemporalField field) { public int get(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.get(field) : date.get(field)); return field.isTimeBased() ? time.get(field) : date.get(field);
} }
return range(field).checkValidIntValue(getLong(field), field); return range(field).checkValidIntValue(getLong(field), field);
} }
@ -214,7 +227,7 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
@Override @Override
public long getLong(TemporalField field) { public long getLong(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
return (field.isTimeBased() ? time.getLong(field) : date.getLong(field)); return field.isTimeBased() ? time.getLong(field) : date.getLong(field);
} }
return field.getFrom(this); return field.getFrom(this);
} }
@ -252,12 +265,16 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
ChronoUnit f = (ChronoUnit) unit; ChronoUnit f = (ChronoUnit) unit;
switch (f) { switch (f) {
case NANOS: return plusNanos(amountToAdd); case NANOS: return plusNanos(amountToAdd);
case MICROS: return plusDays(amountToAdd / MICROS_PER_DAY).plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); case MICROS: return plusDays(amountToAdd / MICROS_PER_DAY)
case MILLIS: return plusDays(amountToAdd / MILLIS_PER_DAY).plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000000); .plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);
case MILLIS: return plusDays(amountToAdd / MILLIS_PER_DAY)
.plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000000);
case SECONDS: return plusSeconds(amountToAdd); case SECONDS: return plusSeconds(amountToAdd);
case MINUTES: return plusMinutes(amountToAdd); case MINUTES: return plusMinutes(amountToAdd);
case HOURS: return plusHours(amountToAdd); case HOURS: return plusHours(amountToAdd);
case HALF_DAYS: return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12); // no overflow (256 is multiple of 2) case HALF_DAYS:
// no overflow (256 is multiple of 2)
return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12);
} }
return with(date.plus(amountToAdd, unit), time); return with(date.plus(amountToAdd, unit), time);
} }
@ -302,7 +319,7 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
totNanos = totNanos + curNoD; // total 432000000000000 totNanos = totNanos + curNoD; // total 432000000000000
totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY); totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY);
long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY); long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY);
LocalTime newTime = (newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD)); LocalTime newTime = newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD);
return with(newDate.plus(totDays, ChronoUnit.DAYS), newTime); return with(newDate.plus(totDays, ChronoUnit.DAYS), newTime);
} }
@ -340,5 +357,4 @@ final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate>
} }
return unit.between(this, end); return unit.between(this, end);
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,7 +48,6 @@ package org.threeten.bp.chrono;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.temporal.ChronoUnit; import org.threeten.bp.temporal.ChronoUnit;
import org.threeten.bp.temporal.Temporal; import org.threeten.bp.temporal.Temporal;

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,13 +49,11 @@ package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.jdk8.Jdk8Methods; import org.threeten.bp.jdk8.Jdk8Methods;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -137,7 +150,8 @@ final class ChronoPeriodImpl
@Override @Override
public ChronoPeriod normalized() { public ChronoPeriod normalized() {
if (chronology.range(ChronoField.MONTH_OF_YEAR).isFixed()) { if (chronology.range(ChronoField.MONTH_OF_YEAR).isFixed()) {
long monthLength = chronology.range(ChronoField.MONTH_OF_YEAR).getMaximum() - chronology.range(ChronoField.MONTH_OF_YEAR).getMinimum() + 1; long monthLength = chronology.range(ChronoField.MONTH_OF_YEAR).getMaximum()
- chronology.range(ChronoField.MONTH_OF_YEAR).getMinimum() + 1;
long total = years * monthLength + months; long total = years * monthLength + months;
int years = Jdk8Methods.safeToInt(total / monthLength); int years = Jdk8Methods.safeToInt(total / monthLength);
int months = Jdk8Methods.safeToInt(total % monthLength); int months = Jdk8Methods.safeToInt(total % monthLength);
@ -150,8 +164,9 @@ final class ChronoPeriodImpl
public Temporal addTo(Temporal temporal) { public Temporal addTo(Temporal temporal) {
Objects.requireNonNull(temporal, "temporal"); Objects.requireNonNull(temporal, "temporal");
Chronology temporalChrono = temporal.query(TemporalQueries.chronology()); Chronology temporalChrono = temporal.query(TemporalQueries.chronology());
if (temporalChrono != null && chronology.equals(temporalChrono) == false) { if (temporalChrono != null && !chronology.equals(temporalChrono)) {
throw new DateTimeException("Invalid chronology, required: " + chronology.getId() + ", but was: " + temporalChrono.getId()); throw new DateTimeException("Invalid chronology, required: " + chronology.getId() + ", but was: "
+ temporalChrono.getId());
} }
if (years != 0) { if (years != 0) {
temporal = temporal.plus(years, YEARS); temporal = temporal.plus(years, YEARS);
@ -169,8 +184,9 @@ final class ChronoPeriodImpl
public Temporal subtractFrom(Temporal temporal) { public Temporal subtractFrom(Temporal temporal) {
Objects.requireNonNull(temporal, "temporal"); Objects.requireNonNull(temporal, "temporal");
Chronology temporalChrono = temporal.query(TemporalQueries.chronology()); Chronology temporalChrono = temporal.query(TemporalQueries.chronology());
if (temporalChrono != null && chronology.equals(temporalChrono) == false) { if (temporalChrono != null && !chronology.equals(temporalChrono)) {
throw new DateTimeException("Invalid chronology, required: " + chronology.getId() + ", but was: " + temporalChrono.getId()); throw new DateTimeException("Invalid chronology, required: " + chronology.getId()
+ ", but was: " + temporalChrono.getId());
} }
if (years != 0) { if (years != 0) {
temporal = temporal.minus(years, YEARS); temporal = temporal.minus(years, YEARS);
@ -192,8 +208,8 @@ final class ChronoPeriodImpl
} }
if (obj instanceof ChronoPeriodImpl) { if (obj instanceof ChronoPeriodImpl) {
ChronoPeriodImpl other = (ChronoPeriodImpl) obj; ChronoPeriodImpl other = (ChronoPeriodImpl) obj;
return years == other.years && months == other.months && return years == other.years && months == other.months
days == other.days && chronology.equals(other.chronology); && days == other.days && chronology.equals(other.chronology);
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,11 +49,9 @@ package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS; import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import static org.threeten.bp.temporal.ChronoUnit.NANOS; import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import java.util.function.ToLongFunction; import java.util.function.ToLongFunction;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -166,8 +179,10 @@ public abstract class ChronoZonedDateTime<D extends ChronoLocalDate>
public int get(TemporalField field) { public int get(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
switch ((ChronoField) field) { switch ((ChronoField) field) {
case INSTANT_SECONDS: throw new UnsupportedTemporalTypeException("Field too large for an int: " + field); case INSTANT_SECONDS:
case OFFSET_SECONDS: return getOffset().getTotalSeconds(); throw new UnsupportedTemporalTypeException("Field too large for an int: " + field);
case OFFSET_SECONDS:
return getOffset().getTotalSeconds();
} }
return toLocalDateTime().get(field); return toLocalDateTime().get(field);
} }
@ -468,8 +483,8 @@ public abstract class ChronoZonedDateTime<D extends ChronoLocalDate>
public boolean isAfter(ChronoZonedDateTime<?> other) { public boolean isAfter(ChronoZonedDateTime<?> other) {
long thisEpochSec = toEpochSecond(); long thisEpochSec = toEpochSecond();
long otherEpochSec = other.toEpochSecond(); long otherEpochSec = other.toEpochSecond();
return thisEpochSec > otherEpochSec || return thisEpochSec > otherEpochSec
(thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano()); || (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano());
} }
/** /**
@ -485,8 +500,8 @@ public abstract class ChronoZonedDateTime<D extends ChronoLocalDate>
public boolean isBefore(ChronoZonedDateTime<?> other) { public boolean isBefore(ChronoZonedDateTime<?> other) {
long thisEpochSec = toEpochSecond(); long thisEpochSec = toEpochSecond();
long otherEpochSec = other.toEpochSecond(); long otherEpochSec = other.toEpochSecond();
return thisEpochSec < otherEpochSec || return thisEpochSec < otherEpochSec
(thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano()); || (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano());
} }
/** /**
@ -500,8 +515,8 @@ public abstract class ChronoZonedDateTime<D extends ChronoLocalDate>
* @return true if the instant equals the instant of the specified date-time * @return true if the instant equals the instant of the specified date-time
*/ */
public boolean isEqual(ChronoZonedDateTime<?> other) { public boolean isEqual(ChronoZonedDateTime<?> other) {
return toEpochSecond() == other.toEpochSecond() && return toEpochSecond() == other.toEpochSecond()
toLocalTime().getNano() == other.toLocalTime().getNano(); && toLocalTime().getNano() == other.toLocalTime().getNano();
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,11 +47,9 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoUnit.SECONDS; import static org.threeten.bp.temporal.ChronoUnit.SECONDS;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime; import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
@ -127,7 +140,8 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
* @param zone the zone identifier, not null * @param zone the zone identifier, not null
* @return the zoned date-time, not null * @return the zoned date-time, not null
*/ */
static <R extends ChronoLocalDate> ChronoZonedDateTimeImpl<R> ofInstant(Chronology chrono, Instant instant, ZoneId zone) { static <R extends ChronoLocalDate> ChronoZonedDateTimeImpl<R> ofInstant(Chronology chrono, Instant instant,
ZoneId zone) {
ZoneRules rules = zone.getRules(); ZoneRules rules = zone.getRules();
ZoneOffset offset = rules.getOffset(instant); ZoneOffset offset = rules.getOffset(instant);
Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules
@ -171,6 +185,7 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
return unit != null && unit.isSupportedBy(this); return unit != null && unit.isSupportedBy(this);
} }
@Override
public ZoneOffset getOffset() { public ZoneOffset getOffset() {
return offset; return offset;
} }
@ -180,8 +195,8 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this));
if (trans != null && trans.isOverlap()) { if (trans != null && trans.isOverlap()) {
ZoneOffset earlierOffset = trans.getOffsetBefore(); ZoneOffset earlierOffset = trans.getOffsetBefore();
if (earlierOffset.equals(offset) == false) { if (!earlierOffset.equals(offset)) {
return new ChronoZonedDateTimeImpl<D>(dateTime, earlierOffset, zone); return new ChronoZonedDateTimeImpl<>(dateTime, earlierOffset, zone);
} }
} }
return this; return this;
@ -192,7 +207,7 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this));
if (trans != null) { if (trans != null) {
ZoneOffset offset = trans.getOffsetAfter(); ZoneOffset offset = trans.getOffsetAfter();
if (offset.equals(getOffset()) == false) { if (!offset.equals(getOffset())) {
return new ChronoZonedDateTimeImpl<>(dateTime, offset, zone); return new ChronoZonedDateTimeImpl<>(dateTime, offset, zone);
} }
} }
@ -205,10 +220,12 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
return dateTime; return dateTime;
} }
@Override
public ZoneId getZone() { public ZoneId getZone() {
return zone; return zone;
} }
@Override
public ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone) { public ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone) {
return ofBest(dateTime, zone, offset); return ofBest(dateTime, zone, offset);
} }
@ -248,7 +265,8 @@ final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate>
if (unit instanceof ChronoUnit) { if (unit instanceof ChronoUnit) {
return with(dateTime.plus(amountToAdd, unit)); return with(dateTime.plus(amountToAdd, unit));
} }
return toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! /// TODO: Generics replacement Risk!
return toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd));
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -39,7 +54,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
@ -161,7 +175,7 @@ public abstract class Chronology implements Comparable<Chronology> {
public static Chronology from(TemporalAccessor temporal) { public static Chronology from(TemporalAccessor temporal) {
Objects.requireNonNull(temporal, "temporal"); Objects.requireNonNull(temporal, "temporal");
Chronology obj = temporal.query(TemporalQueries.chronology()); Chronology obj = temporal.query(TemporalQueries.chronology());
return (obj != null ? obj : IsoChronology.INSTANCE); return obj != null ? obj : IsoChronology.INSTANCE;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -315,8 +329,9 @@ public abstract class Chronology implements Comparable<Chronology> {
<D extends ChronoLocalDate> D ensureChronoLocalDate(Temporal temporal) { <D extends ChronoLocalDate> D ensureChronoLocalDate(Temporal temporal) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
D other = (D) temporal; D other = (D) temporal;
if (this.equals(other.getChronology()) == false) { if (!this.equals(other.getChronology())) {
throw new ClassCastException("Chrono mismatch, expected: " + getId() + ", actual: " + other.getChronology().getId()); throw new ClassCastException("Chrono mismatch, expected: " + getId() + ", actual: "
+ other.getChronology().getId());
} }
return other; return other;
} }
@ -332,7 +347,7 @@ public abstract class Chronology implements Comparable<Chronology> {
<D extends ChronoLocalDate> ChronoLocalDateTimeImpl<D> ensureChronoLocalDateTime(Temporal temporal) { <D extends ChronoLocalDate> ChronoLocalDateTimeImpl<D> ensureChronoLocalDateTime(Temporal temporal) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ChronoLocalDateTimeImpl<D> other = (ChronoLocalDateTimeImpl<D>) temporal; ChronoLocalDateTimeImpl<D> other = (ChronoLocalDateTimeImpl<D>) temporal;
if (this.equals(other.toLocalDate().getChronology()) == false) { if (!this.equals(other.toLocalDate().getChronology())) {
throw new ClassCastException("Chrono mismatch, required: " + getId() throw new ClassCastException("Chrono mismatch, required: " + getId()
+ ", supplied: " + other.toLocalDate().getChronology().getId()); + ", supplied: " + other.toLocalDate().getChronology().getId());
} }
@ -347,10 +362,11 @@ public abstract class Chronology implements Comparable<Chronology> {
* @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl
* or the chronology is not equal this Chrono * or the chronology is not equal this Chrono
*/ */
@SuppressWarnings("checkstyle:SimplifyBooleanExpression")
<D extends ChronoLocalDate> ChronoZonedDateTimeImpl<D> ensureChronoZonedDateTime(Temporal temporal) { <D extends ChronoLocalDate> ChronoZonedDateTimeImpl<D> ensureChronoZonedDateTime(Temporal temporal) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ChronoZonedDateTimeImpl<D> other = (ChronoZonedDateTimeImpl<D>) temporal; ChronoZonedDateTimeImpl<D> other = (ChronoZonedDateTimeImpl<D>) temporal;
if (this.equals(other.toLocalDate().getChronology()) == false) { if (!this.equals(other.toLocalDate().getChronology())) {
throw new ClassCastException("Chrono mismatch, required: " + getId() throw new ClassCastException("Chrono mismatch, required: " + getId()
+ ", supplied: " + other.toLocalDate().getChronology().getId()); + ", supplied: " + other.toLocalDate().getChronology().getId());
} }
@ -536,7 +552,8 @@ public abstract class Chronology implements Comparable<Chronology> {
ChronoLocalDate date = date(temporal); ChronoLocalDate date = date(temporal);
return date.atTime(LocalTime.from(temporal)); return date.atTime(LocalTime.from(temporal));
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass(), ex); throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: "
+ temporal.getClass(), ex);
} }
} }
@ -567,7 +584,8 @@ public abstract class Chronology implements Comparable<Chronology> {
return ChronoZonedDateTimeImpl.ofBest(cldtImpl, zone, null); return ChronoZonedDateTimeImpl.ofBest(cldtImpl, zone, null);
} }
} catch (DateTimeException ex) { } catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex); throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: "
+ temporal.getClass(), ex);
} }
} }
@ -582,8 +600,7 @@ public abstract class Chronology implements Comparable<Chronology> {
* @throws DateTimeException if the result exceeds the supported range * @throws DateTimeException if the result exceeds the supported range
*/ */
public ChronoZonedDateTime<?> zonedDateTime(Instant instant, ZoneId zone) { public ChronoZonedDateTime<?> zonedDateTime(Instant instant, ZoneId zone) {
ChronoZonedDateTime<? extends ChronoLocalDate> result = ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone);
return result;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -760,8 +777,9 @@ public abstract class Chronology implements Comparable<Chronology> {
*/ */
void updateResolveMap(Map<TemporalField, Long> fieldValues, ChronoField field, long value) { void updateResolveMap(Map<TemporalField, Long> fieldValues, ChronoField field, long value) {
Long current = fieldValues.get(field); Long current = fieldValues.get(field);
if (current != null && current.longValue() != value) { if (current != null && current != value) {
throw new DateTimeException("Invalid state, field: " + field + " " + current + " conflicts with " + field + " " + value); throw new DateTimeException("Invalid state, field: " + field + " " + current + " conflicts with "
+ field + " " + value);
} }
fieldValues.put(field, value); fieldValues.put(field, value);
} }
@ -829,5 +847,4 @@ public abstract class Chronology implements Comparable<Chronology> {
public String toString() { public String toString() {
return getId(); return getId();
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -49,7 +64,6 @@ import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -57,7 +71,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -331,10 +344,10 @@ public final class HijrahChronology extends Chronology implements Serializable {
@Override @Override
public int prolepticYear(Era era, int yearOfEra) { public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof HijrahEra == false) { if (!(era instanceof HijrahEra)) {
throw new ClassCastException("Era must be HijrahEra"); throw new ClassCastException("Era must be HijrahEra");
} }
return (era == HijrahEra.AH ? yearOfEra : 1 - yearOfEra); return era == HijrahEra.AH ? yearOfEra : 1 - yearOfEra;
} }
@Override @Override
@ -388,18 +401,19 @@ public final class HijrahChronology extends Chronology implements Serializable {
if (resolverStyle == ResolverStyle.STRICT) { if (resolverStyle == ResolverStyle.STRICT) {
// do not invent era if strict, but do cross-check with year // do not invent era if strict, but do cross-check with year
if (year != null) { if (year != null) {
updateResolveMap(fieldValues, YEAR, (year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year > 0 ? yoeLong : Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
// reinstate the field removed earlier, no cross-check issues // reinstate the field removed earlier, no cross-check issues
fieldValues.put(YEAR_OF_ERA, yoeLong); fieldValues.put(YEAR_OF_ERA, yoeLong);
} }
} else { } else {
// invent era // invent era
updateResolveMap(fieldValues, YEAR, (year == null || year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR,
year == null || year > 0 ? yoeLong : Jdk8Methods.safeSubtract(1, yoeLong));
} }
} else if (era.longValue() == 1L) { } else if (era == 1L) {
updateResolveMap(fieldValues, YEAR, yoeLong); updateResolveMap(fieldValues, YEAR, yoeLong);
} else if (era.longValue() == 0L) { } else if (era == 0L) {
updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong)); updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
throw new DateTimeException("Invalid value for era: " + era); throw new DateTimeException("Invalid value for era: " + era);
@ -418,8 +432,10 @@ public final class HijrahChronology extends Chronology implements Serializable {
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1); long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plusMonths(months).plusDays(days); return date(y, 1, 1).plusMonths(months).plusDays(days);
} else { } else {
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR),
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH),
DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART && dom > 28) { if (resolverStyle == ResolverStyle.SMART && dom > 28) {
dom = Math.min(dom, date(y, moy, 1).lengthOfMonth()); dom = Math.min(dom, date(y, moy, 1).lengthOfMonth());
} }
@ -437,7 +453,8 @@ public final class HijrahChronology extends Chronology implements Serializable {
} }
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
HijrahDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); HijrahDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS);
if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month"); throw new DateTimeException("Strict mode rejected date parsed to a different month");
@ -481,7 +498,8 @@ public final class HijrahChronology extends Chronology implements Serializable {
return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS); return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS);
} }
int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
HijrahDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); HijrahDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) {
throw new DateTimeException("Strict mode rejected date parsed to a different year"); throw new DateTimeException("Strict mode rejected date parsed to a different year");

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -35,7 +50,6 @@ import static org.threeten.bp.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
import static org.threeten.bp.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; import static org.threeten.bp.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -49,7 +63,6 @@ import java.util.Objects;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -124,22 +137,22 @@ public final class HijrahDate
* 0-based, for number of day-of-year in the beginning of month in normal * 0-based, for number of day-of-year in the beginning of month in normal
* year. * year.
*/ */
private static final int NUM_DAYS[] = private static final int[] NUM_DAYS =
{0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325}; {0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325};
/** /**
* 0-based, for number of day-of-year in the beginning of month in leap year. * 0-based, for number of day-of-year in the beginning of month in leap year.
*/ */
private static final int LEAP_NUM_DAYS[] = private static final int[] LEAP_NUM_DAYS =
{0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325}; {0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325};
/** /**
* 0-based, for day-of-month in normal year. * 0-based, for day-of-month in normal year.
*/ */
private static final int MONTH_LENGTH[] = private static final int[] MONTH_LENGTH =
{30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29}; {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29};
/** /**
* 0-based, for day-of-month in leap year. * 0-based, for day-of-month in leap year.
*/ */
private static final int LEAP_MONTH_LENGTH[] = private static final int[] LEAP_MONTH_LENGTH =
{30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30}; {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30};
/** /**
@ -156,7 +169,7 @@ public final class HijrahDate
* *
* Minimum values. * Minimum values.
*/ */
private static final int MIN_VALUES[] = private static final int[] MIN_VALUES =
{ {
0, 0,
MIN_VALUE_OF_ERA, MIN_VALUE_OF_ERA,
@ -170,7 +183,7 @@ public final class HijrahDate
/** /**
* Least maximum values. * Least maximum values.
*/ */
private static final int LEAST_MAX_VALUES[] = private static final int[] LEAST_MAX_VALUES =
{ {
1, 1,
MAX_VALUE_OF_ERA, MAX_VALUE_OF_ERA,
@ -184,7 +197,7 @@ public final class HijrahDate
/** /**
* Maximum values. * Maximum values.
*/ */
private static final int MAX_VALUES[] = private static final int[] MAX_VALUES =
{ {
1, 1,
MAX_VALUE_OF_ERA, MAX_VALUE_OF_ERA,
@ -208,7 +221,7 @@ public final class HijrahDate
/** /**
* Zero-based start date of cycle year. * Zero-based start date of cycle year.
*/ */
private static final int CYCLEYEAR_START_DATE[] = private static final int[] CYCLEYEAR_START_DATE =
{ {
0, 0,
354, 354,
@ -257,23 +270,24 @@ public final class HijrahDate
/** /**
* Default path to the config file. * Default path to the config file.
*/ */
private static final String DEFAULT_CONFIG_PATH = "org" + FILE_SEP + "threeten" + FILE_SEP + "bp" + FILE_SEP + "chrono"; private static final String DEFAULT_CONFIG_PATH = "org" + FILE_SEP + "threeten" + FILE_SEP + "bp"
+ FILE_SEP + "chrono";
/** /**
* Holding the adjusted month days in year. The key is a year (Integer) and * Holding the adjusted month days in year. The key is a year (Integer) and
* the value is the all the month days in year (Integer[]). * the value is the all the month days in year (Integer[]).
*/ */
private static final HashMap<Integer, Integer[]> ADJUSTED_MONTH_DAYS = new HashMap<Integer, Integer[]>(); private static final HashMap<Integer, Integer[]> ADJUSTED_MONTH_DAYS = new HashMap<>();
/** /**
* Holding the adjusted month length in year. The key is a year (Integer) * Holding the adjusted month length in year. The key is a year (Integer)
* and the value is the all the month length in year (Integer[]). * and the value is the all the month length in year (Integer[]).
*/ */
private static final HashMap<Integer, Integer[]> ADJUSTED_MONTH_LENGTHS = new HashMap<Integer, Integer[]>(); private static final HashMap<Integer, Integer[]> ADJUSTED_MONTH_LENGTHS = new HashMap<>();
/** /**
* Holding the adjusted days in the 30 year cycle. The key is a cycle number * Holding the adjusted days in the 30 year cycle. The key is a cycle number
* (Integer) and the value is the all the starting days of the year in the * (Integer) and the value is the all the starting days of the year in the
* cycle (Integer[]). * cycle (Integer[]).
*/ */
private static final HashMap<Integer, Integer[]> ADJUSTED_CYCLE_YEARS = new HashMap<Integer, Integer[]>(); private static final HashMap<Integer, Integer[]> ADJUSTED_CYCLE_YEARS = new HashMap<>();
/** /**
* Holding the adjusted cycle in the 1 - 30000 year. The key is the cycle * Holding the adjusted cycle in the 1 - 30000 year. The key is the cycle
* number (Integer) and the value is the starting days in the cycle in the * number (Integer) and the value is the starting days in the cycle in the
@ -321,52 +335,49 @@ public final class HijrahDate
DEFAULT_MONTH_DAYS = new Integer[NUM_DAYS.length]; DEFAULT_MONTH_DAYS = new Integer[NUM_DAYS.length];
for (int i = 0; i < NUM_DAYS.length; i++) { for (int i = 0; i < NUM_DAYS.length; i++) {
DEFAULT_MONTH_DAYS[i] = Integer.valueOf(NUM_DAYS[i]); DEFAULT_MONTH_DAYS[i] = NUM_DAYS[i];
} }
DEFAULT_LEAP_MONTH_DAYS = new Integer[LEAP_NUM_DAYS.length]; DEFAULT_LEAP_MONTH_DAYS = new Integer[LEAP_NUM_DAYS.length];
for (int i = 0; i < LEAP_NUM_DAYS.length; i++) { for (int i = 0; i < LEAP_NUM_DAYS.length; i++) {
DEFAULT_LEAP_MONTH_DAYS[i] = Integer.valueOf(LEAP_NUM_DAYS[i]); DEFAULT_LEAP_MONTH_DAYS[i] = LEAP_NUM_DAYS[i];
} }
DEFAULT_MONTH_LENGTHS = new Integer[MONTH_LENGTH.length]; DEFAULT_MONTH_LENGTHS = new Integer[MONTH_LENGTH.length];
for (int i = 0; i < MONTH_LENGTH.length; i++) { for (int i = 0; i < MONTH_LENGTH.length; i++) {
DEFAULT_MONTH_LENGTHS[i] = Integer.valueOf(MONTH_LENGTH[i]); DEFAULT_MONTH_LENGTHS[i] = MONTH_LENGTH[i];
} }
DEFAULT_LEAP_MONTH_LENGTHS = new Integer[LEAP_MONTH_LENGTH.length]; DEFAULT_LEAP_MONTH_LENGTHS = new Integer[LEAP_MONTH_LENGTH.length];
for (int i = 0; i < LEAP_MONTH_LENGTH.length; i++) { for (int i = 0; i < LEAP_MONTH_LENGTH.length; i++) {
DEFAULT_LEAP_MONTH_LENGTHS[i] = Integer.valueOf(LEAP_MONTH_LENGTH[i]); DEFAULT_LEAP_MONTH_LENGTHS[i] = LEAP_MONTH_LENGTH[i];
} }
DEFAULT_CYCLE_YEARS = new Integer[CYCLEYEAR_START_DATE.length]; DEFAULT_CYCLE_YEARS = new Integer[CYCLEYEAR_START_DATE.length];
for (int i = 0; i < CYCLEYEAR_START_DATE.length; i++) { for (int i = 0; i < CYCLEYEAR_START_DATE.length; i++) {
DEFAULT_CYCLE_YEARS[i] = Integer.valueOf(CYCLEYEAR_START_DATE[i]); DEFAULT_CYCLE_YEARS[i] = CYCLEYEAR_START_DATE[i];
} }
ADJUSTED_CYCLES = new Long[MAX_ADJUSTED_CYCLE]; ADJUSTED_CYCLES = new Long[MAX_ADJUSTED_CYCLE];
for (int i = 0; i < ADJUSTED_CYCLES.length; i++) { for (int i = 0; i < ADJUSTED_CYCLES.length; i++) {
ADJUSTED_CYCLES[i] = Long.valueOf(10631 * i); ADJUSTED_CYCLES[i] = (long) (10631 * i);
} }
// Initialize min values, least max values and max values. // Initialize min values, least max values and max values.
ADJUSTED_MIN_VALUES = new Integer[MIN_VALUES.length]; ADJUSTED_MIN_VALUES = new Integer[MIN_VALUES.length];
for (int i = 0; i < MIN_VALUES.length; i++) { for (int i = 0; i < MIN_VALUES.length; i++) {
ADJUSTED_MIN_VALUES[i] = Integer.valueOf(MIN_VALUES[i]); ADJUSTED_MIN_VALUES[i] = MIN_VALUES[i];
} }
ADJUSTED_LEAST_MAX_VALUES = new Integer[LEAST_MAX_VALUES.length]; ADJUSTED_LEAST_MAX_VALUES = new Integer[LEAST_MAX_VALUES.length];
for (int i = 0; i < LEAST_MAX_VALUES.length; i++) { for (int i = 0; i < LEAST_MAX_VALUES.length; i++) {
ADJUSTED_LEAST_MAX_VALUES[i] = Integer.valueOf(LEAST_MAX_VALUES[i]); ADJUSTED_LEAST_MAX_VALUES[i] = LEAST_MAX_VALUES[i];
} }
ADJUSTED_MAX_VALUES = new Integer[MAX_VALUES.length]; ADJUSTED_MAX_VALUES = new Integer[MAX_VALUES.length];
for (int i = 0; i < MAX_VALUES.length; i++) { for (int i = 0; i < MAX_VALUES.length; i++) {
ADJUSTED_MAX_VALUES[i] = Integer.valueOf(MAX_VALUES[i]); ADJUSTED_MAX_VALUES[i] = MAX_VALUES[i];
} }
try { try {
readDeviationConfig(); readDeviationConfig();
} catch (IOException e) { } catch (IOException | ParseException e) {
// do nothing. Ignore deviation config.
// e.printStackTrace();
} catch (ParseException e) {
// do nothing. Ignore deviation config. // do nothing. Ignore deviation config.
// e.printStackTrace(); // e.printStackTrace();
} }
@ -471,13 +482,11 @@ public final class HijrahDate
* @param monthOfYear the month-of-year to represent, from 1 to 12 * @param monthOfYear the month-of-year to represent, from 1 to 12
* @param dayOfMonth the day-of-month to represent, from 1 to 30 * @param dayOfMonth the day-of-month to represent, from 1 to 30
* @return the Hijrah date, never null * @return the Hijrah date, never null
* @throws IllegalCalendarFieldValueException if the value of any field is out of range
* @throws InvalidCalendarFieldException if the day-of-month is invalid for the month-year
*/ */
public static HijrahDate of(int prolepticYear, int monthOfYear, int dayOfMonth) { public static HijrahDate of(int prolepticYear, int monthOfYear, int dayOfMonth) {
return (prolepticYear >= 1) ? return (prolepticYear >= 1)
HijrahDate.of(HijrahEra.AH, prolepticYear, monthOfYear, dayOfMonth) : ? HijrahDate.of(HijrahEra.AH, prolepticYear, monthOfYear, dayOfMonth)
HijrahDate.of(HijrahEra.BEFORE_AH, 1 - prolepticYear, monthOfYear, dayOfMonth); : HijrahDate.of(HijrahEra.BEFORE_AH, 1 - prolepticYear, monthOfYear, dayOfMonth);
} }
/** /**
@ -489,8 +498,6 @@ public final class HijrahDate
* @param monthOfYear the month-of-year to represent, from 1 to 12 * @param monthOfYear the month-of-year to represent, from 1 to 12
* @param dayOfMonth the day-of-month to represent, from 1 to 31 * @param dayOfMonth the day-of-month to represent, from 1 to 31
* @return the Hijrah date, never null * @return the Hijrah date, never null
* @throws IllegalCalendarFieldValueException if the value of any field is out of range
* @throws InvalidCalendarFieldException if the day-of-month is invalid for the month-year
*/ */
static HijrahDate of(HijrahEra era, int yearOfEra, int monthOfYear, int dayOfMonth) { static HijrahDate of(HijrahEra era, int yearOfEra, int monthOfYear, int dayOfMonth) {
Objects.requireNonNull(era, "era"); Objects.requireNonNull(era, "era");
@ -506,15 +513,13 @@ public final class HijrahDate
* @param yearOfEra the year to check * @param yearOfEra the year to check
*/ */
private static void checkValidYearOfEra(int yearOfEra) { private static void checkValidYearOfEra(int yearOfEra) {
if (yearOfEra < MIN_VALUE_OF_ERA || if (yearOfEra < MIN_VALUE_OF_ERA || yearOfEra > MAX_VALUE_OF_ERA) {
yearOfEra > MAX_VALUE_OF_ERA) {
throw new DateTimeException("Invalid year of Hijrah Era"); throw new DateTimeException("Invalid year of Hijrah Era");
} }
} }
private static void checkValidDayOfYear(int dayOfYear) { private static void checkValidDayOfYear(int dayOfYear) {
if (dayOfYear < 1 || if (dayOfYear < 1 || dayOfYear > getMaximumDayOfYear()) {
dayOfYear > getMaximumDayOfYear()) {
throw new DateTimeException("Invalid day of year of Hijrah date"); throw new DateTimeException("Invalid day of year of Hijrah date");
} }
} }
@ -526,8 +531,7 @@ public final class HijrahDate
} }
private static void checkValidDayOfMonth(int dayOfMonth) { private static void checkValidDayOfMonth(int dayOfMonth) {
if (dayOfMonth < 1 || if (dayOfMonth < 1 || dayOfMonth > getMaximumDayOfMonth()) {
dayOfMonth > getMaximumDayOfMonth()) {
throw new DateTimeException("Invalid day of month of Hijrah date, day " throw new DateTimeException("Invalid day of month of Hijrah date, day "
+ dayOfMonth + " greater than " + getMaximumDayOfMonth() + " or less than 1"); + dayOfMonth + " greater than " + getMaximumDayOfMonth() + " or less than 1");
} }
@ -538,7 +542,6 @@ public final class HijrahDate
* *
* @param date the date to use, not null * @param date the date to use, not null
* @return the Hijrah date, never null * @return the Hijrah date, never null
* @throws IllegalCalendarFieldValueException if the year is invalid
*/ */
static HijrahDate of(LocalDate date) { static HijrahDate of(LocalDate date) {
long gregorianDays = date.toEpochDay(); long gregorianDays = date.toEpochDay();
@ -627,18 +630,29 @@ public final class HijrahDate
public long getLong(TemporalField field) { public long getLong(TemporalField field) {
if (field instanceof ChronoField) { if (field instanceof ChronoField) {
switch ((ChronoField) field) { switch ((ChronoField) field) {
case DAY_OF_WEEK: return dayOfWeek.getValue(); case DAY_OF_WEEK:
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((dayOfMonth - 1) % 7) + 1; return dayOfWeek.getValue();
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((dayOfYear - 1) % 7) + 1; case ALIGNED_DAY_OF_WEEK_IN_MONTH:
case DAY_OF_MONTH: return this.dayOfMonth; return ((dayOfMonth - 1) % 7) + 1;
case DAY_OF_YEAR: return this.dayOfYear; case ALIGNED_DAY_OF_WEEK_IN_YEAR:
case EPOCH_DAY: return toEpochDay(); return ((dayOfYear - 1) % 7) + 1;
case ALIGNED_WEEK_OF_MONTH: return ((dayOfMonth - 1) / 7) + 1; case DAY_OF_MONTH:
case ALIGNED_WEEK_OF_YEAR: return ((dayOfYear - 1) / 7) + 1; return this.dayOfMonth;
case MONTH_OF_YEAR: return monthOfYear; case DAY_OF_YEAR:
case YEAR_OF_ERA: return yearOfEra; return this.dayOfYear;
case YEAR: return yearOfEra; case EPOCH_DAY:
case ERA: return era.getValue(); return toEpochDay();
case ALIGNED_WEEK_OF_MONTH:
return ((dayOfMonth - 1) / 7) + 1;
case ALIGNED_WEEK_OF_YEAR:
return ((dayOfYear - 1) / 7) + 1;
case MONTH_OF_YEAR:
return monthOfYear;
case YEAR_OF_ERA:
case YEAR:
return yearOfEra;
case ERA:
return era.getValue();
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -658,18 +672,30 @@ public final class HijrahDate
f.checkValidValue(newValue); // TODO: validate value f.checkValidValue(newValue); // TODO: validate value
int nvalue = (int) newValue; int nvalue = (int) newValue;
switch (f) { switch (f) {
case DAY_OF_WEEK: return plusDays(newValue - dayOfWeek.getValue()); case DAY_OF_WEEK:
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH)); return plusDays(newValue - dayOfWeek.getValue());
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR)); case ALIGNED_DAY_OF_WEEK_IN_MONTH:
case DAY_OF_MONTH: return resolvePreviousValid(yearOfEra, monthOfYear, nvalue); return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH));
case DAY_OF_YEAR: return resolvePreviousValid(yearOfEra, ((nvalue - 1) / 30) + 1, ((nvalue - 1) % 30) + 1); case ALIGNED_DAY_OF_WEEK_IN_YEAR:
case EPOCH_DAY: return new HijrahDate(nvalue); return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR));
case ALIGNED_WEEK_OF_MONTH: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_MONTH)) * 7); case DAY_OF_MONTH:
case ALIGNED_WEEK_OF_YEAR: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_YEAR)) * 7); return resolvePreviousValid(yearOfEra, monthOfYear, nvalue);
case MONTH_OF_YEAR: return resolvePreviousValid(yearOfEra, nvalue, dayOfMonth); case DAY_OF_YEAR:
case YEAR_OF_ERA: return resolvePreviousValid(yearOfEra >= 1 ? nvalue : 1 - nvalue, monthOfYear, dayOfMonth); return resolvePreviousValid(yearOfEra, ((nvalue - 1) / 30) + 1, ((nvalue - 1) % 30) + 1);
case YEAR: return resolvePreviousValid(nvalue, monthOfYear, dayOfMonth); case EPOCH_DAY:
case ERA: return resolvePreviousValid(1 - yearOfEra, monthOfYear, dayOfMonth); return new HijrahDate(nvalue);
case ALIGNED_WEEK_OF_MONTH:
return plusDays((newValue - getLong(ALIGNED_WEEK_OF_MONTH)) * 7);
case ALIGNED_WEEK_OF_YEAR:
return plusDays((newValue - getLong(ALIGNED_WEEK_OF_YEAR)) * 7);
case MONTH_OF_YEAR:
return resolvePreviousValid(yearOfEra, nvalue, dayOfMonth);
case YEAR_OF_ERA:
return resolvePreviousValid(yearOfEra >= 1 ? nvalue : 1 - nvalue, monthOfYear, dayOfMonth);
case YEAR:
return resolvePreviousValid(nvalue, monthOfYear, dayOfMonth);
case ERA:
return resolvePreviousValid(1 - yearOfEra, monthOfYear, dayOfMonth);
} }
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
@ -733,7 +759,7 @@ public final class HijrahDate
if (years == 0) { if (years == 0) {
return this; return this;
} }
int newYear = Jdk8Methods.safeAdd(this.yearOfEra, (int)years); int newYear = Jdk8Methods.safeAdd(this.yearOfEra, (int) years);
return HijrahDate.of(this.era, newYear, this.monthOfYear, this.dayOfMonth); return HijrahDate.of(this.era, newYear, this.monthOfYear, this.dayOfMonth);
} }
@ -743,7 +769,7 @@ public final class HijrahDate
return this; return this;
} }
int newMonth = this.monthOfYear - 1; int newMonth = this.monthOfYear - 1;
newMonth = newMonth + (int)months; newMonth = newMonth + (int) months;
int years = newMonth / 12; int years = newMonth / 12;
newMonth = newMonth % 12; newMonth = newMonth % 12;
while (newMonth < 0) { while (newMonth < 0) {
@ -770,12 +796,19 @@ public final class HijrahDate
* int[4] = DAY_OF_YEAR * int[4] = DAY_OF_YEAR
* int[5] = DAY_OF_WEEK * int[5] = DAY_OF_WEEK
* *
* @param julianDay a julian day. * @param gregorianDays a julian day.
*/ */
private static int[] getHijrahDateInfo(long gregorianDays) { private static int[] getHijrahDateInfo(long gregorianDays) {
int era, year, month, date, dayOfWeek, dayOfYear; int era;
int year;
int month;
int date;
int dayOfWeek;
int dayOfYear;
int cycleNumber, yearInCycle, dayOfCycle; int cycleNumber;
int yearInCycle;
int dayOfCycle;
long epochDay = gregorianDays - HIJRAH_JAN_1_1_GREGORIAN_DAY; long epochDay = gregorianDays - HIJRAH_JAN_1_1_GREGORIAN_DAY;
@ -801,8 +834,7 @@ public final class HijrahDate
dayOfYear = getDayOfYear(cycleNumber, dayOfCycle, yearInCycle); dayOfYear = getDayOfYear(cycleNumber, dayOfCycle, yearInCycle);
year = cycleNumber * 30 - yearInCycle; // negative number. year = cycleNumber * 30 - yearInCycle; // negative number.
year = 1 - year; year = 1 - year;
dayOfYear = (isLeapYear(year) ? (dayOfYear + 355) dayOfYear = isLeapYear(year) ? dayOfYear + 355 : dayOfYear + 354;
: (dayOfYear + 354));
month = getMonthOfYear(dayOfYear, year); month = getMonthOfYear(dayOfYear, year);
date = getDayOfMonth(dayOfYear, month, year); date = getDayOfMonth(dayOfYear, month, year);
++date; // Convert from 0-based to 1-based ++date; // Convert from 0-based to 1-based
@ -812,7 +844,7 @@ public final class HijrahDate
dayOfWeek = (int) ((epochDay + 5) % 7); dayOfWeek = (int) ((epochDay + 5) % 7);
dayOfWeek += (dayOfWeek <= 0) ? 7 : 0; dayOfWeek += (dayOfWeek <= 0) ? 7 : 0;
int dateInfo[] = new int[6]; int[] dateInfo = new int[6];
dateInfo[0] = era; dateInfo[0] = era;
dateInfo[1] = year; dateInfo[1] = year;
dateInfo[2] = month + 1; // change to 1-based. dateInfo[2] = month + 1; // change to 1-based.
@ -847,8 +879,7 @@ public final class HijrahDate
int cycleNumber = (prolepticYear - 1) / 30; // 0-based. int cycleNumber = (prolepticYear - 1) / 30; // 0-based.
int yearInCycle = (prolepticYear - 1) % 30; // 0-based. int yearInCycle = (prolepticYear - 1) % 30; // 0-based.
int dayInCycle = getAdjustedCycle(cycleNumber)[Math.abs(yearInCycle)] int dayInCycle = getAdjustedCycle(cycleNumber)[Math.abs(yearInCycle)];
.intValue();
if (yearInCycle < 0) { if (yearInCycle < 0) {
dayInCycle = -dayInCycle; dayInCycle = -dayInCycle;
@ -863,10 +894,10 @@ public final class HijrahDate
} }
if (cycleDays == null) { if (cycleDays == null) {
cycleDays = Long.valueOf(cycleNumber * 10631); cycleDays = (long) (cycleNumber * 10631);
} }
return (cycleDays.longValue() + dayInCycle + HIJRAH_JAN_1_1_GREGORIAN_DAY - 1); return cycleDays + dayInCycle + HIJRAH_JAN_1_1_GREGORIAN_DAY - 1;
} }
/** /**
@ -880,7 +911,7 @@ public final class HijrahDate
int cycleNumber; int cycleNumber;
try { try {
for (int i = 0; i < days.length; i++) { for (int i = 0; i < days.length; i++) {
if (epochDay < days[i].longValue()) { if (epochDay < days[i]) {
return i - 1; return i - 1;
} }
} }
@ -908,9 +939,9 @@ public final class HijrahDate
day = null; day = null;
} }
if (day == null) { if (day == null) {
day = Long.valueOf(cycleNumber * 10631); day = (long) (cycleNumber * 10631);
} }
return (int) (epochDay - day.longValue()); return (int) (epochDay - day);
} }
/** /**
@ -928,7 +959,7 @@ public final class HijrahDate
if (dayOfCycle > 0) { if (dayOfCycle > 0) {
for (int i = 0; i < cycles.length; i++) { for (int i = 0; i < cycles.length; i++) {
if (dayOfCycle < cycles[i].intValue()) { if (dayOfCycle < cycles[i]) {
return i - 1; return i - 1;
} }
} }
@ -936,7 +967,7 @@ public final class HijrahDate
} else { } else {
dayOfCycle = -dayOfCycle; dayOfCycle = -dayOfCycle;
for (int i = 0; i < cycles.length; i++) { for (int i = 0; i < cycles.length; i++) {
if (dayOfCycle <= cycles[i].intValue()) { if (dayOfCycle <= cycles[i]) {
return i - 1; return i - 1;
} }
} }
@ -954,7 +985,7 @@ public final class HijrahDate
private static Integer[] getAdjustedCycle(int cycleNumber) { private static Integer[] getAdjustedCycle(int cycleNumber) {
Integer[] cycles; Integer[] cycles;
try { try {
cycles = ADJUSTED_CYCLE_YEARS.get(Integer.valueOf(cycleNumber)); cycles = ADJUSTED_CYCLE_YEARS.get(cycleNumber);
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
cycles = null; cycles = null;
} }
@ -973,7 +1004,7 @@ public final class HijrahDate
private static Integer[] getAdjustedMonthDays(int year) { private static Integer[] getAdjustedMonthDays(int year) {
Integer[] newMonths; Integer[] newMonths;
try { try {
newMonths = ADJUSTED_MONTH_DAYS.get(Integer.valueOf(year)); newMonths = ADJUSTED_MONTH_DAYS.get(year);
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
newMonths = null; newMonths = null;
} }
@ -996,7 +1027,7 @@ public final class HijrahDate
private static Integer[] getAdjustedMonthLength(int year) { private static Integer[] getAdjustedMonthLength(int year) {
Integer[] newMonths; Integer[] newMonths;
try { try {
newMonths = ADJUSTED_MONTH_LENGTHS.get(Integer.valueOf(year)); newMonths = ADJUSTED_MONTH_LENGTHS.get(year);
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
newMonths = null; newMonths = null;
} }
@ -1022,9 +1053,9 @@ public final class HijrahDate
Integer[] cycles = getAdjustedCycle(cycleNumber); Integer[] cycles = getAdjustedCycle(cycleNumber);
if (dayOfCycle > 0) { if (dayOfCycle > 0) {
return dayOfCycle - cycles[yearInCycle].intValue(); return dayOfCycle - cycles[yearInCycle];
} else { } else {
return cycles[yearInCycle].intValue() + dayOfCycle; return cycles[yearInCycle] + dayOfCycle;
} }
} }
@ -1041,16 +1072,15 @@ public final class HijrahDate
if (dayOfYear >= 0) { if (dayOfYear >= 0) {
for (int i = 0; i < newMonths.length; i++) { for (int i = 0; i < newMonths.length; i++) {
if (dayOfYear < newMonths[i].intValue()) { if (dayOfYear < newMonths[i]) {
return i - 1; return i - 1;
} }
} }
return 11; return 11;
} else { } else {
dayOfYear = (isLeapYear(year) ? (dayOfYear + 355) dayOfYear = isLeapYear(year) ? (dayOfYear + 355) : (dayOfYear + 354);
: (dayOfYear + 354));
for (int i = 0; i < newMonths.length; i++) { for (int i = 0; i < newMonths.length; i++) {
if (dayOfYear < newMonths[i].intValue()) { if (dayOfYear < newMonths[i]) {
return i - 1; return i - 1;
} }
} }
@ -1072,15 +1102,14 @@ public final class HijrahDate
if (dayOfYear >= 0) { if (dayOfYear >= 0) {
if (month > 0) { if (month > 0) {
return dayOfYear - newMonths[month].intValue(); return dayOfYear - newMonths[month];
} else { } else {
return dayOfYear; return dayOfYear;
} }
} else { } else {
dayOfYear = (isLeapYear(year) ? (dayOfYear + 355) dayOfYear = isLeapYear(year) ? dayOfYear + 355 : dayOfYear + 354;
: (dayOfYear + 354));
if (month > 0) { if (month > 0) {
return dayOfYear - newMonths[month].intValue(); return dayOfYear - newMonths[month];
} else { } else {
return dayOfYear; return dayOfYear;
} }
@ -1101,12 +1130,12 @@ public final class HijrahDate
* Returns month days from the beginning of year. * Returns month days from the beginning of year.
* *
* @param month month (0-based) * @param month month (0-based)
* @parma year year * @param year year
* @return month days from the beginning of year * @return month days from the beginning of year
*/ */
private static int getMonthDays(int month, int year) { private static int getMonthDays(int month, int year) {
Integer[] newMonths = getAdjustedMonthDays(year); Integer[] newMonths = getAdjustedMonthDays(year);
return newMonths[month].intValue(); return newMonths[month];
} }
/** /**
@ -1118,7 +1147,7 @@ public final class HijrahDate
*/ */
static int getMonthLength(int month, int year) { static int getMonthLength(int month, int year) {
Integer[] newMonths = getAdjustedMonthLength(year); Integer[] newMonths = getAdjustedMonthLength(year);
return newMonths[month].intValue(); return newMonths[month];
} }
@Override @Override
@ -1146,10 +1175,9 @@ public final class HijrahDate
if (yearInCycle == 29) { if (yearInCycle == 29) {
return ADJUSTED_CYCLES[cycleNumber + 1].intValue() return ADJUSTED_CYCLES[cycleNumber + 1].intValue()
- ADJUSTED_CYCLES[cycleNumber].intValue() - ADJUSTED_CYCLES[cycleNumber].intValue()
- cycleYears[yearInCycle].intValue(); - cycleYears[yearInCycle];
} }
return cycleYears[yearInCycle + 1].intValue() return cycleYears[yearInCycle + 1] - cycleYears[yearInCycle];
- cycleYears[yearInCycle].intValue();
} else { } else {
return isLeapYear(year) ? 355 : 354; return isLeapYear(year) ? 355 : 354;
} }
@ -1244,18 +1272,17 @@ public final class HijrahDate
boolean isStartYLeap = isLeapYear(startYear); boolean isStartYLeap = isLeapYear(startYear);
// Adjusting the number of month. // Adjusting the number of month.
Integer[] orgStartMonthNums = ADJUSTED_MONTH_DAYS.get(Integer.valueOf( Integer[] orgStartMonthNums = ADJUSTED_MONTH_DAYS.get(startYear);
startYear));
if (orgStartMonthNums == null) { if (orgStartMonthNums == null) {
if (isStartYLeap) { if (isStartYLeap) {
orgStartMonthNums = new Integer[LEAP_NUM_DAYS.length]; orgStartMonthNums = new Integer[LEAP_NUM_DAYS.length];
for (int l = 0; l < LEAP_NUM_DAYS.length; l++) { for (int l = 0; l < LEAP_NUM_DAYS.length; l++) {
orgStartMonthNums[l] = Integer.valueOf(LEAP_NUM_DAYS[l]); orgStartMonthNums[l] = LEAP_NUM_DAYS[l];
} }
} else { } else {
orgStartMonthNums = new Integer[NUM_DAYS.length]; orgStartMonthNums = new Integer[NUM_DAYS.length];
for (int l = 0; l < NUM_DAYS.length; l++) { for (int l = 0; l < NUM_DAYS.length; l++) {
orgStartMonthNums[l] = Integer.valueOf(NUM_DAYS[l]); orgStartMonthNums[l] = NUM_DAYS[l];
} }
} }
} }
@ -1264,31 +1291,27 @@ public final class HijrahDate
for (int month = 0; month < 12; month++) { for (int month = 0; month < 12; month++) {
if (month > startMonth) { if (month > startMonth) {
newStartMonthNums[month] = Integer.valueOf(orgStartMonthNums[month] newStartMonthNums[month] = orgStartMonthNums[month] - offset;
.intValue()
- offset);
} else { } else {
newStartMonthNums[month] = Integer.valueOf(orgStartMonthNums[month] newStartMonthNums[month] = orgStartMonthNums[month].intValue();
.intValue());
} }
} }
ADJUSTED_MONTH_DAYS.put(Integer.valueOf(startYear), newStartMonthNums); ADJUSTED_MONTH_DAYS.put(startYear, newStartMonthNums);
// Adjusting the days of month. // Adjusting the days of month.
Integer[] orgStartMonthLengths = ADJUSTED_MONTH_LENGTHS.get(Integer.valueOf( Integer[] orgStartMonthLengths = ADJUSTED_MONTH_LENGTHS.get(startYear);
startYear));
if (orgStartMonthLengths == null) { if (orgStartMonthLengths == null) {
if (isStartYLeap) { if (isStartYLeap) {
orgStartMonthLengths = new Integer[LEAP_MONTH_LENGTH.length]; orgStartMonthLengths = new Integer[LEAP_MONTH_LENGTH.length];
for (int l = 0; l < LEAP_MONTH_LENGTH.length; l++) { for (int l = 0; l < LEAP_MONTH_LENGTH.length; l++) {
orgStartMonthLengths[l] = Integer.valueOf(LEAP_MONTH_LENGTH[l]); orgStartMonthLengths[l] = LEAP_MONTH_LENGTH[l];
} }
} else { } else {
orgStartMonthLengths = new Integer[MONTH_LENGTH.length]; orgStartMonthLengths = new Integer[MONTH_LENGTH.length];
for (int l = 0; l < MONTH_LENGTH.length; l++) { for (int l = 0; l < MONTH_LENGTH.length; l++) {
orgStartMonthLengths[l] = Integer.valueOf(MONTH_LENGTH[l]); orgStartMonthLengths[l] = MONTH_LENGTH[l];
} }
} }
} }
@ -1297,36 +1320,33 @@ public final class HijrahDate
for (int month = 0; month < 12; month++) { for (int month = 0; month < 12; month++) {
if (month == startMonth) { if (month == startMonth) {
newStartMonthLengths[month] = Integer.valueOf( newStartMonthLengths[month] = orgStartMonthLengths[month] - offset;
orgStartMonthLengths[month].intValue() - offset);
} else { } else {
newStartMonthLengths[month] = Integer.valueOf( newStartMonthLengths[month] = orgStartMonthLengths[month].intValue();
orgStartMonthLengths[month].intValue());
} }
} }
ADJUSTED_MONTH_LENGTHS.put(Integer.valueOf(startYear), newStartMonthLengths); ADJUSTED_MONTH_LENGTHS.put(startYear, newStartMonthLengths);
if (startYear != endYear) { if (startYear != endYear) {
// System.out.println("over year"); // System.out.println("over year");
// Adjusting starting 30 year cycle. // Adjusting starting 30 year cycle.
int sCycleNumber = (startYear - 1) / 30; int sCycleNumber = (startYear - 1) / 30;
int sYearInCycle = (startYear - 1) % 30; // 0-based. int sYearInCycle = (startYear - 1) % 30; // 0-based.
Integer[] startCycles = ADJUSTED_CYCLE_YEARS.get(Integer.valueOf( Integer[] startCycles = ADJUSTED_CYCLE_YEARS.get(sCycleNumber);
sCycleNumber));
if (startCycles == null) { if (startCycles == null) {
startCycles = new Integer[CYCLEYEAR_START_DATE.length]; startCycles = new Integer[CYCLEYEAR_START_DATE.length];
for (int j = 0; j < startCycles.length; j++) { for (int j = 0; j < startCycles.length; j++) {
startCycles[j] = Integer.valueOf(CYCLEYEAR_START_DATE[j]); startCycles[j] = CYCLEYEAR_START_DATE[j];
} }
} }
for (int j = sYearInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) { for (int j = sYearInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) {
startCycles[j] = Integer.valueOf(startCycles[j].intValue() - offset); startCycles[j] = startCycles[j] - offset;
} }
// System.out.println(sCycleNumber + ":" + sYearInCycle); // System.out.println(sCycleNumber + ":" + sYearInCycle);
ADJUSTED_CYCLE_YEARS.put(Integer.valueOf(sCycleNumber), startCycles); ADJUSTED_CYCLE_YEARS.put(sCycleNumber, startCycles);
int sYearInMaxY = (startYear - 1) / 30; int sYearInMaxY = (startYear - 1) / 30;
int sEndInMaxY = (endYear - 1) / 30; int sEndInMaxY = (endYear - 1) / 30;
@ -1337,49 +1357,46 @@ public final class HijrahDate
// System.out.println(sYearInMaxY); // System.out.println(sYearInMaxY);
for (int j = sYearInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) { for (int j = sYearInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) {
ADJUSTED_CYCLES[j] = Long.valueOf(ADJUSTED_CYCLES[j].longValue() ADJUSTED_CYCLES[j] = ADJUSTED_CYCLES[j] - offset;
- offset);
} }
// Adjusting ending 30 * MAX_ADJUSTED_CYCLE year cycles. // Adjusting ending 30 * MAX_ADJUSTED_CYCLE year cycles.
for (int j = sEndInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) { for (int j = sEndInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) {
ADJUSTED_CYCLES[j] = Long.valueOf(ADJUSTED_CYCLES[j].longValue() ADJUSTED_CYCLES[j] = ADJUSTED_CYCLES[j] + offset;
+ offset);
} }
} }
// Adjusting ending 30 year cycle. // Adjusting ending 30 year cycle.
int eCycleNumber = (endYear - 1) / 30; int eCycleNumber = (endYear - 1) / 30;
int sEndInCycle = (endYear - 1) % 30; // 0-based. int sEndInCycle = (endYear - 1) % 30; // 0-based.
Integer[] endCycles = ADJUSTED_CYCLE_YEARS.get(Integer.valueOf( Integer[] endCycles = ADJUSTED_CYCLE_YEARS.get(eCycleNumber);
eCycleNumber));
if (endCycles == null) { if (endCycles == null) {
endCycles = new Integer[CYCLEYEAR_START_DATE.length]; endCycles = new Integer[CYCLEYEAR_START_DATE.length];
for (int j = 0; j < endCycles.length; j++) { for (int j = 0; j < endCycles.length; j++) {
endCycles[j] = Integer.valueOf(CYCLEYEAR_START_DATE[j]); endCycles[j] = CYCLEYEAR_START_DATE[j];
} }
} }
for (int j = sEndInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) { for (int j = sEndInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) {
endCycles[j] = Integer.valueOf(endCycles[j].intValue() + offset); endCycles[j] = endCycles[j].intValue() + offset;
} }
ADJUSTED_CYCLE_YEARS.put(Integer.valueOf(eCycleNumber), endCycles); ADJUSTED_CYCLE_YEARS.put(eCycleNumber, endCycles);
} }
// Adjusting ending year. // Adjusting ending year.
boolean isEndYLeap = isLeapYear(endYear); boolean isEndYLeap = isLeapYear(endYear);
Integer[] orgEndMonthDays = ADJUSTED_MONTH_DAYS.get(Integer.valueOf(endYear)); Integer[] orgEndMonthDays = ADJUSTED_MONTH_DAYS.get(endYear);
if (orgEndMonthDays == null) { if (orgEndMonthDays == null) {
if (isEndYLeap) { if (isEndYLeap) {
orgEndMonthDays = new Integer[LEAP_NUM_DAYS.length]; orgEndMonthDays = new Integer[LEAP_NUM_DAYS.length];
for (int l = 0; l < LEAP_NUM_DAYS.length; l++) { for (int l = 0; l < LEAP_NUM_DAYS.length; l++) {
orgEndMonthDays[l] = Integer.valueOf(LEAP_NUM_DAYS[l]); orgEndMonthDays[l] = LEAP_NUM_DAYS[l];
} }
} else { } else {
orgEndMonthDays = new Integer[NUM_DAYS.length]; orgEndMonthDays = new Integer[NUM_DAYS.length];
for (int l = 0; l < NUM_DAYS.length; l++) { for (int l = 0; l < NUM_DAYS.length; l++) {
orgEndMonthDays[l] = Integer.valueOf(NUM_DAYS[l]); orgEndMonthDays[l] = NUM_DAYS[l];
} }
} }
} }
@ -1388,31 +1405,27 @@ public final class HijrahDate
for (int month = 0; month < 12; month++) { for (int month = 0; month < 12; month++) {
if (month > endMonth) { if (month > endMonth) {
newEndMonthDays[month] = Integer.valueOf(orgEndMonthDays[month] newEndMonthDays[month] = orgEndMonthDays[month] + offset;
.intValue()
+ offset);
} else { } else {
newEndMonthDays[month] = Integer.valueOf(orgEndMonthDays[month] newEndMonthDays[month] = orgEndMonthDays[month].intValue();
.intValue());
} }
} }
ADJUSTED_MONTH_DAYS.put(Integer.valueOf(endYear), newEndMonthDays); ADJUSTED_MONTH_DAYS.put(endYear, newEndMonthDays);
// Adjusting the days of month. // Adjusting the days of month.
Integer[] orgEndMonthLengths = ADJUSTED_MONTH_LENGTHS.get(Integer.valueOf( Integer[] orgEndMonthLengths = ADJUSTED_MONTH_LENGTHS.get(endYear);
endYear));
if (orgEndMonthLengths == null) { if (orgEndMonthLengths == null) {
if (isEndYLeap) { if (isEndYLeap) {
orgEndMonthLengths = new Integer[LEAP_MONTH_LENGTH.length]; orgEndMonthLengths = new Integer[LEAP_MONTH_LENGTH.length];
for (int l = 0; l < LEAP_MONTH_LENGTH.length; l++) { for (int l = 0; l < LEAP_MONTH_LENGTH.length; l++) {
orgEndMonthLengths[l] = Integer.valueOf(LEAP_MONTH_LENGTH[l]); orgEndMonthLengths[l] = LEAP_MONTH_LENGTH[l];
} }
} else { } else {
orgEndMonthLengths = new Integer[MONTH_LENGTH.length]; orgEndMonthLengths = new Integer[MONTH_LENGTH.length];
for (int l = 0; l < MONTH_LENGTH.length; l++) { for (int l = 0; l < MONTH_LENGTH.length; l++) {
orgEndMonthLengths[l] = Integer.valueOf(MONTH_LENGTH[l]); orgEndMonthLengths[l] = MONTH_LENGTH[l];
} }
} }
} }
@ -1421,35 +1434,26 @@ public final class HijrahDate
for (int month = 0; month < 12; month++) { for (int month = 0; month < 12; month++) {
if (month == endMonth) { if (month == endMonth) {
newEndMonthLengths[month] = Integer.valueOf( newEndMonthLengths[month] = orgEndMonthLengths[month].intValue() + offset;
orgEndMonthLengths[month].intValue() + offset);
} else { } else {
newEndMonthLengths[month] = Integer.valueOf( newEndMonthLengths[month] = orgEndMonthLengths[month].intValue();
orgEndMonthLengths[month].intValue());
} }
} }
ADJUSTED_MONTH_LENGTHS.put(Integer.valueOf(endYear), newEndMonthLengths); ADJUSTED_MONTH_LENGTHS.put(endYear, newEndMonthLengths);
Integer[] startMonthLengths = ADJUSTED_MONTH_LENGTHS.get(Integer.valueOf( Integer[] startMonthLengths = ADJUSTED_MONTH_LENGTHS.get(startYear);
startYear)); Integer[] endMonthLengths = ADJUSTED_MONTH_LENGTHS.get(endYear);
Integer[] endMonthLengths = ADJUSTED_MONTH_LENGTHS.get(Integer.valueOf( Integer[] startMonthDays = ADJUSTED_MONTH_DAYS.get(startYear);
endYear)); Integer[] endMonthDays = ADJUSTED_MONTH_DAYS.get(endYear);
Integer[] startMonthDays = ADJUSTED_MONTH_DAYS
.get(Integer.valueOf(startYear));
Integer[] endMonthDays = ADJUSTED_MONTH_DAYS.get(Integer.valueOf(endYear));
int startMonthLength = startMonthLengths[startMonth].intValue(); int startMonthLength = startMonthLengths[startMonth];
int endMonthLength = endMonthLengths[endMonth].intValue(); int endMonthLength = endMonthLengths[endMonth];
int startMonthDay = startMonthDays[11].intValue() int startMonthDay = startMonthDays[11] + startMonthLengths[11];
+ startMonthLengths[11].intValue(); int endMonthDay = endMonthDays[11] + endMonthLengths[11];
int endMonthDay = endMonthDays[11].intValue()
+ endMonthLengths[11].intValue();
int maxMonthLength = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH] int maxMonthLength = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH];
.intValue(); int leastMaxMonthLength = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH];
int leastMaxMonthLength = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH]
.intValue();
if (maxMonthLength < startMonthLength) { if (maxMonthLength < startMonthLength) {
maxMonthLength = startMonthLength; maxMonthLength = startMonthLength;
@ -1457,7 +1461,7 @@ public final class HijrahDate
if (maxMonthLength < endMonthLength) { if (maxMonthLength < endMonthLength) {
maxMonthLength = endMonthLength; maxMonthLength = endMonthLength;
} }
ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH] = Integer.valueOf(maxMonthLength); ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH] = maxMonthLength;
if (leastMaxMonthLength > startMonthLength) { if (leastMaxMonthLength > startMonthLength) {
leastMaxMonthLength = startMonthLength; leastMaxMonthLength = startMonthLength;
@ -1465,12 +1469,10 @@ public final class HijrahDate
if (leastMaxMonthLength > endMonthLength) { if (leastMaxMonthLength > endMonthLength) {
leastMaxMonthLength = endMonthLength; leastMaxMonthLength = endMonthLength;
} }
ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH] = Integer.valueOf( ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH] = leastMaxMonthLength;
leastMaxMonthLength);
int maxMonthDay = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR].intValue(); int maxMonthDay = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR];
int leastMaxMonthDay = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR] int leastMaxMonthDay = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR];
.intValue();
if (maxMonthDay < startMonthDay) { if (maxMonthDay < startMonthDay) {
maxMonthDay = startMonthDay; maxMonthDay = startMonthDay;
@ -1479,7 +1481,7 @@ public final class HijrahDate
maxMonthDay = endMonthDay; maxMonthDay = endMonthDay;
} }
ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR] = Integer.valueOf(maxMonthDay); ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR] = maxMonthDay;
if (leastMaxMonthDay > startMonthDay) { if (leastMaxMonthDay > startMonthDay) {
leastMaxMonthDay = startMonthDay; leastMaxMonthDay = startMonthDay;
@ -1487,8 +1489,7 @@ public final class HijrahDate
if (leastMaxMonthDay > endMonthDay) { if (leastMaxMonthDay > endMonthDay) {
leastMaxMonthDay = endMonthDay; leastMaxMonthDay = endMonthDay;
} }
ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR] = Integer.valueOf( ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR] = leastMaxMonthDay;
leastMaxMonthDay);
} }
/** /**
@ -1544,7 +1545,7 @@ public final class HijrahDate
int offsetIndex = deviationElement.indexOf(':'); int offsetIndex = deviationElement.indexOf(':');
if (offsetIndex != -1) { if (offsetIndex != -1) {
String offsetString = deviationElement.substring( String offsetString = deviationElement.substring(
offsetIndex + 1, deviationElement.length()); offsetIndex + 1);
int offset; int offset;
try { try {
offset = Integer.parseInt(offsetString); offset = Integer.parseInt(offsetString);
@ -1569,8 +1570,7 @@ public final class HijrahDate
String startYearStg = startDateStg.substring(0, String startYearStg = startDateStg.substring(0,
startDateYearSepIndex); startDateYearSepIndex);
String startMonthStg = startDateStg.substring( String startMonthStg = startDateStg.substring(
startDateYearSepIndex + 1, startDateStg startDateYearSepIndex + 1);
.length());
try { try {
startYear = Integer.parseInt(startYearStg); startYear = Integer.parseInt(startYearStg);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
@ -1594,7 +1594,7 @@ public final class HijrahDate
String endYearStg = endDateStg.substring(0, String endYearStg = endDateStg.substring(0,
endDateYearSepIndex); endDateYearSepIndex);
String endMonthStg = endDateStg.substring( String endMonthStg = endDateStg.substring(
endDateYearSepIndex + 1, endDateStg.length()); endDateYearSepIndex + 1);
try { try {
endYear = Integer.parseInt(endYearStg); endYear = Integer.parseInt(endYearStg);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,9 +47,7 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.ERA; import static org.threeten.bp.temporal.ChronoField.ERA;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
@ -156,9 +169,9 @@ public enum HijrahEra implements Era {
if (query == TemporalQueries.precision()) { if (query == TemporalQueries.precision()) {
return (R) ChronoUnit.ERAS; return (R) ChronoUnit.ERAS;
} }
if (query == TemporalQueries.chronology() || query == TemporalQueries.zone() || if (query == TemporalQueries.chronology() || query == TemporalQueries.zone()
query == TemporalQueries.zoneId() || query == TemporalQueries.offset() || || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()
query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) { || query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);
@ -177,7 +190,6 @@ public enum HijrahEra implements Era {
* @return the computed prolepticYear * @return the computed prolepticYear
*/ */
int prolepticYear(int yearOfEra) { int prolepticYear(int yearOfEra) {
return (this == HijrahEra.AH ? yearOfEra : 1 - yearOfEra); return this == HijrahEra.AH ? yearOfEra : 1 - yearOfEra;
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -45,14 +60,12 @@ import static org.threeten.bp.temporal.ChronoField.PROLEPTIC_MONTH;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA; import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -355,10 +368,10 @@ public final class IsoChronology extends Chronology implements Serializable {
@Override @Override
public int prolepticYear(Era era, int yearOfEra) { public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof IsoEra == false) { if (!(era instanceof IsoEra)) {
throw new ClassCastException("Era must be IsoEra"); throw new ClassCastException("Era must be IsoEra");
} }
return (era == IsoEra.CE ? yearOfEra : 1 - yearOfEra); return era == IsoEra.CE ? yearOfEra : 1 - yearOfEra;
} }
@Override @Override
@ -405,18 +418,19 @@ public final class IsoChronology extends Chronology implements Serializable {
if (resolverStyle == ResolverStyle.STRICT) { if (resolverStyle == ResolverStyle.STRICT) {
// do not invent era if strict, but do cross-check with year // do not invent era if strict, but do cross-check with year
if (year != null) { if (year != null) {
updateResolveMap(fieldValues, YEAR, (year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year > 0 ? yoeLong : Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
// reinstate the field removed earlier, no cross-check issues // reinstate the field removed earlier, no cross-check issues
fieldValues.put(YEAR_OF_ERA, yoeLong); fieldValues.put(YEAR_OF_ERA, yoeLong);
} }
} else { } else {
// invent era // invent era
updateResolveMap(fieldValues, YEAR, (year == null || year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR,
year == null || year > 0 ? yoeLong : Jdk8Methods.safeSubtract(1, yoeLong));
} }
} else if (era.longValue() == 1L) { } else if (era == 1L) {
updateResolveMap(fieldValues, YEAR, yoeLong); updateResolveMap(fieldValues, YEAR, yoeLong);
} else if (era.longValue() == 0L) { } else if (era == 0L) {
updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong)); updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
throw new DateTimeException("Invalid value for era: " + era); throw new DateTimeException("Invalid value for era: " + era);
@ -459,7 +473,8 @@ public final class IsoChronology extends Chronology implements Serializable {
} }
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)); LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month"); throw new DateTimeException("Strict mode rejected date parsed to a different month");
@ -503,7 +518,8 @@ public final class IsoChronology extends Chronology implements Serializable {
return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days); return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days);
} }
int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) {
throw new DateTimeException("Strict mode rejected date parsed to a different year"); throw new DateTimeException("Strict mode rejected date parsed to a different year");

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,9 +47,7 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.ERA; import static org.threeten.bp.temporal.ChronoField.ERA;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
@ -161,9 +174,9 @@ public enum IsoEra implements Era {
if (query == TemporalQueries.precision()) { if (query == TemporalQueries.precision()) {
return (R) ChronoUnit.ERAS; return (R) ChronoUnit.ERAS;
} }
if (query == TemporalQueries.chronology() || query == TemporalQueries.zone() || if (query == TemporalQueries.chronology() || query == TemporalQueries.zone()
query == TemporalQueries.zoneId() || query == TemporalQueries.offset() || || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()
query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) { || query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -48,7 +63,6 @@ import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
@ -57,7 +71,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -141,7 +154,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
ERA_SHORT_NAMES.put(TARGET_LANGUAGE, new String[]{"Unknown", "\u6176", "\u660e", "\u5927", "\u662d", "\u5e73"}); ERA_SHORT_NAMES.put(TARGET_LANGUAGE, new String[]{"Unknown", "\u6176", "\u660e", "\u5927", "\u662d", "\u5e73"});
ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Unknown", "Keio", "Meiji", "Taisho", "Showa", "Heisei"}); ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Unknown", "Keio", "Meiji", "Taisho", "Showa", "Heisei"});
ERA_FULL_NAMES.put(TARGET_LANGUAGE, ERA_FULL_NAMES.put(TARGET_LANGUAGE,
new String[]{"Unknown", "\u6176\u5fdc", "\u660e\u6cbb", "\u5927\u6b63", "\u662d\u548c", "\u5e73\u6210"}); new String[]{"Unknown", "\u6176\u5fdc", "\u660e\u6cbb", "\u5927\u6b63", "\u662d\u548c",
"\u5e73\u6210"});
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -195,7 +209,7 @@ public final class JapaneseChronology extends Chronology implements Serializable
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Override // override with covariant return type @Override // override with covariant return type
public JapaneseDate date(Era era, int yearOfEra, int month, int dayOfMonth) { public JapaneseDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
if (era instanceof JapaneseEra == false) { if (!(era instanceof JapaneseEra)) {
throw new ClassCastException("Era must be JapaneseEra"); throw new ClassCastException("Era must be JapaneseEra");
} }
return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth); return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth);
@ -230,7 +244,7 @@ public final class JapaneseChronology extends Chronology implements Serializable
*/ */
@Override @Override
public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
if (era instanceof JapaneseEra == false) { if (!(era instanceof JapaneseEra)) {
throw new ClassCastException("Era must be JapaneseEra"); throw new ClassCastException("Era must be JapaneseEra");
} }
return JapaneseDate.ofYearDay((JapaneseEra) era, yearOfEra, dayOfYear); return JapaneseDate.ofYearDay((JapaneseEra) era, yearOfEra, dayOfYear);
@ -322,7 +336,7 @@ public final class JapaneseChronology extends Chronology implements Serializable
@Override @Override
public int prolepticYear(Era era, int yearOfEra) { public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof JapaneseEra == false) { if (!(era instanceof JapaneseEra)) {
throw new ClassCastException("Era must be JapaneseEra"); throw new ClassCastException("Era must be JapaneseEra");
} }
JapaneseEra jera = (JapaneseEra) era; JapaneseEra jera = (JapaneseEra) era;
@ -399,7 +413,7 @@ public final class JapaneseChronology extends Chronology implements Serializable
} }
case MONTH_OF_YEAR: case MONTH_OF_YEAR:
return ValueRange.of(jcal.getMinimum(Calendar.MONTH) + 1, jcal.getGreatestMinimum(Calendar.MONTH) + 1, return ValueRange.of(jcal.getMinimum(Calendar.MONTH) + 1, jcal.getGreatestMinimum(Calendar.MONTH) + 1,
jcal.getLeastMaximum(Calendar.MONTH) + 1, jcal.getMaximum(Calendar.MONTH) + 1); jcal.getLeastMaximum(Calendar.MONTH) + 1, jcal.getMaximum(Calendar.MONTH) + 1);
case DAY_OF_YEAR: { case DAY_OF_YEAR: {
JapaneseEra[] eras = JapaneseEra.values(); JapaneseEra[] eras = JapaneseEra.values();
int min = 366; int min = 366;
@ -438,8 +452,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
} }
Long yoeLong = fieldValues.get(YEAR_OF_ERA); Long yoeLong = fieldValues.get(YEAR_OF_ERA);
if (yoeLong != null) { if (yoeLong != null) {
int yoe= range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); int yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA);
if (era == null && resolverStyle != ResolverStyle.STRICT && fieldValues.containsKey(YEAR) == false) { if (era == null && resolverStyle != ResolverStyle.STRICT && !fieldValues.containsKey(YEAR)) {
List<Era> eras = eras(); List<Era> eras = eras();
era = (JapaneseEra) eras.get(eras.size() - 1); era = (JapaneseEra) eras.get(eras.size() - 1);
} }
@ -466,8 +480,10 @@ public final class JapaneseChronology extends Chronology implements Serializable
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1); long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plusMonths(months).plusDays(days); return date(y, 1, 1).plusMonths(months).plusDays(days);
} else { } else {
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR),
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH),
DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART && dom > 28) { if (resolverStyle == ResolverStyle.SMART && dom > 28) {
dom = Math.min(dom, date(y, moy, 1).lengthOfMonth()); dom = Math.min(dom, date(y, moy, 1).lengthOfMonth());
} }
@ -485,7 +501,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
} }
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
JapaneseDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); JapaneseDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS);
if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month"); throw new DateTimeException("Strict mode rejected date parsed to a different month");
@ -529,7 +546,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS); return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS);
} }
int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
JapaneseDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); JapaneseDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) {
throw new DateTimeException("Strict mode rejected date parsed to a different year"); throw new DateTimeException("Strict mode rejected date parsed to a different year");
@ -556,7 +574,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
return null; return null;
} }
private JapaneseDate resolveEYMD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle, JapaneseEra era, int yoe) { private JapaneseDate resolveEYMD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle,
JapaneseEra era, int yoe) {
if (resolverStyle == ResolverStyle.LENIENT) { if (resolverStyle == ResolverStyle.LENIENT) {
int y = era.startDate().getYear() + yoe - 1; int y = era.startDate().getYear() + yoe - 1;
long months = Jdk8Methods.safeSubtract(fieldValues.remove(MONTH_OF_YEAR), 1); long months = Jdk8Methods.safeSubtract(fieldValues.remove(MONTH_OF_YEAR), 1);
@ -588,7 +607,8 @@ public final class JapaneseChronology extends Chronology implements Serializable
return date(era, yoe, moy, dom); return date(era, yoe, moy, dom);
} }
private JapaneseDate resolveEYD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle, JapaneseEra era, int yoe) { private JapaneseDate resolveEYD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle,
JapaneseEra era, int yoe) {
if (resolverStyle == ResolverStyle.LENIENT) { if (resolverStyle == ResolverStyle.LENIENT) {
int y = era.startDate().getYear() + yoe - 1; int y = era.startDate().getYear() + yoe - 1;
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_YEAR), 1); long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_YEAR), 1);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp.chrono;
import java.io.Serializable; import java.io.Serializable;
import java.util.Calendar; import java.util.Calendar;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -351,10 +365,10 @@ public final class JapaneseDate
*/ */
@Override @Override
public boolean isSupported(TemporalField field) { public boolean isSupported(TemporalField field) {
if (field == ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH || if (field == ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH
field == ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR || || field == ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR
field == ChronoField.ALIGNED_WEEK_OF_MONTH || || field == ChronoField.ALIGNED_WEEK_OF_MONTH
field == ChronoField.ALIGNED_WEEK_OF_YEAR) { || field == ChronoField.ALIGNED_WEEK_OF_YEAR) {
return false; return false;
} }
return super.isSupported(field); return super.isSupported(field);
@ -522,13 +536,13 @@ public final class JapaneseDate
} }
private JapaneseDate with(LocalDate newDate) { private JapaneseDate with(LocalDate newDate) {
return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate)); return newDate.equals(isoDate) ? this : new JapaneseDate(newDate);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) { public ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) {
return (ChronoLocalDateTime<JapaneseDate>)super.atTime(localTime); return (ChronoLocalDateTime<JapaneseDate>) super.atTime(localTime);
} }
@Override @Override

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp.chrono;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
import org.threeten.bp.temporal.ChronoField; import org.threeten.bp.temporal.ChronoField;
@ -93,7 +107,7 @@ public final class JapaneseEra
private static final int ADDITIONAL_VALUE = 4; private static final int ADDITIONAL_VALUE = 4;
// array for the singleton JapaneseEra instances // array for the singleton JapaneseEra instances
private static JapaneseEra[] KNOWN_ERAS; private static JapaneseEra[] knownEras;
static { static {
JapaneseEra[] array = new JapaneseEra[5]; JapaneseEra[] array = new JapaneseEra[5];
@ -102,7 +116,7 @@ public final class JapaneseEra
array[2] = SHOWA; array[2] = SHOWA;
array[3] = HEISEI; array[3] = HEISEI;
array[4] = REIWA; array[4] = REIWA;
KNOWN_ERAS = array; knownEras = array;
} }
/** /**
@ -146,7 +160,7 @@ public final class JapaneseEra
* @throws DateTimeException if an additional era has already been registered * @throws DateTimeException if an additional era has already been registered
*/ */
public static JapaneseEra registerEra(LocalDate since, String name) { public static JapaneseEra registerEra(LocalDate since, String name) {
JapaneseEra[] known = KNOWN_ERAS; JapaneseEra[] known = knownEras;
if (known.length > 5) { if (known.length > 5) {
throw new DateTimeException("Only one additional Japanese era can be added"); throw new DateTimeException("Only one additional Japanese era can be added");
} }
@ -158,7 +172,7 @@ public final class JapaneseEra
JapaneseEra era = new JapaneseEra(ADDITIONAL_VALUE, since, name); JapaneseEra era = new JapaneseEra(ADDITIONAL_VALUE, since, name);
JapaneseEra[] newArray = Arrays.copyOf(known, 6); JapaneseEra[] newArray = Arrays.copyOf(known, 6);
newArray[5] = era; newArray[5] = era;
KNOWN_ERAS = newArray; knownEras = newArray;
return era; return era;
} }
@ -174,7 +188,7 @@ public final class JapaneseEra
* @throws DateTimeException if the value is invalid * @throws DateTimeException if the value is invalid
*/ */
public static JapaneseEra of(int japaneseEra) { public static JapaneseEra of(int japaneseEra) {
JapaneseEra[] known = KNOWN_ERAS; JapaneseEra[] known = knownEras;
if (japaneseEra < MEIJI.eraValue || japaneseEra > known[known.length - 1].eraValue) { if (japaneseEra < MEIJI.eraValue || japaneseEra > known[known.length - 1].eraValue) {
throw new DateTimeException("japaneseEra is invalid"); throw new DateTimeException("japaneseEra is invalid");
} }
@ -193,7 +207,7 @@ public final class JapaneseEra
*/ */
public static JapaneseEra valueOf(String japaneseEra) { public static JapaneseEra valueOf(String japaneseEra) {
Objects.requireNonNull(japaneseEra, "japaneseEra"); Objects.requireNonNull(japaneseEra, "japaneseEra");
JapaneseEra[] known = KNOWN_ERAS; JapaneseEra[] known = knownEras;
for (JapaneseEra era : known) { for (JapaneseEra era : known) {
if (japaneseEra.equals(era.name)) { if (japaneseEra.equals(era.name)) {
return era; return era;
@ -214,7 +228,7 @@ public final class JapaneseEra
* @return an array of JapaneseEras * @return an array of JapaneseEras
*/ */
public static JapaneseEra[] values() { public static JapaneseEra[] values() {
JapaneseEra[] known = KNOWN_ERAS; JapaneseEra[] known = knownEras;
return Arrays.copyOf(known, known.length); return Arrays.copyOf(known, known.length);
} }
@ -229,7 +243,7 @@ public final class JapaneseEra
if (date.isBefore(MEIJI.since)) { if (date.isBefore(MEIJI.since)) {
throw new DateTimeException("Date too early: " + date); throw new DateTimeException("Date too early: " + date);
} }
JapaneseEra[] known = KNOWN_ERAS; JapaneseEra[] known = knownEras;
for (int i = known.length - 1; i >= 0; i--) { for (int i = known.length - 1; i >= 0; i--) {
JapaneseEra era = known[i]; JapaneseEra era = known[i];
if (date.compareTo(era.since) >= 0) { if (date.compareTo(era.since) >= 0) {

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -48,14 +63,12 @@ import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -242,10 +255,10 @@ public final class MinguoChronology extends Chronology implements Serializable {
@Override @Override
public int prolepticYear(Era era, int yearOfEra) { public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof MinguoEra == false) { if (!(era instanceof MinguoEra)) {
throw new ClassCastException("Era must be MinguoEra"); throw new ClassCastException("Era must be MinguoEra");
} }
return (era == MinguoEra.ROC ? yearOfEra : 1 - yearOfEra); return era == MinguoEra.ROC ? yearOfEra : 1 - yearOfEra;
} }
@Override @Override
@ -264,11 +277,13 @@ public final class MinguoChronology extends Chronology implements Serializable {
switch (field) { switch (field) {
case PROLEPTIC_MONTH: { case PROLEPTIC_MONTH: {
ValueRange range = PROLEPTIC_MONTH.range(); ValueRange range = PROLEPTIC_MONTH.range();
return ValueRange.of(range.getMinimum() - YEARS_DIFFERENCE * 12L, range.getMaximum() - YEARS_DIFFERENCE * 12L); return ValueRange.of(range.getMinimum() - YEARS_DIFFERENCE * 12L,
range.getMaximum() - YEARS_DIFFERENCE * 12L);
} }
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
return ValueRange.of(1, range.getMaximum() - YEARS_DIFFERENCE, -range.getMinimum() + 1 + YEARS_DIFFERENCE); return ValueRange.of(1, range.getMaximum() - YEARS_DIFFERENCE,
-range.getMinimum() + 1 + YEARS_DIFFERENCE);
} }
case YEAR: { case YEAR: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
@ -306,18 +321,20 @@ public final class MinguoChronology extends Chronology implements Serializable {
if (resolverStyle == ResolverStyle.STRICT) { if (resolverStyle == ResolverStyle.STRICT) {
// do not invent era if strict, but do cross-check with year // do not invent era if strict, but do cross-check with year
if (year != null) { if (year != null) {
updateResolveMap(fieldValues, YEAR, (year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year > 0 ? yoeLong : Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
// reinstate the field removed earlier, no cross-check issues // reinstate the field removed earlier, no cross-check issues
fieldValues.put(YEAR_OF_ERA, yoeLong); fieldValues.put(YEAR_OF_ERA, yoeLong);
} }
} else { } else {
// invent era // invent era
updateResolveMap(fieldValues, YEAR, (year == null || year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year == null || year > 0
? yoeLong
: Jdk8Methods.safeSubtract(1, yoeLong));
} }
} else if (era.longValue() == 1L) { } else if (era == 1L) {
updateResolveMap(fieldValues, YEAR, yoeLong); updateResolveMap(fieldValues, YEAR, yoeLong);
} else if (era.longValue() == 0L) { } else if (era == 0L) {
updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong)); updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
throw new DateTimeException("Invalid value for era: " + era); throw new DateTimeException("Invalid value for era: " + era);
@ -336,8 +353,10 @@ public final class MinguoChronology extends Chronology implements Serializable {
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1); long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plusMonths(months).plusDays(days); return date(y, 1, 1).plusMonths(months).plusDays(days);
} else { } else {
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR),
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH),
DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART && dom > 28) { if (resolverStyle == ResolverStyle.SMART && dom > 28) {
dom = Math.min(dom, date(y, moy, 1).lengthOfMonth()); dom = Math.min(dom, date(y, moy, 1).lengthOfMonth());
} }
@ -355,7 +374,8 @@ public final class MinguoChronology extends Chronology implements Serializable {
} }
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
MinguoDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); MinguoDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS);
if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month"); throw new DateTimeException("Strict mode rejected date parsed to a different month");
@ -399,7 +419,8 @@ public final class MinguoChronology extends Chronology implements Serializable {
return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS); return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS);
} }
int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
MinguoDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); MinguoDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) {
throw new DateTimeException("Strict mode rejected date parsed to a different year"); throw new DateTimeException("Strict mode rejected date parsed to a different year");

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,10 +48,8 @@ package org.threeten.bp.chrono;
import static org.threeten.bp.chrono.MinguoChronology.YEARS_DIFFERENCE; import static org.threeten.bp.chrono.MinguoChronology.YEARS_DIFFERENCE;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -162,7 +175,7 @@ public final class MinguoDate
/** /**
* Creates an instance from an ISO date. * Creates an instance from an ISO date.
* *
* @param isoDate the standard local date, validated not null * @param date the standard local date, validated not null
*/ */
MinguoDate(LocalDate date) { MinguoDate(LocalDate date) {
Objects.requireNonNull(date, "date"); Objects.requireNonNull(date, "date");
@ -197,7 +210,9 @@ public final class MinguoDate
return isoDate.range(field); return isoDate.range(field);
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
long max = (getProlepticYear() <= 0 ? -range.getMinimum() + 1 + YEARS_DIFFERENCE : range.getMaximum() - YEARS_DIFFERENCE); long max = getProlepticYear() <= 0
? -range.getMinimum() + 1 + YEARS_DIFFERENCE
: range.getMaximum() - YEARS_DIFFERENCE;
return ValueRange.of(1, max); return ValueRange.of(1, max);
} }
} }
@ -216,12 +231,12 @@ public final class MinguoDate
return getProlepticMonth(); return getProlepticMonth();
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
int prolepticYear = getProlepticYear(); int prolepticYear = getProlepticYear();
return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear); return prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear;
} }
case YEAR: case YEAR:
return getProlepticYear(); return getProlepticYear();
case ERA: case ERA:
return (getProlepticYear() >= 1 ? 1 : 0); return getProlepticYear() >= 1 ? 1 : 0;
} }
return isoDate.getLong(field); return isoDate.getLong(field);
} }
@ -259,7 +274,9 @@ public final class MinguoDate
int nvalue = getChronology().range(f).checkValidIntValue(newValue, f); int nvalue = getChronology().range(f).checkValidIntValue(newValue, f);
switch (f) { switch (f) {
case YEAR_OF_ERA: case YEAR_OF_ERA:
return with(isoDate.withYear(getProlepticYear() >= 1 ? nvalue + YEARS_DIFFERENCE : (1 - nvalue) + YEARS_DIFFERENCE)); return with(isoDate.withYear(getProlepticYear() >= 1
? nvalue + YEARS_DIFFERENCE
: (1 - nvalue) + YEARS_DIFFERENCE));
case YEAR: case YEAR:
return with(isoDate.withYear(nvalue + YEARS_DIFFERENCE)); return with(isoDate.withYear(nvalue + YEARS_DIFFERENCE));
case ERA: case ERA:
@ -309,12 +326,12 @@ public final class MinguoDate
} }
private MinguoDate with(LocalDate newDate) { private MinguoDate with(LocalDate newDate) {
return (newDate.equals(isoDate) ? this : new MinguoDate(newDate)); return newDate.equals(isoDate) ? this : new MinguoDate(newDate);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final ChronoLocalDateTime<MinguoDate> atTime(LocalTime localTime) { public ChronoLocalDateTime<MinguoDate> atTime(LocalTime localTime) {
return (ChronoLocalDateTime<MinguoDate>) super.atTime(localTime); return (ChronoLocalDateTime<MinguoDate>) super.atTime(localTime);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,9 +47,7 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.ERA; import static org.threeten.bp.temporal.ChronoField.ERA;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
@ -156,9 +169,9 @@ public enum MinguoEra implements Era {
if (query == TemporalQueries.precision()) { if (query == TemporalQueries.precision()) {
return (R) ChronoUnit.ERAS; return (R) ChronoUnit.ERAS;
} }
if (query == TemporalQueries.chronology() || query == TemporalQueries.zone() || if (query == TemporalQueries.chronology() || query == TemporalQueries.zone()
query == TemporalQueries.zoneId() || query == TemporalQueries.offset() || || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()
query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) { || query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -48,7 +63,6 @@ import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -56,7 +70,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
@ -136,11 +149,13 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, new String[]{"B.B.", "B.E."}); ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, new String[]{"B.B.", "B.E."});
ERA_SHORT_NAMES.put(TARGET_LANGUAGE, ERA_SHORT_NAMES.put(TARGET_LANGUAGE,
new String[]{"\u0e1e.\u0e28.", new String[]{"\u0e1e.\u0e28.",
"\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"}); "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32"
+ "\u0e25\u0e17\u0e35\u0e48"});
ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Before Buddhist", "Budhhist Era"}); ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Before Buddhist", "Budhhist Era"});
ERA_FULL_NAMES.put(TARGET_LANGUAGE, ERA_FULL_NAMES.put(TARGET_LANGUAGE,
new String[]{"\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a", new String[]{"\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a",
"\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"}); "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25"
+ "\u0e17\u0e35\u0e48"});
} }
/** /**
@ -278,10 +293,10 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
@Override @Override
public int prolepticYear(Era era, int yearOfEra) { public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof ThaiBuddhistEra == false) { if (!(era instanceof ThaiBuddhistEra)) {
throw new ClassCastException("Era must be BuddhistEra"); throw new ClassCastException("Era must be BuddhistEra");
} }
return (era == ThaiBuddhistEra.BE ? yearOfEra : 1 - yearOfEra); return era == ThaiBuddhistEra.BE ? yearOfEra : 1 - yearOfEra;
} }
@Override @Override
@ -300,11 +315,13 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
switch (field) { switch (field) {
case PROLEPTIC_MONTH: { case PROLEPTIC_MONTH: {
ValueRange range = PROLEPTIC_MONTH.range(); ValueRange range = PROLEPTIC_MONTH.range();
return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE * 12L, range.getMaximum() + YEARS_DIFFERENCE * 12L); return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE * 12L,
range.getMaximum() + YEARS_DIFFERENCE * 12L);
} }
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
return ValueRange.of(1, -(range.getMinimum() + YEARS_DIFFERENCE) + 1, range.getMaximum() + YEARS_DIFFERENCE); return ValueRange.of(1, -(range.getMinimum() + YEARS_DIFFERENCE) + 1,
range.getMaximum() + YEARS_DIFFERENCE);
} }
case YEAR: { case YEAR: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
@ -342,18 +359,22 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
if (resolverStyle == ResolverStyle.STRICT) { if (resolverStyle == ResolverStyle.STRICT) {
// do not invent era if strict, but do cross-check with year // do not invent era if strict, but do cross-check with year
if (year != null) { if (year != null) {
updateResolveMap(fieldValues, YEAR, (year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year > 0
? yoeLong
: Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
// reinstate the field removed earlier, no cross-check issues // reinstate the field removed earlier, no cross-check issues
fieldValues.put(YEAR_OF_ERA, yoeLong); fieldValues.put(YEAR_OF_ERA, yoeLong);
} }
} else { } else {
// invent era // invent era
updateResolveMap(fieldValues, YEAR, (year == null || year > 0 ? yoeLong: Jdk8Methods.safeSubtract(1, yoeLong))); updateResolveMap(fieldValues, YEAR, year == null || year > 0
? yoeLong
: Jdk8Methods.safeSubtract(1, yoeLong));
} }
} else if (era.longValue() == 1L) { } else if (era == 1L) {
updateResolveMap(fieldValues, YEAR, yoeLong); updateResolveMap(fieldValues, YEAR, yoeLong);
} else if (era.longValue() == 0L) { } else if (era == 0L) {
updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong)); updateResolveMap(fieldValues, YEAR, Jdk8Methods.safeSubtract(1, yoeLong));
} else { } else {
throw new DateTimeException("Invalid value for era: " + era); throw new DateTimeException("Invalid value for era: " + era);
@ -372,8 +393,10 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1); long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plusMonths(months).plusDays(days); return date(y, 1, 1).plusMonths(months).plusDays(days);
} else { } else {
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR),
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH),
DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART && dom > 28) { if (resolverStyle == ResolverStyle.SMART && dom > 28) {
dom = Math.min(dom, date(y, moy, 1).lengthOfMonth()); dom = Math.min(dom, date(y, moy, 1).lengthOfMonth());
} }
@ -391,7 +414,8 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
} }
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
ThaiBuddhistDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); ThaiBuddhistDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS);
if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month"); throw new DateTimeException("Strict mode rejected date parsed to a different month");
@ -435,7 +459,8 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ
return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS); return date(y, 1, 1).plus(weeks, WEEKS).plus(days, DAYS);
} }
int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(
fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
ThaiBuddhistDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); ThaiBuddhistDate date = date(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) {
throw new DateTimeException("Strict mode rejected date parsed to a different year"); throw new DateTimeException("Strict mode rejected date parsed to a different year");

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,13 +47,9 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.chrono.ThaiBuddhistChronology.YEARS_DIFFERENCE; import static org.threeten.bp.chrono.ThaiBuddhistChronology.YEARS_DIFFERENCE;
import static org.threeten.bp.temporal.ChronoField.DAY_OF_MONTH;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Clock; import org.threeten.bp.Clock;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -164,7 +175,7 @@ public final class ThaiBuddhistDate
/** /**
* Creates an instance from an ISO date. * Creates an instance from an ISO date.
* *
* @param isoDate the standard local date, validated not null * @param date the standard local date, validated not null
*/ */
ThaiBuddhistDate(LocalDate date) { ThaiBuddhistDate(LocalDate date) {
Objects.requireNonNull(date, "date"); Objects.requireNonNull(date, "date");
@ -199,7 +210,9 @@ public final class ThaiBuddhistDate
return isoDate.range(field); return isoDate.range(field);
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
ValueRange range = YEAR.range(); ValueRange range = YEAR.range();
long max = (getProlepticYear() <= 0 ? -(range.getMinimum() + YEARS_DIFFERENCE) + 1 : range.getMaximum() + YEARS_DIFFERENCE); long max = getProlepticYear() <= 0
? -(range.getMinimum() + YEARS_DIFFERENCE) + 1
: range.getMaximum() + YEARS_DIFFERENCE;
return ValueRange.of(1, max); return ValueRange.of(1, max);
} }
} }
@ -218,12 +231,12 @@ public final class ThaiBuddhistDate
return getProlepticMonth(); return getProlepticMonth();
case YEAR_OF_ERA: { case YEAR_OF_ERA: {
int prolepticYear = getProlepticYear(); int prolepticYear = getProlepticYear();
return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear); return prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear;
} }
case YEAR: case YEAR:
return getProlepticYear(); return getProlepticYear();
case ERA: case ERA:
return (getProlepticYear() >= 1 ? 1 : 0); return getProlepticYear() >= 1 ? 1 : 0;
} }
return isoDate.getLong(field); return isoDate.getLong(field);
} }
@ -261,7 +274,8 @@ public final class ThaiBuddhistDate
int nvalue = getChronology().range(f).checkValidIntValue(newValue, f); int nvalue = getChronology().range(f).checkValidIntValue(newValue, f);
switch (f) { switch (f) {
case YEAR_OF_ERA: case YEAR_OF_ERA:
return with(isoDate.withYear((getProlepticYear() >= 1 ? nvalue : 1 - nvalue) - YEARS_DIFFERENCE)); return with(isoDate.withYear((getProlepticYear() >= 1 ? nvalue : 1 - nvalue)
- YEARS_DIFFERENCE));
case YEAR: case YEAR:
return with(isoDate.withYear(nvalue - YEARS_DIFFERENCE)); return with(isoDate.withYear(nvalue - YEARS_DIFFERENCE));
case ERA: case ERA:
@ -311,12 +325,12 @@ public final class ThaiBuddhistDate
} }
private ThaiBuddhistDate with(LocalDate newDate) { private ThaiBuddhistDate with(LocalDate newDate) {
return (newDate.equals(isoDate) ? this : new ThaiBuddhistDate(newDate)); return newDate.equals(isoDate) ? this : new ThaiBuddhistDate(newDate);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final ChronoLocalDateTime<ThaiBuddhistDate> atTime(LocalTime localTime) { public ChronoLocalDateTime<ThaiBuddhistDate> atTime(LocalTime localTime) {
return (ChronoLocalDateTime<ThaiBuddhistDate>) super.atTime(localTime); return (ChronoLocalDateTime<ThaiBuddhistDate>) super.atTime(localTime);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,9 +47,7 @@
package org.threeten.bp.chrono; package org.threeten.bp.chrono;
import static org.threeten.bp.temporal.ChronoField.ERA; import static org.threeten.bp.temporal.ChronoField.ERA;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.format.DateTimeFormatterBuilder; import org.threeten.bp.format.DateTimeFormatterBuilder;
import org.threeten.bp.format.TextStyle; import org.threeten.bp.format.TextStyle;
@ -79,7 +92,6 @@ public enum ThaiBuddhistEra implements Era {
* *
* @param thaiBuddhistEra the era to represent, from 0 to 1 * @param thaiBuddhistEra the era to represent, from 0 to 1
* @return the BuddhistEra singleton, never null * @return the BuddhistEra singleton, never null
* @throws IllegalCalendarFieldValueException if the era is invalid
*/ */
public static ThaiBuddhistEra of(int thaiBuddhistEra) { public static ThaiBuddhistEra of(int thaiBuddhistEra) {
switch (thaiBuddhistEra) { switch (thaiBuddhistEra) {
@ -155,9 +167,9 @@ public enum ThaiBuddhistEra implements Era {
if (query == TemporalQueries.precision()) { if (query == TemporalQueries.precision()) {
return (R) ChronoUnit.ERAS; return (R) ChronoUnit.ERAS;
} }
if (query == TemporalQueries.chronology() || query == TemporalQueries.zone() || if (query == TemporalQueries.chronology() || query == TemporalQueries.zone()
query == TemporalQueries.zoneId() || query == TemporalQueries.offset() || || query == TemporalQueries.zoneId() || query == TemporalQueries.offset()
query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) { || query == TemporalQueries.localDate() || query == TemporalQueries.localTime()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -49,14 +64,12 @@ import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_DAY; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -165,8 +178,9 @@ public final class DateTimeBuilder
DateTimeBuilder addFieldValue(TemporalField field, long value) { DateTimeBuilder addFieldValue(TemporalField field, long value) {
Objects.requireNonNull(field, "field"); Objects.requireNonNull(field, "field");
Long old = getFieldValue0(field); // check first for better error message Long old = getFieldValue0(field); // check first for better error message
if (old != null && old.longValue() != value) { if (old != null && old != value) {
throw new DateTimeException("Conflict found: " + field + " " + old + " differs from " + field + " " + value + ": " + this); throw new DateTimeException("Conflict found: " + field + " " + old + " differs from " + field + " "
+ value + ": " + this);
} }
return putFieldValue0(field, value); return putFieldValue0(field, value);
} }
@ -211,7 +225,7 @@ public final class DateTimeBuilder
} }
resolveTimeInferZeroes(resolverStyle); resolveTimeInferZeroes(resolverStyle);
crossCheck(); crossCheck();
if (excessDays != null && excessDays.isZero() == false && date != null && time != null) { if (excessDays != null && !excessDays.isZero() && date != null && time != null) {
date = date.plus(excessDays); date = date.plus(excessDays);
excessDays = Period.ZERO; excessDays = Period.ZERO;
} }
@ -232,8 +246,9 @@ public final class DateTimeBuilder
ChronoZonedDateTime<?> czdt = (ChronoZonedDateTime<?>) resolvedObject; ChronoZonedDateTime<?> czdt = (ChronoZonedDateTime<?>) resolvedObject;
if (zone == null) { if (zone == null) {
zone = czdt.getZone(); zone = czdt.getZone();
} else if (zone.equals(czdt.getZone()) == false) { } else if (!zone.equals(czdt.getZone())) {
throw new DateTimeException("ChronoZonedDateTime must use the effective parsed zone: " + zone); throw new DateTimeException("ChronoZonedDateTime must use the effective parsed zone: "
+ zone);
} }
resolvedObject = czdt.toLocalDateTime(); resolvedObject = czdt.toLocalDateTime();
} }
@ -255,7 +270,7 @@ public final class DateTimeBuilder
continue outer; // have to restart to avoid concurrent modification continue outer; // have to restart to avoid concurrent modification
} }
throw new DateTimeException("Unknown type: " + resolvedObject.getClass().getName()); throw new DateTimeException("Unknown type: " + resolvedObject.getClass().getName());
} else if (fieldValues.containsKey(targetField) == false) { } else if (!fieldValues.containsKey(targetField)) {
changes++; changes++;
continue outer; // have to restart to avoid concurrent modification continue outer; // have to restart to avoid concurrent modification
} }
@ -269,25 +284,25 @@ public final class DateTimeBuilder
} }
private void resolveMakeChanges(TemporalField targetField, ChronoLocalDate date) { private void resolveMakeChanges(TemporalField targetField, ChronoLocalDate date) {
if (chrono.equals(date.getChronology()) == false) { if (!chrono.equals(date.getChronology())) {
throw new DateTimeException("ChronoLocalDate must use the effective parsed chronology: " + chrono); throw new DateTimeException("ChronoLocalDate must use the effective parsed chronology: " + chrono);
} }
long epochDay = date.toEpochDay(); long epochDay = date.toEpochDay();
Long old = fieldValues.put(ChronoField.EPOCH_DAY, epochDay); Long old = fieldValues.put(ChronoField.EPOCH_DAY, epochDay);
if (old != null && old.longValue() != epochDay) { if (old != null && old != epochDay) {
throw new DateTimeException("Conflict found: " + LocalDate.ofEpochDay(old) + throw new DateTimeException("Conflict found: " + LocalDate.ofEpochDay(old)
" differs from " + LocalDate.ofEpochDay(epochDay) + + " differs from " + LocalDate.ofEpochDay(epochDay)
" while resolving " + targetField); + " while resolving " + targetField);
} }
} }
private void resolveMakeChanges(TemporalField targetField, LocalTime time) { private void resolveMakeChanges(TemporalField targetField, LocalTime time) {
long nanOfDay = time.toNanoOfDay(); long nanOfDay = time.toNanoOfDay();
Long old = fieldValues.put(ChronoField.NANO_OF_DAY, nanOfDay); Long old = fieldValues.put(ChronoField.NANO_OF_DAY, nanOfDay);
if (old != null && old.longValue() != nanOfDay) { if (old != null && old != nanOfDay) {
throw new DateTimeException("Conflict found: " + LocalTime.ofNanoOfDay(old) + throw new DateTimeException("Conflict found: " + LocalTime.ofNanoOfDay(old)
" differs from " + time + + " differs from " + time
" while resolving " + targetField); + " while resolving " + targetField);
} }
} }
@ -297,7 +312,6 @@ public final class DateTimeBuilder
} else { } else {
if (fieldValues.containsKey(EPOCH_DAY)) { if (fieldValues.containsKey(EPOCH_DAY)) {
checkDate(LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY))); checkDate(LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY)));
return;
} }
} }
} }
@ -316,7 +330,8 @@ public final class DateTimeBuilder
} }
Long val2 = fieldValues.get(field); Long val2 = fieldValues.get(field);
if (val1 != val2) { if (val1 != val2) {
throw new DateTimeException("Conflict found: Field " + field + " " + val1 + " differs from " + field + " " + val2 + " derived from " + date); throw new DateTimeException("Conflict found: Field " + field + " " + val1
+ " differs from " + field + " " + val2 + " derived from " + date);
} }
} }
} }
@ -465,11 +480,11 @@ public final class DateTimeBuilder
} }
if (resolverStyle != ResolverStyle.LENIENT) { if (resolverStyle != ResolverStyle.LENIENT) {
if (hod != null) { if (hod != null) {
if (resolverStyle == ResolverStyle.SMART && if (resolverStyle == ResolverStyle.SMART
hod.longValue() == 24 && && hod == 24
(moh == null || moh.longValue() == 0) && && (moh == null || moh == 0)
(som == null || som.longValue() == 0) && && (som == null || som == 0)
(nos == null || nos.longValue() == 0)) { && (nos == null || nos == 0)) {
hod = 0L; hod = 0L;
excessDays = Period.ofDays(1); excessDays = Period.ofDays(1);
} }
@ -556,7 +571,7 @@ public final class DateTimeBuilder
} else { } else {
resolveMakeChanges(INSTANT_SECONDS, zdt.toLocalDate()); resolveMakeChanges(INSTANT_SECONDS, zdt.toLocalDate());
} }
addFieldValue(SECOND_OF_DAY, (long) zdt.toLocalTime().toSecondOfDay()); addFieldValue(SECOND_OF_DAY, zdt.toLocalTime().toSecondOfDay());
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -586,8 +601,8 @@ public final class DateTimeBuilder
continue; continue;
} }
if (temporalValue != value) { if (temporalValue != value) {
throw new DateTimeException("Cross check failed: " + throw new DateTimeException("Cross check failed: "
field + " " + temporalValue + " vs " + field + " " + value); + field + " " + temporalValue + " vs " + field + " " + value);
} }
it.remove(); it.remove();
} }
@ -595,10 +610,10 @@ public final class DateTimeBuilder
} }
private void resolveFractional() { private void resolveFractional() {
if (time == null && if (time == null
(fieldValues.containsKey(INSTANT_SECONDS) || && (fieldValues.containsKey(INSTANT_SECONDS)
fieldValues.containsKey(SECOND_OF_DAY) || || fieldValues.containsKey(SECOND_OF_DAY)
fieldValues.containsKey(SECOND_OF_MINUTE))) { || fieldValues.containsKey(SECOND_OF_MINUTE))) {
if (fieldValues.containsKey(NANO_OF_SECOND)) { if (fieldValues.containsKey(NANO_OF_SECOND)) {
long nos = fieldValues.get(NANO_OF_SECOND); long nos = fieldValues.get(NANO_OF_SECOND);
fieldValues.put(MICRO_OF_SECOND, nos / 1000); fieldValues.put(MICRO_OF_SECOND, nos / 1000);
@ -647,9 +662,9 @@ public final class DateTimeBuilder
if (field == null) { if (field == null) {
return false; return false;
} }
return fieldValues.containsKey(field) || return fieldValues.containsKey(field)
(date != null && date.isSupported(field)) || || (date != null && date.isSupported(field))
(time != null && time.isSupported(field)); || (time != null && time.isSupported(field));
} }
@Override @Override

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,7 +47,6 @@
package org.threeten.bp.format; package org.threeten.bp.format;
import java.util.Locale; import java.util.Locale;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
/** /**

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -40,7 +55,6 @@ import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND; import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import java.io.IOException; import java.io.IOException;
import java.text.FieldPosition; import java.text.FieldPosition;
import java.text.Format; import java.text.Format;
@ -54,7 +68,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Period; import org.threeten.bp.Period;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
@ -1533,7 +1546,8 @@ public final class DateTimeFormatter {
// continue // continue
} }
} }
throw new DateTimeException("Unable to convert parsed text to any specified type: " + Arrays.toString(types)); throw new DateTimeException("Unable to convert parsed text to any specified type: "
+ Arrays.toString(types));
} catch (DateTimeParseException ex) { } catch (DateTimeParseException ex) {
throw ex; throw ex;
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
@ -1566,7 +1580,7 @@ public final class DateTimeFormatter {
* @throws DateTimeParseException if the parse fails * @throws DateTimeParseException if the parse fails
*/ */
private DateTimeBuilder parseToBuilder(final CharSequence text, final ParsePosition position) { private DateTimeBuilder parseToBuilder(final CharSequence text, final ParsePosition position) {
ParsePosition pos = (position != null ? position : new ParsePosition(0)); ParsePosition pos = position != null ? position : new ParsePosition(0);
Parsed result = parseUnresolved0(text, pos); Parsed result = parseUnresolved0(text, pos);
if (result == null || pos.getErrorIndex() >= 0 || (position == null && pos.getIndex() < text.length())) { if (result == null || pos.getErrorIndex() >= 0 || (position == null && pos.getIndex() < text.length())) {
String abbr = ""; String abbr = "";
@ -1576,11 +1590,12 @@ public final class DateTimeFormatter {
abbr = text.toString(); abbr = text.toString();
} }
if (pos.getErrorIndex() >= 0) { if (pos.getErrorIndex() >= 0) {
throw new DateTimeParseException("Text '" + abbr + "' could not be parsed at index " + throw new DateTimeParseException("Text '" + abbr + "' could not be parsed at index "
pos.getErrorIndex(), text, pos.getErrorIndex()); + pos.getErrorIndex(), text, pos.getErrorIndex());
} else { } else {
throw new DateTimeParseException("Text '" + abbr + "' could not be parsed, unparsed text found at index " + throw new DateTimeParseException("Text '" + abbr
pos.getIndex(), text, pos.getIndex()); + "' could not be parsed, unparsed text found at index "
+ pos.getIndex(), text, pos.getIndex());
} }
} }
return result.toBuilder(); return result.toBuilder();
@ -1744,7 +1759,7 @@ public final class DateTimeFormatter {
try { try {
if (query == null) { if (query == null) {
return formatter.parseToBuilder(text, null) return formatter.parseToBuilder(text, null)
.resolve(formatter.getResolverStyle(), formatter.getResolverFields()); .resolve(formatter.getResolverStyle(), formatter.getResolverFields());
} }
return formatter.parse(text, query); return formatter.parse(text, query);
} catch (DateTimeParseException ex) { } catch (DateTimeParseException ex) {
@ -1773,7 +1788,7 @@ public final class DateTimeFormatter {
} }
try { try {
DateTimeBuilder builder = unresolved.toBuilder() DateTimeBuilder builder = unresolved.toBuilder()
.resolve(formatter.getResolverStyle(), formatter.getResolverFields()); .resolve(formatter.getResolverStyle(), formatter.getResolverFields());
if (query == null) { if (query == null) {
return builder; return builder;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -40,7 +55,6 @@ import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE; import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -63,7 +77,6 @@ import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.TreeMap; import java.util.TreeMap;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -117,11 +130,9 @@ public final class DateTimeFormatterBuilder {
/** /**
* Query for a time-zone that is region-only. * Query for a time-zone that is region-only.
*/ */
private static final TemporalQuery<ZoneId> QUERY_REGION_ONLY = new TemporalQuery<ZoneId>() { private static final TemporalQuery<ZoneId> QUERY_REGION_ONLY = temporal -> {
public ZoneId queryFrom(TemporalAccessor temporal) { ZoneId zone = temporal.query(TemporalQueries.zoneId());
ZoneId zone = temporal.query(TemporalQueries.zoneId()); return zone != null && !(zone instanceof ZoneOffset) ? zone : null;
return (zone != null && zone instanceof ZoneOffset == false ? zone : null);
}
}; };
/** /**
@ -135,7 +146,7 @@ public final class DateTimeFormatterBuilder {
/** /**
* The list of printers that will be used. * The list of printers that will be used.
*/ */
private final List<DateTimePrinterParser> printerParsers = new ArrayList<DateTimeFormatterBuilder.DateTimePrinterParser>(); private final List<DateTimePrinterParser> printerParsers = new ArrayList<>();
/** /**
* Whether this builder produces an optional formatter. * Whether this builder produces an optional formatter.
*/ */
@ -452,8 +463,8 @@ public final class DateTimeFormatterBuilder {
throw new IllegalArgumentException("The maximum width must be from 1 to 19 inclusive but was " + maxWidth); throw new IllegalArgumentException("The maximum width must be from 1 to 19 inclusive but was " + maxWidth);
} }
if (maxWidth < minWidth) { if (maxWidth < minWidth) {
throw new IllegalArgumentException("The maximum width must exceed or equal the minimum width but " + throw new IllegalArgumentException("The maximum width must exceed or equal the minimum width but "
maxWidth + " < " + minWidth); + maxWidth + " < " + minWidth);
} }
NumberPrinterParser pp = new NumberPrinterParser(field, minWidth, maxWidth, signStyle); NumberPrinterParser pp = new NumberPrinterParser(field, minWidth, maxWidth, signStyle);
appendValue(pp); appendValue(pp);
@ -571,13 +582,12 @@ public final class DateTimeFormatterBuilder {
/** /**
* Appends a fixed width printer-parser. * Appends a fixed width printer-parser.
* *
* @param width the width
* @param pp the printer-parser, not null * @param pp the printer-parser, not null
* @return this, for chaining, not null * @return this, for chaining, not null
*/ */
private DateTimeFormatterBuilder appendValue(NumberPrinterParser pp) { private DateTimeFormatterBuilder appendValue(NumberPrinterParser pp) {
if (active.valueParserIndex >= 0 && if (active.valueParserIndex >= 0
active.printerParsers.get(active.valueParserIndex) instanceof NumberPrinterParser) { && active.printerParsers.get(active.valueParserIndex) instanceof NumberPrinterParser) {
final int activeValueParser = active.valueParserIndex; final int activeValueParser = active.valueParserIndex;
// adjacent parsing mode, update setting in previous parsers // adjacent parsing mode, update setting in previous parsers
@ -1057,8 +1067,7 @@ public final class DateTimeFormatterBuilder {
* @param preferredZones the set of preferred zone ids, not null * @param preferredZones the set of preferred zone ids, not null
* @return this, for chaining, not null * @return this, for chaining, not null
*/ */
public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle, public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle, Set<ZoneId> preferredZones) {
Set<ZoneId> preferredZones) {
// TODO: preferred zones currently ignored // TODO: preferred zones currently ignored
Objects.requireNonNull(preferredZones, "preferredZones"); Objects.requireNonNull(preferredZones, "preferredZones");
appendInternal(new ZoneTextPrinterParser(textStyle)); appendInternal(new ZoneTextPrinterParser(textStyle));
@ -1389,7 +1398,9 @@ public final class DateTimeFormatterBuilder {
char cur = pattern.charAt(pos); char cur = pattern.charAt(pos);
if ((cur >= 'A' && cur <= 'Z') || (cur >= 'a' && cur <= 'z')) { if ((cur >= 'A' && cur <= 'Z') || (cur >= 'a' && cur <= 'z')) {
int start = pos++; int start = pos++;
for ( ; pos < pattern.length() && pattern.charAt(pos) == cur; pos++); // short loop while (pos < pattern.length() && pattern.charAt(pos) == cur) {
pos++;
}
int count = pos - start; int count = pos - start;
// padding // padding
if (cur == 'p') { if (cur == 'p') {
@ -1399,7 +1410,9 @@ public final class DateTimeFormatterBuilder {
if ((cur >= 'A' && cur <= 'Z') || (cur >= 'a' && cur <= 'z')) { if ((cur >= 'A' && cur <= 'Z') || (cur >= 'a' && cur <= 'z')) {
pad = count; pad = count;
start = pos++; start = pos++;
for ( ; pos < pattern.length() && pattern.charAt(pos) == cur; pos++); // short loop while (pos < pattern.length() && pattern.charAt(pos) == cur) {
pos++;
}
count = pos - start; count = pos - start;
} }
} }
@ -1432,7 +1445,7 @@ public final class DateTimeFormatterBuilder {
} else if (count == 4) { } else if (count == 4) {
appendLocalizedOffset(TextStyle.FULL); appendLocalizedOffset(TextStyle.FULL);
} else if (count == 5) { } else if (count == 5) {
appendOffset("+HH:MM:ss","Z"); appendOffset("+HH:MM:ss", "Z");
} else { } else {
throw new IllegalArgumentException("Too many pattern letters: " + cur); throw new IllegalArgumentException("Too many pattern letters: " + cur);
} }
@ -1453,7 +1466,7 @@ public final class DateTimeFormatterBuilder {
if (count > 5) { if (count > 5) {
throw new IllegalArgumentException("Too many pattern letters: " + cur); throw new IllegalArgumentException("Too many pattern letters: " + cur);
} }
String zero = (count == 1 ? "+00" : (count % 2 == 0 ? "+0000" : "+00:00")); String zero = count == 1 ? "+00" : (count % 2 == 0 ? "+0000" : "+00:00");
appendOffset(OffsetIdPrinterParser.PATTERNS[count + (count == 1 ? 0 : 1)], zero); appendOffset(OffsetIdPrinterParser.PATTERNS[count + (count == 1 ? 0 : 1)], zero);
} else if (cur == 'W') { } else if (cur == 'W') {
if (count > 1) { if (count > 1) {
@ -1475,7 +1488,7 @@ public final class DateTimeFormatterBuilder {
} else if (cur == '\'') { } else if (cur == '\'') {
// parse literals // parse literals
int start = pos++; int start = pos++;
for ( ; pos < pattern.length(); pos++) { for (; pos < pattern.length(); pos++) {
if (pattern.charAt(pos) == '\'') { if (pattern.charAt(pos) == '\'') {
if (pos + 1 < pattern.length() && pattern.charAt(pos + 1) == '\'') { if (pos + 1 < pattern.length() && pattern.charAt(pos + 1) == '\'') {
pos++; pos++;
@ -1813,7 +1826,8 @@ public final class DateTimeFormatterBuilder {
*/ */
public DateTimeFormatterBuilder optionalEnd() { public DateTimeFormatterBuilder optionalEnd() {
if (active.parent == null) { if (active.parent == null) {
throw new IllegalStateException("Cannot call optionalEnd() as there was no previous call to optionalStart()"); throw new IllegalStateException("Cannot call optionalEnd() as there was no previous call "
+ "to optionalStart()");
} }
if (active.printerParsers.size() > 0) { if (active.printerParsers.size() > 0) {
CompositePrinterParser cpp = new CompositePrinterParser(active.printerParsers, active.optional); CompositePrinterParser cpp = new CompositePrinterParser(active.printerParsers, active.optional);
@ -1993,7 +2007,7 @@ public final class DateTimeFormatterBuilder {
} }
try { try {
for (DateTimePrinterParser pp : printerParsers) { for (DateTimePrinterParser pp : printerParsers) {
if (pp.print(context, buf) == false) { if (!pp.print(context, buf)) {
buf.setLength(length); // reset buffer buf.setLength(length); // reset buffer
return true; return true;
} }
@ -2071,7 +2085,7 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public boolean print(DateTimePrintContext context, StringBuilder buf) { public boolean print(DateTimePrintContext context, StringBuilder buf) {
int preLen = buf.length(); int preLen = buf.length();
if (printerParser.print(context, buf) == false) { if (!printerParser.print(context, buf)) {
return false; return false;
} }
int len = buf.length() - preLen; int len = buf.length() - preLen;
@ -2105,8 +2119,8 @@ public final class DateTimeFormatterBuilder {
endPos = text.length(); endPos = text.length();
} }
int pos = position; int pos = position;
while (pos < endPos && while (pos < endPos
(caseSensitive ? text.charAt(pos) == padChar : context.charEquals(text.charAt(pos), padChar))) { && (caseSensitive ? text.charAt(pos) == padChar : context.charEquals(text.charAt(pos), padChar))) {
pos++; pos++;
} }
text = text.subSequence(0, endPos); text = text.subSequence(0, endPos);
@ -2127,7 +2141,7 @@ public final class DateTimeFormatterBuilder {
/** /**
* Enumeration to apply simple parse settings. * Enumeration to apply simple parse settings.
*/ */
static enum SettingsParser implements DateTimePrinterParser { enum SettingsParser implements DateTimePrinterParser {
SENSITIVE, SENSITIVE,
INSENSITIVE, INSENSITIVE,
STRICT, STRICT,
@ -2176,10 +2190,12 @@ public final class DateTimeFormatterBuilder {
this.value = value; this.value = value;
} }
@Override
public boolean print(DateTimePrintContext context, StringBuilder buf) { public boolean print(DateTimePrintContext context, StringBuilder buf) {
return true; return true;
} }
@Override
public int parse(DateTimeParseContext context, CharSequence text, int position) { public int parse(DateTimeParseContext context, CharSequence text, int position) {
if (context.getParsed(field) == null) { if (context.getParsed(field) == null) {
context.setParsedField(field, value, position, position); context.setParsedField(field, value, position, position);
@ -2212,7 +2228,7 @@ public final class DateTimeFormatterBuilder {
return ~position; return ~position;
} }
char ch = text.charAt(position); char ch = text.charAt(position);
if (context.charEquals(literal, ch) == false) { if (!context.charEquals(literal, ch)) {
return ~position; return ~position;
} }
return position + 1; return position + 1;
@ -2250,7 +2266,7 @@ public final class DateTimeFormatterBuilder {
if (position > length || position < 0) { if (position > length || position < 0) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
if (context.subSequenceEquals(text, position, literal, 0, literal.length()) == false) { if (!context.subSequenceEquals(text, position, literal, 0, literal.length())) {
return ~position; return ~position;
} }
return position + literal.length(); return position + literal.length();
@ -2318,7 +2334,8 @@ public final class DateTimeFormatterBuilder {
* @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater, * @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater,
* -1 if fixed width due to active adjacent parsing * -1 if fixed width due to active adjacent parsing
*/ */
private NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth) { private NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle,
int subsequentWidth) {
// validated by caller // validated by caller
this.field = field; this.field = field;
this.minWidth = minWidth; this.minWidth = minWidth;
@ -2346,7 +2363,8 @@ public final class DateTimeFormatterBuilder {
* @return a new updated printer-parser, not null * @return a new updated printer-parser, not null
*/ */
NumberPrinterParser withSubsequentWidth(int subsequentWidth) { NumberPrinterParser withSubsequentWidth(int subsequentWidth) {
return new NumberPrinterParser(field, minWidth, maxWidth, signStyle, this.subsequentWidth + subsequentWidth); return new NumberPrinterParser(field, minWidth, maxWidth, signStyle,
this.subsequentWidth + subsequentWidth);
} }
@Override @Override
@ -2357,11 +2375,11 @@ public final class DateTimeFormatterBuilder {
} }
long value = getValue(context, valueLong); long value = getValue(context, valueLong);
DecimalStyle symbols = context.getSymbols(); DecimalStyle symbols = context.getSymbols();
String str = (value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value))); String str = value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value));
if (str.length() > maxWidth) { if (str.length() > maxWidth) {
throw new DateTimeException("Field " + field + throw new DateTimeException("Field " + field
" cannot be printed as the value " + value + + " cannot be printed as the value " + value
" exceeds the maximum print width of " + maxWidth); + " exceeds the maximum print width of " + maxWidth);
} }
str = symbols.convertNumberToI18N(str); str = symbols.convertNumberToI18N(str);
@ -2384,9 +2402,9 @@ public final class DateTimeFormatterBuilder {
buf.append(symbols.getNegativeSign()); buf.append(symbols.getNegativeSign());
break; break;
case NOT_NEGATIVE: case NOT_NEGATIVE:
throw new DateTimeException("Field " + field + throw new DateTimeException("Field " + field
" cannot be printed as the value " + value + + " cannot be printed as the value " + value
" cannot be negative according to the SignStyle"); + " cannot be negative according to the SignStyle");
} }
} }
for (int i = 0; i < minWidth - str.length(); i++) { for (int i = 0; i < minWidth - str.length(); i++) {
@ -2408,8 +2426,8 @@ public final class DateTimeFormatterBuilder {
} }
boolean isFixedWidth(DateTimeParseContext context) { boolean isFixedWidth(DateTimeParseContext context) {
return subsequentWidth == -1 || return subsequentWidth == -1
(subsequentWidth > 0 && minWidth == maxWidth && signStyle == SignStyle.NOT_NEGATIVE); || (subsequentWidth > 0 && minWidth == maxWidth && signStyle == SignStyle.NOT_NEGATIVE);
} }
@Override @Override
@ -2422,13 +2440,13 @@ public final class DateTimeFormatterBuilder {
boolean negative = false; boolean negative = false;
boolean positive = false; boolean positive = false;
if (sign == context.getSymbols().getPositiveSign()) { if (sign == context.getSymbols().getPositiveSign()) {
if (signStyle.parse(true, context.isStrict(), minWidth == maxWidth) == false) { if (!signStyle.parse(true, context.isStrict(), minWidth == maxWidth)) {
return ~position; return ~position;
} }
positive = true; positive = true;
position++; position++;
} else if (sign == context.getSymbols().getNegativeSign()) { } else if (sign == context.getSymbols().getNegativeSign()) {
if (signStyle.parse(false, context.isStrict(), minWidth == maxWidth) == false) { if (!signStyle.parse(false, context.isStrict(), minWidth == maxWidth)) {
return ~position; return ~position;
} }
negative = true; negative = true;
@ -2438,12 +2456,13 @@ public final class DateTimeFormatterBuilder {
return ~position; return ~position;
} }
} }
int effMinWidth = (context.isStrict() || isFixedWidth(context) ? minWidth : 1); int effMinWidth = context.isStrict() || isFixedWidth(context) ? minWidth : 1;
int minEndPos = position + effMinWidth; int minEndPos = position + effMinWidth;
if (minEndPos > length) { if (minEndPos > length) {
return ~position; return ~position;
} }
int effMaxWidth = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9) + Math.max(subsequentWidth, 0); int effMaxWidth = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9)
+ Math.max(subsequentWidth, 0);
long total = 0; long total = 0;
BigInteger totalBig = null; BigInteger totalBig = null;
int pos = position; int pos = position;
@ -2569,11 +2588,12 @@ public final class DateTimeFormatterBuilder {
throw new IllegalArgumentException("The maxWidth must be greater than the width"); throw new IllegalArgumentException("The maxWidth must be greater than the width");
} }
if (baseDate == null) { if (baseDate == null) {
if (field.range().isValidValue(baseValue) == false) { if (!field.range().isValidValue(baseValue)) {
throw new IllegalArgumentException("The base value must be within the range of the field"); throw new IllegalArgumentException("The base value must be within the range of the field");
} }
if ((((long) baseValue) + EXCEED_POINTS[width]) > Integer.MAX_VALUE) { if ((((long) baseValue) + EXCEED_POINTS[width]) > Integer.MAX_VALUE) {
throw new DateTimeException("Unable to add printer-parser as the range exceeds the capacity of an int"); throw new DateTimeException("Unable to add printer-parser as the range exceeds "
+ "the capacity of an int");
} }
} }
this.baseValue = baseValue; this.baseValue = baseValue;
@ -2642,7 +2662,7 @@ public final class DateTimeFormatterBuilder {
@Override @Override
boolean isFixedWidth(DateTimeParseContext context) { boolean isFixedWidth(DateTimeParseContext context) {
if (context.isStrict() == false) { if (!context.isStrict()) {
return false; return false;
} }
return super.isFixedWidth(context); return super.isFixedWidth(context);
@ -2650,7 +2670,8 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public String toString() { public String toString() {
return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + "," + (baseDate != null ? baseDate : baseValue) + ")"; return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + ","
+ (baseDate != null ? baseDate : baseValue) + ")";
} }
} }
@ -2674,7 +2695,7 @@ public final class DateTimeFormatterBuilder {
*/ */
FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
Objects.requireNonNull(field, "field"); Objects.requireNonNull(field, "field");
if (field.range().isFixed() == false) { if (!field.range().isFixed()) {
throw new IllegalArgumentException("Field must have a fixed set of values: " + field); throw new IllegalArgumentException("Field must have a fixed set of values: " + field);
} }
if (minWidth < 0 || minWidth > 9) { if (minWidth < 0 || minWidth > 9) {
@ -2684,8 +2705,8 @@ public final class DateTimeFormatterBuilder {
throw new IllegalArgumentException("Maximum width must be from 1 to 9 inclusive but was " + maxWidth); throw new IllegalArgumentException("Maximum width must be from 1 to 9 inclusive but was " + maxWidth);
} }
if (maxWidth < minWidth) { if (maxWidth < minWidth) {
throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " + throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but "
maxWidth + " < " + minWidth); + maxWidth + " < " + minWidth);
} }
this.field = field; this.field = field;
this.minWidth = minWidth; this.minWidth = minWidth;
@ -2725,17 +2746,17 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public int parse(DateTimeParseContext context, CharSequence text, int position) { public int parse(DateTimeParseContext context, CharSequence text, int position) {
int effectiveMin = (context.isStrict() ? minWidth : 0); int effectiveMin = context.isStrict() ? minWidth : 0;
int effectiveMax = (context.isStrict() ? maxWidth : 9); int effectiveMax = context.isStrict() ? maxWidth : 9;
int length = text.length(); int length = text.length();
if (position == length) { if (position == length) {
// valid if whole field is optional, invalid if minimum width // valid if whole field is optional, invalid if minimum width
return (effectiveMin > 0 ? ~position : position); return effectiveMin > 0 ? ~position : position;
} }
if (decimalPoint) { if (decimalPoint) {
if (text.charAt(position) != context.getSymbols().getDecimalSeparator()) { if (text.charAt(position) != context.getSymbols().getDecimalSeparator()) {
// valid if whole field is optional, invalid if minimum width // valid if whole field is optional, invalid if minimum width
return (effectiveMin > 0 ? ~position : position); return effectiveMin > 0 ? ~position : position;
} }
position++; position++;
} }
@ -2816,7 +2837,7 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public String toString() { public String toString() {
String decimal = (decimalPoint ? ",DecimalPoint" : ""); String decimal = decimalPoint ? ",DecimalPoint" : "";
return "Fraction(" + field + "," + minWidth + "," + maxWidth + decimal + ")"; return "Fraction(" + field + "," + minWidth + "," + maxWidth + decimal + ")";
} }
} }
@ -2869,7 +2890,7 @@ public final class DateTimeFormatterBuilder {
if (position < 0 || position > length) { if (position < 0 || position > length) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
TextStyle style = (context.isStrict() ? textStyle : null); TextStyle style = context.isStrict() ? textStyle : null;
Iterator<Entry<String, Long>> it = provider.getTextIterator(field, style, context.getLocale()); Iterator<Entry<String, Long>> it = provider.getTextIterator(field, style, context.getLocale());
if (it != null) { if (it != null) {
while (it.hasNext()) { while (it.hasNext()) {
@ -2927,7 +2948,7 @@ public final class DateTimeFormatterBuilder {
public boolean print(DateTimePrintContext context, StringBuilder buf) { public boolean print(DateTimePrintContext context, StringBuilder buf) {
// use INSTANT_SECONDS, thus this code is not bound by Instant.MAX // use INSTANT_SECONDS, thus this code is not bound by Instant.MAX
Long inSecs = context.getValue(INSTANT_SECONDS); Long inSecs = context.getValue(INSTANT_SECONDS);
Long inNanos = 0L; long inNanos = 0L;
if (context.getTemporal().isSupported(NANO_OF_SECOND)) { if (context.getTemporal().isSupported(NANO_OF_SECOND)) {
inNanos = context.getTemporal().getLong(NANO_OF_SECOND); inNanos = context.getTemporal().getLong(NANO_OF_SECOND);
} }
@ -2979,13 +3000,13 @@ public final class DateTimeFormatterBuilder {
} else if (inNano % 1000 == 0) { } else if (inNano % 1000 == 0) {
buf.append(Integer.toString((inNano / 1000) + 1000000).substring(1)); buf.append(Integer.toString((inNano / 1000) + 1000000).substring(1));
} else { } else {
buf.append(Integer.toString((inNano) + 1000000000).substring(1)); buf.append(Integer.toString(inNano + 1000000000).substring(1));
} }
} }
} else if (fractionalDigits > 0 || (fractionalDigits == -1 && inNano > 0)) { } else if (fractionalDigits > 0 || (fractionalDigits == -1 && inNano > 0)) {
buf.append('.'); buf.append('.');
int div = 100000000; int div = 100000000;
for (int i = 0; ((fractionalDigits == -1 && inNano > 0) || i < fractionalDigits); i++) { for (int i = 0; (fractionalDigits == -1 && inNano > 0) || i < fractionalDigits; i++) {
int digit = inNano / div; int digit = inNano / div;
buf.append((char) (digit + '0')); buf.append((char) (digit + '0'));
inNano = inNano - (digit * div); inNano = inNano - (digit * div);
@ -3000,12 +3021,13 @@ public final class DateTimeFormatterBuilder {
public int parse(DateTimeParseContext context, CharSequence text, int position) { public int parse(DateTimeParseContext context, CharSequence text, int position) {
// new context to avoid overwriting fields like year/month/day // new context to avoid overwriting fields like year/month/day
DateTimeParseContext newContext = context.copy(); DateTimeParseContext newContext = context.copy();
int minDigits = (fractionalDigits < 0 ? 0 : fractionalDigits); int minDigits = fractionalDigits < 0 ? 0 : fractionalDigits;
int maxDigits = (fractionalDigits < 0 ? 9 : fractionalDigits); int maxDigits = fractionalDigits < 0 ? 9 : fractionalDigits;
CompositePrinterParser parser = new DateTimeFormatterBuilder() CompositePrinterParser parser = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T') .append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T')
.appendValue(HOUR_OF_DAY, 2).appendLiteral(':').appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':') .appendValue(HOUR_OF_DAY, 2).appendLiteral(':').appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2).appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true).appendLiteral('Z') .appendValue(SECOND_OF_MINUTE, 2).appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true)
.appendLiteral('Z')
.toFormatter().toPrinterParser(false); .toFormatter().toPrinterParser(false);
int pos = parser.parse(newContext, text, position); int pos = parser.parse(newContext, text, position);
if (pos < 0) { if (pos < 0) {
@ -3020,8 +3042,8 @@ public final class DateTimeFormatterBuilder {
int min = newContext.getParsed(MINUTE_OF_HOUR).intValue(); int min = newContext.getParsed(MINUTE_OF_HOUR).intValue();
Long secVal = newContext.getParsed(SECOND_OF_MINUTE); Long secVal = newContext.getParsed(SECOND_OF_MINUTE);
Long nanoVal = newContext.getParsed(NANO_OF_SECOND); Long nanoVal = newContext.getParsed(NANO_OF_SECOND);
int sec = (secVal != null ? secVal.intValue() : 0); int sec = secVal != null ? secVal.intValue() : 0;
int nano = (nanoVal != null ? nanoVal.intValue() : 0); int nano = nanoVal != null ? nanoVal.intValue() : 0;
int year = (int) yearParsed % 10000; int year = (int) yearParsed % 10000;
int days = 0; int days = 0;
if (hour == 24 && min == 0 && sec == 0 && nano == 0) { if (hour == 24 && min == 0 && sec == 0 && nano == 0) {
@ -3141,12 +3163,12 @@ public final class DateTimeFormatterBuilder {
char sign = text.charAt(position); // IOOBE if invalid position char sign = text.charAt(position); // IOOBE if invalid position
if (sign == '+' || sign == '-') { if (sign == '+' || sign == '-') {
// starts // starts
int negative = (sign == '-' ? -1 : 1); int negative = sign == '-' ? -1 : 1;
int[] array = new int[4]; int[] array = new int[4];
array[0] = position + 1; array[0] = position + 1;
if ((parseNumber(array, 1, text, true) || if (!(parseNumber(array, 1, text, true)
parseNumber(array, 2, text, type >=3) || || parseNumber(array, 2, text, type >= 3)
parseNumber(array, 3, text, false)) == false) { || parseNumber(array, 3, text, false))) {
// success // success
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]); long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]); return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
@ -3244,7 +3266,7 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public int parse(DateTimeParseContext context, CharSequence text, int position) { public int parse(DateTimeParseContext context, CharSequence text, int position) {
if (context.subSequenceEquals(text, position, "GMT", 0, 3) == false) { if (!context.subSequenceEquals(text, position, "GMT", 0, 3)) {
return ~position; return ~position;
} }
position += 3; position += 3;
@ -3259,7 +3281,7 @@ public final class DateTimeFormatterBuilder {
if (sign != '+' && sign != '-') { if (sign != '+' && sign != '-') {
return context.setParsedField(OFFSET_SECONDS, 0, position, position); return context.setParsedField(OFFSET_SECONDS, 0, position, position);
} }
int negative = (sign == '-' ? -1 : 1); int negative = sign == '-' ? -1 : 1;
if (position == end) { if (position == end) {
return ~position; return ~position;
} }
@ -3270,11 +3292,11 @@ public final class DateTimeFormatterBuilder {
return ~position; return ~position;
} }
position++; position++;
int hour = ((int) (ch - 48)); int hour = ch - 48;
if (position != end) { if (position != end) {
ch = text.charAt(position); ch = text.charAt(position);
if (ch >= '0' && ch <= '9') { if (ch >= '0' && ch <= '9') {
hour = hour * 10 + ((int) (ch - 48)); hour = hour * 10 + ch - 48;
if (hour > 23) { if (hour > 23) {
return ~position; return ~position;
} }
@ -3295,13 +3317,13 @@ public final class DateTimeFormatterBuilder {
return ~position; return ~position;
} }
position++; position++;
int min = ((int) (ch - 48)); int min = ch - 48;
ch = text.charAt(position); ch = text.charAt(position);
if (ch < '0' || ch > '9') { if (ch < '0' || ch > '9') {
return ~position; return ~position;
} }
position++; position++;
min = min * 10 + ((int) (ch - 48)); min = min * 10 + ch - 48;
if (min > 59) { if (min > 59) {
return ~position; return ~position;
} }
@ -3319,13 +3341,13 @@ public final class DateTimeFormatterBuilder {
return ~position; return ~position;
} }
position++; position++;
int sec = ((int) (ch - 48)); int sec = ch - 48;
ch = text.charAt(position); ch = text.charAt(position);
if (ch < '0' || ch > '9') { if (ch < '0' || ch > '9') {
return ~position; return ~position;
} }
position++; position++;
sec = sec * 10 + ((int) (ch - 48)); sec = sec * 10 + ch - 48;
if (sec > 59) { if (sec > 59) {
return ~position; return ~position;
} }
@ -3340,15 +3362,12 @@ public final class DateTimeFormatterBuilder {
*/ */
static final class ZoneTextPrinterParser implements DateTimePrinterParser { static final class ZoneTextPrinterParser implements DateTimePrinterParser {
/** The text style to output. */ /** The text style to output. */
private static final Comparator<String> LENGTH_COMPARATOR = new Comparator<String>() { private static final Comparator<String> LENGTH_COMPARATOR = (str1, str2) -> {
@Override int cmp = str2.length() - str1.length();
public int compare(String str1, String str2) { if (cmp == 0) {
int cmp = str2.length() - str1.length(); cmp = str1.compareTo(str2);
if (cmp == 0) {
cmp = str1.compareTo(str2);
}
return cmp;
} }
return cmp;
}; };
/** The text style to output. */ /** The text style to output. */
private final TextStyle textStyle; private final TextStyle textStyle;
@ -3375,7 +3394,7 @@ public final class DateTimeFormatterBuilder {
daylight = zone.getRules().isDaylightSavings(instant); daylight = zone.getRules().isDaylightSavings(instant);
} }
TimeZone tz = TimeZone.getTimeZone(zone.getId()); TimeZone tz = TimeZone.getTimeZone(zone.getId());
int tzstyle = (textStyle.asNormal() == TextStyle.FULL ? TimeZone.LONG : TimeZone.SHORT); int tzstyle = textStyle.asNormal() == TextStyle.FULL ? TimeZone.LONG : TimeZone.SHORT;
String text = tz.getDisplayName(daylight, tzstyle, context.getLocale()); String text = tz.getDisplayName(daylight, tzstyle, context.getLocale());
buf.append(text); buf.append(text);
return true; return true;
@ -3389,7 +3408,7 @@ public final class DateTimeFormatterBuilder {
for (String id : ZoneId.getAvailableZoneIds()) { for (String id : ZoneId.getAvailableZoneIds()) {
ids.put(id, id); ids.put(id, id);
TimeZone tz = TimeZone.getTimeZone(id); TimeZone tz = TimeZone.getTimeZone(id);
int tzstyle = (textStyle.asNormal() == TextStyle.FULL ? TimeZone.LONG : TimeZone.SHORT); int tzstyle = textStyle.asNormal() == TextStyle.FULL ? TimeZone.LONG : TimeZone.SHORT;
String textWinter = tz.getDisplayName(false, tzstyle, context.getLocale()); String textWinter = tz.getDisplayName(false, tzstyle, context.getLocale());
if (id.startsWith("Etc/") || (!textWinter.startsWith("GMT+") && !textWinter.startsWith("GMT+"))) { if (id.startsWith("Etc/") || (!textWinter.startsWith("GMT+") && !textWinter.startsWith("GMT+"))) {
ids.put(textWinter, id); ids.put(textWinter, id);
@ -3479,17 +3498,15 @@ public final class DateTimeFormatterBuilder {
return endPos; return endPos;
} else if (length >= position + 2) { } else if (length >= position + 2) {
char nextNextChar = text.charAt(position + 1); char nextNextChar = text.charAt(position + 1);
if (context.charEquals(nextChar, 'U') && if (context.charEquals(nextChar, 'U') && context.charEquals(nextNextChar, 'T')) {
context.charEquals(nextNextChar, 'T')) { if (length >= position + 3 && context.charEquals(text.charAt(position + 2), 'C')) {
if (length >= position + 3 &&
context.charEquals(text.charAt(position + 2), 'C')) {
return parsePrefixedOffset(context, text, position, position + 3); return parsePrefixedOffset(context, text, position, position + 3);
} }
return parsePrefixedOffset(context, text, position, position + 2); return parsePrefixedOffset(context, text, position, position + 2);
} else if (context.charEquals(nextChar, 'G') && } else if (context.charEquals(nextChar, 'G')
length >= position + 3 && && length >= position + 3
context.charEquals(nextNextChar, 'M') && && context.charEquals(nextNextChar, 'M')
context.charEquals(text.charAt(position + 2), 'T')) { && context.charEquals(text.charAt(position + 2), 'T')) {
return parsePrefixedOffset(context, text, position, position + 3); return parsePrefixedOffset(context, text, position, position + 3);
} }
} }
@ -3502,7 +3519,8 @@ public final class DateTimeFormatterBuilder {
synchronized (this) { synchronized (this) {
cached = cachedSubstringTree; cached = cachedSubstringTree;
if (cached == null || cached.getKey() != regionIdsSize) { if (cached == null || cached.getKey() != regionIdsSize) {
cachedSubstringTree = cached = new SimpleImmutableEntry<Integer, SubstringTree>(regionIdsSize, prepareParser(regionIds)); cached = new SimpleImmutableEntry<>(regionIdsSize, prepareParser(regionIds));
cachedSubstringTree = cached;
} }
} }
} }
@ -3541,7 +3559,7 @@ public final class DateTimeFormatterBuilder {
return null; return null;
} }
if (caseSensitive) { if (caseSensitive) {
return (regionIds.contains(parsedZoneId) ? ZoneId.of(parsedZoneId) : null); return regionIds.contains(parsedZoneId) ? ZoneId.of(parsedZoneId) : null;
} else { } else {
for (String regionId : regionIds) { for (String regionId : regionIds) {
if (regionId.equalsIgnoreCase(parsedZoneId)) { if (regionId.equalsIgnoreCase(parsedZoneId)) {
@ -3601,11 +3619,11 @@ public final class DateTimeFormatterBuilder {
/** /**
* Map of a substring to a set of substrings that contain the key. * Map of a substring to a set of substrings that contain the key.
*/ */
private final Map<CharSequence, SubstringTree> substringMap = new HashMap<CharSequence, SubstringTree>(); private final Map<CharSequence, SubstringTree> substringMap = new HashMap<>();
/** /**
* Map of a substring to a set of substrings that contain the key. * Map of a substring to a set of substrings that contain the key.
*/ */
private final Map<String, SubstringTree> substringMapCI = new HashMap<String, SubstringTree>(); private final Map<String, SubstringTree> substringMapCI = new HashMap<>();
/** /**
* Constructor. * Constructor.
@ -3695,8 +3713,10 @@ public final class DateTimeFormatterBuilder {
if (textStyle == null) { if (textStyle == null) {
buf.append(chrono.getId()); buf.append(chrono.getId());
} else { } else {
// TODO: replace with supported bundle type
ResourceBundle bundle = ResourceBundle.getBundle( ResourceBundle bundle = ResourceBundle.getBundle(
"org.threeten.bp.format.ChronologyText", context.getLocale(), DateTimeFormatterBuilder.class.getClassLoader()); "org.threeten.bp.format.ChronologyText", context.getLocale(),
DateTimeFormatterBuilder.class.getClassLoader());
try { try {
String text = bundle.getString(chrono.getId()); String text = bundle.getString(chrono.getId());
buf.append(text); buf.append(text);
@ -3778,8 +3798,8 @@ public final class DateTimeFormatterBuilder {
@Override @Override
public String toString() { public String toString() {
return "Localized(" + (dateStyle != null ? dateStyle : "") + "," + return "Localized(" + (dateStyle != null ? dateStyle : "") + ","
(timeStyle != null ? timeStyle : "") + ")"; + (timeStyle != null ? timeStyle : "") + ")";
} }
} }
@ -3827,7 +3847,8 @@ public final class DateTimeFormatterBuilder {
break; break;
case 'Y': // weekyear case 'Y': // weekyear
if (count == 2) { if (count == 2) {
pp = new ReducedPrinterParser(weekFields.weekBasedYear(), 2, 2, 0, ReducedPrinterParser.BASE_DATE); pp = new ReducedPrinterParser(weekFields.weekBasedYear(), 2, 2, 0,
ReducedPrinterParser.BASE_DATE);
} else { } else {
pp = new NumberPrinterParser(weekFields.weekBasedYear(), count, 19, pp = new NumberPrinterParser(weekFields.weekBasedYear(), count, 19,
(count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1); (count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1);
@ -3871,11 +3892,7 @@ public final class DateTimeFormatterBuilder {
/** /**
* Length comparator. * Length comparator.
*/ */
static final Comparator<String> LENGTH_SORT = new Comparator<String>() { static final Comparator<String> LENGTH_SORT =
@Override (str1, str2) -> str1.length() == str2.length() ? str1.compareTo(str2) : str1.length() - str2.length();
public int compare(String str1, String str2) {
return str1.length() == str2.length() ? str1.compareTo(str2) : str1.length() - str2.length();
}
};
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -37,7 +52,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Period; import org.threeten.bp.Period;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
@ -224,8 +238,8 @@ public final class DateTimeParseContext {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char ch1 = cs1.charAt(offset1 + i); char ch1 = cs1.charAt(offset1 + i);
char ch2 = cs2.charAt(offset2 + i); char ch2 = cs2.charAt(offset2 + i);
if (ch1 != ch2 && Character.toUpperCase(ch1) != Character.toUpperCase(ch2) && if (ch1 != ch2 && Character.toUpperCase(ch1) != Character.toUpperCase(ch2)
Character.toLowerCase(ch1) != Character.toLowerCase(ch2)) { && Character.toLowerCase(ch1) != Character.toLowerCase(ch2)) {
return false; return false;
} }
} }
@ -256,9 +270,9 @@ public final class DateTimeParseContext {
* @return true if equal * @return true if equal
*/ */
static boolean charEqualsIgnoreCase(char c1, char c2) { static boolean charEqualsIgnoreCase(char c1, char c2) {
return c1 == c2 || return c1 == c2
Character.toUpperCase(c1) == Character.toUpperCase(c2) || || Character.toUpperCase(c1) == Character.toUpperCase(c2)
Character.toLowerCase(c1) == Character.toLowerCase(c2); || Character.toLowerCase(c1) == Character.toLowerCase(c2);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -369,7 +383,8 @@ public final class DateTimeParseContext {
} }
} }
void addChronologyChangedParser(ReducedPrinterParser reducedPrinterParser, long value, int errorPos, int successPos) { void addChronologyChangedParser(ReducedPrinterParser reducedPrinterParser, long value, int errorPos,
int successPos) {
Parsed currentParsed = currentParsed(); Parsed currentParsed = currentParsed();
if (currentParsed.callbacks == null) { if (currentParsed.callbacks == null) {
currentParsed.callbacks = new ArrayList<Object[]>(2); currentParsed.callbacks = new ArrayList<Object[]>(2);
@ -424,8 +439,8 @@ public final class DateTimeParseContext {
* Temporary store of parsed data. * Temporary store of parsed data.
*/ */
final class Parsed implements TemporalAccessor { final class Parsed implements TemporalAccessor {
Chronology chrono = null; Chronology chrono;
ZoneId zone = null; ZoneId zone;
final Map<TemporalField, Long> fieldValues = new HashMap<>(); final Map<TemporalField, Long> fieldValues = new HashMap<>();
boolean leapSecond; boolean leapSecond;
Period excessDays = Period.ZERO; Period excessDays = Period.ZERO;
@ -451,7 +466,7 @@ public final class DateTimeParseContext {
} }
@Override @Override
public int get(TemporalField field) { public int get(TemporalField field) {
if (fieldValues.containsKey(field) == false) { if (!fieldValues.containsKey(field)) {
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
long value = fieldValues.get(field); long value = fieldValues.get(field);
@ -459,7 +474,7 @@ public final class DateTimeParseContext {
} }
@Override @Override
public long getLong(TemporalField field) { public long getLong(TemporalField field) {
if (fieldValues.containsKey(field) == false) { if (!fieldValues.containsKey(field)) {
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
} }
return fieldValues.get(field); return fieldValues.get(field);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,10 +48,8 @@ package org.threeten.bp.format;
import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS; import static org.threeten.bp.temporal.ChronoField.INSTANT_SECONDS;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
@ -120,20 +133,21 @@ public final class DateTimePrintContext {
if (overrideChrono == null && overrideZone == null) { if (overrideChrono == null && overrideZone == null) {
return temporal; return temporal;
} }
final Chronology effectiveChrono = (overrideChrono != null ? overrideChrono : temporalChrono); final Chronology effectiveChrono = overrideChrono != null ? overrideChrono : temporalChrono;
final ZoneId effectiveZone = (overrideZone != null ? overrideZone : temporalZone); final ZoneId effectiveZone = overrideZone != null ? overrideZone : temporalZone;
// use overrides // use overrides
if (overrideZone != null) { if (overrideZone != null) {
// handle instant // handle instant
if (temporal.isSupported(INSTANT_SECONDS)) { if (temporal.isSupported(INSTANT_SECONDS)) {
Chronology chrono = (effectiveChrono != null ? effectiveChrono : IsoChronology.INSTANCE); Chronology chrono = effectiveChrono != null ? effectiveChrono : IsoChronology.INSTANCE;
return chrono.zonedDateTime(Instant.from(temporal), overrideZone); return chrono.zonedDateTime(Instant.from(temporal), overrideZone);
} }
// block changing zone on OffsetTime, and similar problem cases // block changing zone on OffsetTime, and similar problem cases
ZoneId normalizedOffset = overrideZone.normalized(); ZoneId normalizedOffset = overrideZone.normalized();
ZoneOffset temporalOffset = temporal.query(TemporalQueries.offset()); ZoneOffset temporalOffset = temporal.query(TemporalQueries.offset());
if (normalizedOffset instanceof ZoneOffset && temporalOffset != null && normalizedOffset.equals(temporalOffset) == false) { if (normalizedOffset instanceof ZoneOffset && temporalOffset != null
&& !normalizedOffset.equals(temporalOffset)) {
throw new DateTimeException("Invalid override zone for temporal: " + overrideZone + " " + temporal); throw new DateTimeException("Invalid override zone for temporal: " + overrideZone + " " + temporal);
} }
} }
@ -146,7 +160,8 @@ public final class DateTimePrintContext {
if (!(overrideChrono == IsoChronology.INSTANCE && temporalChrono == null)) { if (!(overrideChrono == IsoChronology.INSTANCE && temporalChrono == null)) {
for (ChronoField f : ChronoField.values()) { for (ChronoField f : ChronoField.values()) {
if (f.isDateBased() && temporal.isSupported(f)) { if (f.isDateBased() && temporal.isSupported(f)) {
throw new DateTimeException("Invalid override chronology for temporal: " + overrideChrono + " " + temporal); throw new DateTimeException("Invalid override chronology for temporal: "
+ overrideChrono + " " + temporal);
} }
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp.format;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.threeten.bp.temporal.TemporalField; import org.threeten.bp.temporal.TemporalField;
/** /**
@ -50,7 +64,7 @@ import org.threeten.bp.temporal.TemporalField;
*/ */
public abstract class DateTimeTextProvider { public abstract class DateTimeTextProvider {
private static DateTimeTextProvider MUTABLE_PROVIDER; private static DateTimeTextProvider mutableProvider;
/** /**
* Gets the provider. * Gets the provider.
@ -71,10 +85,10 @@ public abstract class DateTimeTextProvider {
* @throws IllegalStateException if initialization has already occurred or another provider has been set * @throws IllegalStateException if initialization has already occurred or another provider has been set
*/ */
public static void setInitializer(DateTimeTextProvider provider) { public static void setInitializer(DateTimeTextProvider provider) {
if (MUTABLE_PROVIDER != null) { if (mutableProvider != null) {
throw new IllegalStateException("Provider was already set, possibly with a default during initialization"); throw new IllegalStateException("Provider was already set, possibly with a default during initialization");
} }
MUTABLE_PROVIDER = provider; mutableProvider = provider;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -120,8 +134,8 @@ public abstract class DateTimeTextProvider {
// initialize the provider // initialize the provider
static DateTimeTextProvider initialize() { static DateTimeTextProvider initialize() {
// Set the default initializer if none has been provided yet // Set the default initializer if none has been provided yet
MUTABLE_PROVIDER = new SimpleDateTimeTextProvider(); mutableProvider = new SimpleDateTimeTextProvider();
return MUTABLE_PROVIDER; return mutableProvider;
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -311,8 +326,8 @@ public final class DecimalStyle {
} }
if (obj instanceof DecimalStyle) { if (obj instanceof DecimalStyle) {
DecimalStyle other = (DecimalStyle) obj; DecimalStyle other = (DecimalStyle) obj;
return (zeroDigit == other.zeroDigit && positiveSign == other.positiveSign && return zeroDigit == other.zeroDigit && positiveSign == other.positiveSign
negativeSign == other.negativeSign && decimalSeparator == other.decimalSeparator); && negativeSign == other.negativeSign && decimalSeparator == other.decimalSeparator;
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -36,7 +51,6 @@ import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
/** /**

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -35,7 +50,6 @@ import static org.threeten.bp.temporal.ChronoField.AMPM_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.DAY_OF_WEEK; import static org.threeten.bp.temporal.ChronoField.DAY_OF_WEEK;
import static org.threeten.bp.temporal.ChronoField.ERA; import static org.threeten.bp.temporal.ChronoField.ERA;
import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR; import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.util.AbstractMap.SimpleImmutableEntry; import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,7 +63,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.threeten.bp.temporal.IsoFields; import org.threeten.bp.temporal.IsoFields;
import org.threeten.bp.temporal.TemporalField; import org.threeten.bp.temporal.TemporalField;
@ -106,7 +119,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
private Object createStore(TemporalField field, Locale locale) { private Object createStore(TemporalField field, Locale locale) {
if (field == MONTH_OF_YEAR) { if (field == MONTH_OF_YEAR) {
DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale); DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale);
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<TextStyle, Map<Long,String>>(); Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
Long f1 = 1L; Long f1 = 1L;
Long f2 = 2L; Long f2 = 2L;
Long f3 = 3L; Long f3 = 3L;
@ -120,7 +133,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
Long f11 = 11L; Long f11 = 11L;
Long f12 = 12L; Long f12 = 12L;
String[] array = oldSymbols.getMonths(); String[] array = oldSymbols.getMonths();
Map<Long, String> map = new HashMap<Long, String>(); Map<Long, String> map = new HashMap<>();
map.put(f1, array[Calendar.JANUARY]); map.put(f1, array[Calendar.JANUARY]);
map.put(f2, array[Calendar.FEBRUARY]); map.put(f2, array[Calendar.FEBRUARY]);
map.put(f3, array[Calendar.MARCH]); map.put(f3, array[Calendar.MARCH]);
@ -135,7 +148,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
map.put(f12, array[Calendar.DECEMBER]); map.put(f12, array[Calendar.DECEMBER]);
styleMap.put(TextStyle.FULL, map); styleMap.put(TextStyle.FULL, map);
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(f1, array[Calendar.JANUARY].substring(0, 1)); map.put(f1, array[Calendar.JANUARY].substring(0, 1));
map.put(f2, array[Calendar.FEBRUARY].substring(0, 1)); map.put(f2, array[Calendar.FEBRUARY].substring(0, 1));
map.put(f3, array[Calendar.MARCH].substring(0, 1)); map.put(f3, array[Calendar.MARCH].substring(0, 1));
@ -151,7 +164,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
styleMap.put(TextStyle.NARROW, map); styleMap.put(TextStyle.NARROW, map);
array = oldSymbols.getShortMonths(); array = oldSymbols.getShortMonths();
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(f1, array[Calendar.JANUARY]); map.put(f1, array[Calendar.JANUARY]);
map.put(f2, array[Calendar.FEBRUARY]); map.put(f2, array[Calendar.FEBRUARY]);
map.put(f3, array[Calendar.MARCH]); map.put(f3, array[Calendar.MARCH]);
@ -169,7 +182,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
} }
if (field == DAY_OF_WEEK) { if (field == DAY_OF_WEEK) {
DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale); DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale);
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<TextStyle, Map<Long,String>>(); Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
Long f1 = 1L; Long f1 = 1L;
Long f2 = 2L; Long f2 = 2L;
Long f3 = 3L; Long f3 = 3L;
@ -178,7 +191,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
Long f6 = 6L; Long f6 = 6L;
Long f7 = 7L; Long f7 = 7L;
String[] array = oldSymbols.getWeekdays(); String[] array = oldSymbols.getWeekdays();
Map<Long, String> map = new HashMap<Long, String>(); Map<Long, String> map = new HashMap<>();
map.put(f1, array[Calendar.MONDAY]); map.put(f1, array[Calendar.MONDAY]);
map.put(f2, array[Calendar.TUESDAY]); map.put(f2, array[Calendar.TUESDAY]);
map.put(f3, array[Calendar.WEDNESDAY]); map.put(f3, array[Calendar.WEDNESDAY]);
@ -188,7 +201,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
map.put(f7, array[Calendar.SUNDAY]); map.put(f7, array[Calendar.SUNDAY]);
styleMap.put(TextStyle.FULL, map); styleMap.put(TextStyle.FULL, map);
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(f1, array[Calendar.MONDAY].substring(0, 1)); map.put(f1, array[Calendar.MONDAY].substring(0, 1));
map.put(f2, array[Calendar.TUESDAY].substring(0, 1)); map.put(f2, array[Calendar.TUESDAY].substring(0, 1));
map.put(f3, array[Calendar.WEDNESDAY].substring(0, 1)); map.put(f3, array[Calendar.WEDNESDAY].substring(0, 1));
@ -199,7 +212,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
styleMap.put(TextStyle.NARROW, map); styleMap.put(TextStyle.NARROW, map);
array = oldSymbols.getShortWeekdays(); array = oldSymbols.getShortWeekdays();
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(f1, array[Calendar.MONDAY]); map.put(f1, array[Calendar.MONDAY]);
map.put(f2, array[Calendar.TUESDAY]); map.put(f2, array[Calendar.TUESDAY]);
map.put(f3, array[Calendar.WEDNESDAY]); map.put(f3, array[Calendar.WEDNESDAY]);
@ -212,9 +225,9 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
} }
if (field == AMPM_OF_DAY) { if (field == AMPM_OF_DAY) {
DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale); DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale);
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<TextStyle, Map<Long,String>>(); Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
String[] array = oldSymbols.getAmPmStrings(); String[] array = oldSymbols.getAmPmStrings();
Map<Long, String> map = new HashMap<Long, String>(); Map<Long, String> map = new HashMap<>();
map.put(0L, array[Calendar.AM]); map.put(0L, array[Calendar.AM]);
map.put(1L, array[Calendar.PM]); map.put(1L, array[Calendar.PM]);
styleMap.put(TextStyle.FULL, map); styleMap.put(TextStyle.FULL, map);
@ -223,14 +236,14 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
} }
if (field == ERA) { if (field == ERA) {
DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale); DateFormatSymbols oldSymbols = DateFormatSymbols.getInstance(locale);
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<TextStyle, Map<Long,String>>(); Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
String[] array = oldSymbols.getEras(); String[] array = oldSymbols.getEras();
Map<Long, String> map = new HashMap<Long, String>(); Map<Long, String> map = new HashMap<Long, String>();
map.put(0L, array[GregorianCalendar.BC]); map.put(0L, array[GregorianCalendar.BC]);
map.put(1L, array[GregorianCalendar.AD]); map.put(1L, array[GregorianCalendar.AD]);
styleMap.put(TextStyle.SHORT, map); styleMap.put(TextStyle.SHORT, map);
if (locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) { if (locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(0L, "Before Christ"); map.put(0L, "Before Christ");
map.put(1L, "Anno Domini"); map.put(1L, "Anno Domini");
styleMap.put(TextStyle.FULL, map); styleMap.put(TextStyle.FULL, map);
@ -246,14 +259,14 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
} }
// hard code English quarter text // hard code English quarter text
if (field == IsoFields.QUARTER_OF_YEAR) { if (field == IsoFields.QUARTER_OF_YEAR) {
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<TextStyle, Map<Long,String>>(); Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
Map<Long, String> map = new HashMap<Long, String>(); Map<Long, String> map = new HashMap<>();
map.put(1L, "Q1"); map.put(1L, "Q1");
map.put(2L, "Q2"); map.put(2L, "Q2");
map.put(3L, "Q3"); map.put(3L, "Q3");
map.put(4L, "Q4"); map.put(4L, "Q4");
styleMap.put(TextStyle.SHORT, map); styleMap.put(TextStyle.SHORT, map);
map = new HashMap<Long, String>(); map = new HashMap<>();
map.put(1L, "1st quarter"); map.put(1L, "1st quarter");
map.put(2L, "2nd quarter"); map.put(2L, "2nd quarter");
map.put(3L, "3rd quarter"); map.put(3L, "3rd quarter");
@ -280,7 +293,7 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
private static LocaleStore createLocaleStore(Map<TextStyle, Map<Long, String>> valueTextMap) { private static LocaleStore createLocaleStore(Map<TextStyle, Map<Long, String>> valueTextMap) {
valueTextMap.put(TextStyle.FULL_STANDALONE, valueTextMap.get(TextStyle.FULL)); valueTextMap.put(TextStyle.FULL_STANDALONE, valueTextMap.get(TextStyle.FULL));
valueTextMap.put(TextStyle.SHORT_STANDALONE, valueTextMap.get(TextStyle.SHORT)); valueTextMap.put(TextStyle.SHORT_STANDALONE, valueTextMap.get(TextStyle.SHORT));
if (valueTextMap.containsKey(TextStyle.NARROW) && valueTextMap.containsKey(TextStyle.NARROW_STANDALONE) == false) { if (valueTextMap.containsKey(TextStyle.NARROW) && !valueTextMap.containsKey(TextStyle.NARROW_STANDALONE)) {
valueTextMap.put(TextStyle.NARROW_STANDALONE, valueTextMap.get(TextStyle.NARROW)); valueTextMap.put(TextStyle.NARROW_STANDALONE, valueTextMap.get(TextStyle.NARROW));
} }
return new LocaleStore(valueTextMap); return new LocaleStore(valueTextMap);
@ -313,16 +326,16 @@ final class SimpleDateTimeTextProvider extends DateTimeTextProvider {
*/ */
LocaleStore(Map<TextStyle, Map<Long, String>> valueTextMap) { LocaleStore(Map<TextStyle, Map<Long, String>> valueTextMap) {
this.valueTextMap = valueTextMap; this.valueTextMap = valueTextMap;
Map<TextStyle, List<Entry<String, Long>>> map = new HashMap<TextStyle, List<Entry<String,Long>>>(); Map<TextStyle, List<Entry<String, Long>>> map = new HashMap<>();
List<Entry<String, Long>> allList = new ArrayList<Map.Entry<String,Long>>(); List<Entry<String, Long>> allList = new ArrayList<>();
for (TextStyle style : valueTextMap.keySet()) { for (TextStyle style : valueTextMap.keySet()) {
Map<String, Entry<String, Long>> reverse = new HashMap<String, Map.Entry<String,Long>>(); Map<String, Entry<String, Long>> reverse = new HashMap<>();
for (Map.Entry<Long, String> entry : valueTextMap.get(style).entrySet()) { for (Map.Entry<Long, String> entry : valueTextMap.get(style).entrySet()) {
if (reverse.put(entry.getValue(), createEntry(entry.getValue(), entry.getKey())) != null) { if (reverse.put(entry.getValue(), createEntry(entry.getValue(), entry.getKey())) != null) {
continue; // not parsable, try next style continue; // not parsable, try next style
} }
} }
List<Entry<String, Long>> list = new ArrayList<Map.Entry<String,Long>>(reverse.values()); List<Entry<String, Long>> list = new ArrayList<>(reverse.values());
Collections.sort(list, COMPARATOR); Collections.sort(list, COMPARATOR);
map.put(style, list); map.put(style, list);
allList.addAll(list); allList.addAll(list);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -219,7 +234,7 @@ public final class Jdk8Methods {
* @return the floor division * @return the floor division
*/ */
public static long floorDiv(long a, long b) { public static long floorDiv(long a, long b) {
return (a >= 0 ? a / b : ((a + 1) / b) - 1); return a >= 0 ? a / b : ((a + 1) / b) - 1;
} }
/** /**
@ -274,7 +289,7 @@ public final class Jdk8Methods {
* @return the floor division * @return the floor division
*/ */
public static int floorDiv(int a, int b) { public static int floorDiv(int a, int b) {
return (a >= 0 ? a / b : ((a + 1) / b) - 1); return a >= 0 ? a / b : ((a + 1) / b) - 1;
} }
/** /**

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -44,7 +59,6 @@ import static org.threeten.bp.temporal.ChronoUnit.NANOS;
import static org.threeten.bp.temporal.ChronoUnit.SECONDS; import static org.threeten.bp.temporal.ChronoUnit.SECONDS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -524,6 +538,7 @@ public enum ChronoField implements TemporalField {
* *
* @return true if it is a component of a date * @return true if it is a component of a date
*/ */
@Override
public boolean isDateBased() { public boolean isDateBased() {
return ordinal() >= DAY_OF_WEEK.ordinal() && ordinal() <= ERA.ordinal(); return ordinal() >= DAY_OF_WEEK.ordinal() && ordinal() <= ERA.ordinal();
} }
@ -533,6 +548,7 @@ public enum ChronoField implements TemporalField {
* *
* @return true if it is a component of a time * @return true if it is a component of a time
*/ */
@Override
public boolean isTimeBased() { public boolean isTimeBased() {
return ordinal() < DAY_OF_WEEK.ordinal(); return ordinal() < DAY_OF_WEEK.ordinal();
} }
@ -606,7 +622,7 @@ public enum ChronoField implements TemporalField {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Override @Override
public TemporalAccessor resolve(Map<TemporalField, Long> fieldValues, public TemporalAccessor resolve(Map<TemporalField, Long> fieldValues,
TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
return null; // resolve implemented in builder return null; // resolve implemented in builder
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -209,6 +224,7 @@ public enum ChronoUnit implements TemporalUnit {
* *
* @return true if a date unit, false if a time unit * @return true if a date unit, false if a time unit
*/ */
@Override
public boolean isDateBased() { public boolean isDateBased() {
return this.compareTo(DAYS) >= 0 && this != FOREVER; return this.compareTo(DAYS) >= 0 && this != FOREVER;
} }
@ -218,6 +234,7 @@ public enum ChronoUnit implements TemporalUnit {
* *
* @return true if a time unit, false if a date unit * @return true if a time unit, false if a date unit
*/ */
@Override
public boolean isTimeBased() { public boolean isTimeBased() {
return this.compareTo(DAYS) < 0; return this.compareTo(DAYS) < 0;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -43,11 +58,9 @@ import static org.threeten.bp.temporal.ChronoUnit.FOREVER;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.WEEKS; import static org.threeten.bp.temporal.ChronoUnit.WEEKS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Duration; import org.threeten.bp.Duration;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
import org.threeten.bp.chrono.Chronology; import org.threeten.bp.chrono.Chronology;
@ -223,18 +236,18 @@ public final class IsoFields {
} }
@Override @Override
public boolean isSupportedBy(TemporalAccessor temporal) { public boolean isSupportedBy(TemporalAccessor temporal) {
return temporal.isSupported(DAY_OF_YEAR) && temporal.isSupported(MONTH_OF_YEAR) && return temporal.isSupported(DAY_OF_YEAR) && temporal.isSupported(MONTH_OF_YEAR)
temporal.isSupported(YEAR) && isIso(temporal); && temporal.isSupported(YEAR) && isIso(temporal);
} }
@Override @Override
public ValueRange rangeRefinedBy(TemporalAccessor temporal) { public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: DayOfQuarter"); throw new UnsupportedTemporalTypeException("Unsupported field: DayOfQuarter");
} }
long qoy = temporal.getLong(QUARTER_OF_YEAR); long qoy = temporal.getLong(QUARTER_OF_YEAR);
if (qoy == 1) { if (qoy == 1) {
long year = temporal.getLong(YEAR); long year = temporal.getLong(YEAR);
return (IsoChronology.INSTANCE.isLeapYear(year) ? ValueRange.of(1, 91) : ValueRange.of(1, 90)); return IsoChronology.INSTANCE.isLeapYear(year) ? ValueRange.of(1, 91) : ValueRange.of(1, 90);
} else if (qoy == 2) { } else if (qoy == 2) {
return ValueRange.of(1, 91); return ValueRange.of(1, 91);
} else if (qoy == 3 || qoy == 4) { } else if (qoy == 3 || qoy == 4) {
@ -244,7 +257,7 @@ public final class IsoFields {
} }
@Override @Override
public long getFrom(TemporalAccessor temporal) { public long getFrom(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: DayOfQuarter"); throw new UnsupportedTemporalTypeException("Unsupported field: DayOfQuarter");
} }
int doy = temporal.get(DAY_OF_YEAR); int doy = temporal.get(DAY_OF_YEAR);
@ -280,7 +293,7 @@ public final class IsoFields {
if (resolverStyle == ResolverStyle.STRICT) { if (resolverStyle == ResolverStyle.STRICT) {
int max = 92; int max = 92;
if (qoy == 1) { if (qoy == 1) {
max = (IsoChronology.INSTANCE.isLeapYear(y) ? 91 : 90); max = IsoChronology.INSTANCE.isLeapYear(y) ? 91 : 90;
} else if (qoy == 2) { } else if (qoy == 2) {
max = 91; max = 91;
} }
@ -323,11 +336,11 @@ public final class IsoFields {
} }
@Override @Override
public long getFrom(TemporalAccessor temporal) { public long getFrom(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: QuarterOfYear"); throw new UnsupportedTemporalTypeException("Unsupported field: QuarterOfYear");
} }
long moy = temporal.getLong(MONTH_OF_YEAR); long moy = temporal.getLong(MONTH_OF_YEAR);
return ((moy + 2) / 3); return (moy + 2) / 3;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
@ -366,14 +379,14 @@ public final class IsoFields {
} }
@Override @Override
public ValueRange rangeRefinedBy(TemporalAccessor temporal) { public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: WeekOfWeekBasedYear"); throw new UnsupportedTemporalTypeException("Unsupported field: WeekOfWeekBasedYear");
} }
return getWeekRange(LocalDate.from(temporal)); return getWeekRange(LocalDate.from(temporal));
} }
@Override @Override
public long getFrom(TemporalAccessor temporal) { public long getFrom(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: WeekOfWeekBasedYear"); throw new UnsupportedTemporalTypeException("Unsupported field: WeekOfWeekBasedYear");
} }
return getWeek(LocalDate.from(temporal)); return getWeek(LocalDate.from(temporal));
@ -450,7 +463,7 @@ public final class IsoFields {
} }
@Override @Override
public long getFrom(TemporalAccessor temporal) { public long getFrom(TemporalAccessor temporal) {
if (temporal.isSupported(this) == false) { if (!temporal.isSupported(this)) {
throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear"); throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear");
} }
return getWeekBasedYear(LocalDate.from(temporal)); return getWeekBasedYear(LocalDate.from(temporal));
@ -458,7 +471,7 @@ public final class IsoFields {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <R extends Temporal> R adjustInto(R temporal, long newValue) { public <R extends Temporal> R adjustInto(R temporal, long newValue) {
if (isSupportedBy(temporal) == false) { if (!isSupportedBy(temporal)) {
throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear"); throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear");
} }
int newWby = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check int newWby = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check
@ -532,7 +545,7 @@ public final class IsoFields {
} }
int week = ((doy0 - firstMonDoy0) / 7) + 1; int week = ((doy0 - firstMonDoy0) / 7) + 1;
if (week == 53) { if (week == 53) {
if ((firstMonDoy0 == -3 || (firstMonDoy0 == -2 && date.isLeapYear())) == false) { if (!(firstMonDoy0 == -3 || (firstMonDoy0 == -2 && date.isLeapYear()))) {
week = 1; week = 1;
} }
} }
@ -602,7 +615,7 @@ public final class IsoFields {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <R extends Temporal> R addTo(R temporal, long periodToAdd) { public <R extends Temporal> R addTo(R temporal, long periodToAdd) {
switch(this) { switch (this) {
case WEEK_BASED_YEARS: case WEEK_BASED_YEARS:
long added = Jdk8Methods.safeAdd(temporal.get(WEEK_BASED_YEAR), periodToAdd); long added = Jdk8Methods.safeAdd(temporal.get(WEEK_BASED_YEAR), periodToAdd);
return (R) temporal.with(WEEK_BASED_YEAR, added); return (R) temporal.with(WEEK_BASED_YEAR, added);
@ -616,9 +629,10 @@ public final class IsoFields {
@Override @Override
public long between(Temporal temporal1, Temporal temporal2) { public long between(Temporal temporal1, Temporal temporal2) {
switch(this) { switch (this) {
case WEEK_BASED_YEARS: case WEEK_BASED_YEARS:
return Jdk8Methods.safeSubtract(temporal2.getLong(WEEK_BASED_YEAR), temporal1.getLong(WEEK_BASED_YEAR)); return Jdk8Methods.safeSubtract(temporal2.getLong(WEEK_BASED_YEAR),
temporal1.getLong(WEEK_BASED_YEAR));
case QUARTER_YEARS: case QUARTER_YEARS:
return temporal1.until(temporal2, MONTHS) / 3; return temporal1.until(temporal2, MONTHS) / 3;
default: default:

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp.temporal;
import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
import static org.threeten.bp.temporal.ChronoUnit.DAYS; import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.FOREVER; import static org.threeten.bp.temporal.ChronoUnit.FOREVER;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -173,7 +187,7 @@ public final class JulianFields {
private final ValueRange range; private final ValueRange range;
private final long offset; private final long offset;
private Field(String name, TemporalUnit baseUnit, TemporalUnit rangeUnit, long offset) { Field(String name, TemporalUnit baseUnit, TemporalUnit rangeUnit, long offset) {
this.name = name; this.name = name;
this.baseUnit = baseUnit; this.baseUnit = baseUnit;
this.rangeUnit = rangeUnit; this.rangeUnit = rangeUnit;
@ -215,7 +229,7 @@ public final class JulianFields {
@Override @Override
public ValueRange rangeRefinedBy(TemporalAccessor temporal) { public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
if (isSupportedBy(temporal) == false) { if (!isSupportedBy(temporal)) {
throw new UnsupportedTemporalTypeException("Unsupported field: " + this); throw new UnsupportedTemporalTypeException("Unsupported field: " + this);
} }
return range(); return range();
@ -229,7 +243,7 @@ public final class JulianFields {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <R extends Temporal> R adjustInto(R dateTime, long newValue) { public <R extends Temporal> R adjustInto(R dateTime, long newValue) {
if (range().isValidValue(newValue) == false) { if (!range().isValidValue(newValue)) {
throw new DateTimeException("Invalid value: " + name + " " + newValue); throw new DateTimeException("Invalid value: " + name + " " + newValue);
} }
return (R) dateTime.with(EPOCH_DAY, Jdk8Methods.safeSubtract(newValue, offset)); return (R) dateTime.with(EPOCH_DAY, Jdk8Methods.safeSubtract(newValue, offset));
@ -244,7 +258,7 @@ public final class JulianFields {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Override @Override
public TemporalAccessor resolve(Map<TemporalField, Long> fieldValues, public TemporalAccessor resolve(Map<TemporalField, Long> fieldValues,
TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
long value = fieldValues.remove(this); long value = fieldValues.remove(this);
Chronology chrono = Chronology.from(partialTemporal); Chronology chrono = Chronology.from(partialTemporal);
return chrono.dateEpochDay(Jdk8Methods.safeSubtract(value, offset)); return chrono.dateEpochDay(Jdk8Methods.safeSubtract(value, offset));

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -239,7 +239,8 @@ public interface TemporalAccessor {
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
default <R> R query(TemporalQuery<R> query) { default <R> R query(TemporalQuery<R> query) {
if (query == TemporalQueries.zoneId() || query == TemporalQueries.chronology() || query == TemporalQueries.precision()) { if (query == TemporalQueries.zoneId() || query == TemporalQueries.chronology()
|| query == TemporalQueries.precision()) {
return null; return null;
} }
return query.queryFrom(this); return query.queryFrom(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -38,7 +53,6 @@ import static org.threeten.bp.temporal.ChronoUnit.DAYS;
import static org.threeten.bp.temporal.ChronoUnit.MONTHS; import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
import static org.threeten.bp.temporal.ChronoUnit.YEARS; import static org.threeten.bp.temporal.ChronoUnit.YEARS;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
/** /**
@ -347,7 +361,7 @@ public final class TemporalAdjusters {
Temporal temp = temporal.with(DAY_OF_MONTH, temporal.range(DAY_OF_MONTH).getMaximum()); Temporal temp = temporal.with(DAY_OF_MONTH, temporal.range(DAY_OF_MONTH).getMaximum());
int curDow = temp.get(DAY_OF_WEEK); int curDow = temp.get(DAY_OF_WEEK);
int daysDiff = dowValue - curDow; int daysDiff = dowValue - curDow;
daysDiff = (daysDiff == 0 ? 0 : (daysDiff > 0 ? daysDiff - 7 : daysDiff)); daysDiff = daysDiff == 0 ? 0 : (daysDiff > 0 ? daysDiff - 7 : daysDiff);
daysDiff -= (-ordinal - 1L) * 7L; // safe from overflow daysDiff -= (-ordinal - 1L) * 7L; // safe from overflow
return temp.plus(daysDiff, DAYS); return temp.plus(daysDiff, DAYS);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,7 +47,6 @@
package org.threeten.bp.temporal; package org.threeten.bp.temporal;
import java.util.List; import java.util.List;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.Duration; import org.threeten.bp.Duration;
import org.threeten.bp.Period; import org.threeten.bp.Period;

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,7 +48,6 @@ package org.threeten.bp.temporal;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.format.ResolverStyle; import org.threeten.bp.format.ResolverStyle;

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,7 +49,6 @@ package org.threeten.bp.temporal;
import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY; import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY; import static org.threeten.bp.temporal.ChronoField.NANO_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS; import static org.threeten.bp.temporal.ChronoField.OFFSET_SECONDS;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalTime; import org.threeten.bp.LocalTime;
import org.threeten.bp.OffsetDateTime; import org.threeten.bp.OffsetDateTime;
@ -117,7 +131,7 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the zone ID of a temporal, not null * @return a query that can obtain the zone ID of a temporal, not null
*/ */
public static final TemporalQuery<ZoneId> zoneId() { public static TemporalQuery<ZoneId> zoneId() {
return ZONE_ID; return ZONE_ID;
} }
static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<ZoneId>() { static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<ZoneId>() {
@ -162,7 +176,7 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the chronology of a temporal, not null * @return a query that can obtain the chronology of a temporal, not null
*/ */
public static final TemporalQuery<Chronology> chronology() { public static TemporalQuery<Chronology> chronology() {
return CHRONO; return CHRONO;
} }
static final TemporalQuery<Chronology> CHRONO = new TemporalQuery<Chronology>() { static final TemporalQuery<Chronology> CHRONO = new TemporalQuery<Chronology>() {
@ -205,7 +219,7 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the precision of a temporal, not null * @return a query that can obtain the precision of a temporal, not null
*/ */
public static final TemporalQuery<TemporalUnit> precision() { public static TemporalQuery<TemporalUnit> precision() {
return PRECISION; return PRECISION;
} }
static final TemporalQuery<TemporalUnit> PRECISION = new TemporalQuery<TemporalUnit>() { static final TemporalQuery<TemporalUnit> PRECISION = new TemporalQuery<TemporalUnit>() {
@ -236,14 +250,14 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the zone ID or offset of a temporal, not null * @return a query that can obtain the zone ID or offset of a temporal, not null
*/ */
public static final TemporalQuery<ZoneId> zone() { public static TemporalQuery<ZoneId> zone() {
return ZONE; return ZONE;
} }
static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<ZoneId>() { static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<ZoneId>() {
@Override @Override
public ZoneId queryFrom(TemporalAccessor temporal) { public ZoneId queryFrom(TemporalAccessor temporal) {
ZoneId zone = temporal.query(ZONE_ID); ZoneId zone = temporal.query(ZONE_ID);
return (zone != null ? zone : temporal.query(OFFSET)); return zone != null ? zone : temporal.query(OFFSET);
} }
}; };
@ -259,17 +273,14 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the offset of a temporal, not null * @return a query that can obtain the offset of a temporal, not null
*/ */
public static final TemporalQuery<ZoneOffset> offset() { public static TemporalQuery<ZoneOffset> offset() {
return OFFSET; return OFFSET;
} }
static final TemporalQuery<ZoneOffset> OFFSET = new TemporalQuery<ZoneOffset>() { static final TemporalQuery<ZoneOffset> OFFSET = temporal -> {
@Override if (temporal.isSupported(OFFSET_SECONDS)) {
public ZoneOffset queryFrom(TemporalAccessor temporal) { return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
if (temporal.isSupported(OFFSET_SECONDS)) {
return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
}
return null;
} }
return null;
}; };
/** /**
@ -284,17 +295,14 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the date of a temporal, not null * @return a query that can obtain the date of a temporal, not null
*/ */
public static final TemporalQuery<LocalDate> localDate() { public static TemporalQuery<LocalDate> localDate() {
return LOCAL_DATE; return LOCAL_DATE;
} }
static final TemporalQuery<LocalDate> LOCAL_DATE = new TemporalQuery<LocalDate>() { static final TemporalQuery<LocalDate> LOCAL_DATE = temporal -> {
@Override if (temporal.isSupported(EPOCH_DAY)) {
public LocalDate queryFrom(TemporalAccessor temporal) { return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
if (temporal.isSupported(EPOCH_DAY)) {
return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
}
return null;
} }
return null;
}; };
/** /**
@ -309,17 +317,14 @@ public final class TemporalQueries {
* *
* @return a query that can obtain the date of a temporal, not null * @return a query that can obtain the date of a temporal, not null
*/ */
public static final TemporalQuery<LocalTime> localTime() { public static TemporalQuery<LocalTime> localTime() {
return LOCAL_TIME; return LOCAL_TIME;
} }
static final TemporalQuery<LocalTime> LOCAL_TIME = new TemporalQuery<LocalTime>() { static final TemporalQuery<LocalTime> LOCAL_TIME = temporal -> {
@Override if (temporal.isSupported(NANO_OF_DAY)) {
public LocalTime queryFrom(TemporalAccessor temporal) { return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
if (temporal.isSupported(NANO_OF_DAY)) {
return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
}
return null;
} }
return null;
}; };
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -32,7 +47,6 @@
package org.threeten.bp.temporal; package org.threeten.bp.temporal;
import java.io.Serializable; import java.io.Serializable;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
/** /**
@ -240,7 +254,7 @@ public final class ValueRange implements Serializable {
* @return true if the value is valid * @return true if the value is valid
*/ */
public boolean isValidValue(long value) { public boolean isValidValue(long value) {
return (value >= getMinimum() && value <= getMaximum()); return value >= getMinimum() && value <= getMaximum();
} }
/** /**
@ -268,7 +282,7 @@ public final class ValueRange implements Serializable {
* @see #isValidValue(long) * @see #isValidValue(long)
*/ */
public long checkValidValue(long value, TemporalField field) { public long checkValidValue(long value, TemporalField field) {
if (isValidValue(value) == false) { if (!isValidValue(value)) {
if (field != null) { if (field != null) {
throw new DateTimeException("Invalid value for " + field + " (valid values " + this + "): " + value); throw new DateTimeException("Invalid value for " + field + " (valid values " + this + "): " + value);
} else { } else {
@ -291,7 +305,7 @@ public final class ValueRange implements Serializable {
* @see #isValidIntValue(long) * @see #isValidIntValue(long)
*/ */
public int checkValidIntValue(long value, TemporalField field) { public int checkValidIntValue(long value, TemporalField field) {
if (isValidIntValue(value) == false) { if (!isValidIntValue(value)) {
throw new DateTimeException("Invalid int value for " + field + ": " + value); throw new DateTimeException("Invalid int value for " + field + ": " + value);
} }
return (int) value; return (int) value;
@ -315,8 +329,8 @@ public final class ValueRange implements Serializable {
} }
if (obj instanceof ValueRange) { if (obj instanceof ValueRange) {
ValueRange other = (ValueRange) obj; ValueRange other = (ValueRange) obj;
return minSmallest == other.minSmallest && minLargest == other.minLargest && return minSmallest == other.minSmallest && minLargest == other.minLargest
maxSmallest == other.maxSmallest && maxLargest == other.maxLargest; && maxSmallest == other.maxSmallest && maxLargest == other.maxLargest;
} }
return false; return false;
} }
@ -328,8 +342,8 @@ public final class ValueRange implements Serializable {
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
long hash = minSmallest + minLargest << 16 + minLargest >> 48 + maxSmallest << 32 + long hash = minSmallest + minLargest << 16 + minLargest >> 48 + maxSmallest << 32
maxSmallest >> 32 + maxLargest << 48 + maxLargest >> 16; + maxSmallest >> 32 + maxLargest << 48 + maxLargest >> 16;
return (int) (hash ^ (hash >>> 32)); return (int) (hash ^ (hash >>> 32));
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -607,7 +622,8 @@ public final class WeekFields implements Serializable {
private final TemporalUnit rangeUnit; private final TemporalUnit rangeUnit;
private final ValueRange range; private final ValueRange range;
private ComputedDayOfField(String name, WeekFields weekDef, TemporalUnit baseUnit, TemporalUnit rangeUnit, ValueRange range) { private ComputedDayOfField(String name, WeekFields weekDef, TemporalUnit baseUnit, TemporalUnit rangeUnit,
ValueRange range) {
this.name = name; this.name = name;
this.weekDef = weekDef; this.weekDef = weekDef;
this.baseUnit = baseUnit; this.baseUnit = baseUnit;
@ -731,7 +747,7 @@ public final class WeekFields implements Serializable {
* @return the week number where zero is used for a partial week and 1 for the first full week * @return the week number where zero is used for a partial week and 1 for the first full week
*/ */
private int computeWeek(int offset, int day) { private int computeWeek(int offset, int day) {
return ((7 + offset + (day - 1)) / 7); return (7 + offset + (day - 1)) / 7;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -783,13 +799,13 @@ public final class WeekFields implements Serializable {
fieldValues.put(DAY_OF_WEEK, (long) isoDow); fieldValues.put(DAY_OF_WEEK, (long) isoDow);
return null; return null;
} }
if (fieldValues.containsKey(DAY_OF_WEEK) == false) { if (!fieldValues.containsKey(DAY_OF_WEEK)) {
return null; return null;
} }
// week-based-year // week-based-year
if (rangeUnit == ChronoUnit.FOREVER) { if (rangeUnit == ChronoUnit.FOREVER) {
if (fieldValues.containsKey(weekDef.weekOfWeekBasedYear) == false) { if (!fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) {
return null; return null;
} }
Chronology chrono = Chronology.from(partialTemporal); // defaults to ISO Chronology chrono = Chronology.from(partialTemporal); // defaults to ISO
@ -824,7 +840,7 @@ public final class WeekFields implements Serializable {
return date; return date;
} }
if (fieldValues.containsKey(YEAR) == false) { if (!fieldValues.containsKey(YEAR)) {
return null; return null;
} }
int isoDow = DAY_OF_WEEK.checkValidIntValue(fieldValues.get(DAY_OF_WEEK)); int isoDow = DAY_OF_WEEK.checkValidIntValue(fieldValues.get(DAY_OF_WEEK));
@ -832,7 +848,7 @@ public final class WeekFields implements Serializable {
int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); int year = YEAR.checkValidIntValue(fieldValues.get(YEAR));
Chronology chrono = Chronology.from(partialTemporal); // defaults to ISO Chronology chrono = Chronology.from(partialTemporal); // defaults to ISO
if (rangeUnit == MONTHS) { // week-of-month if (rangeUnit == MONTHS) { // week-of-month
if (fieldValues.containsKey(MONTH_OF_YEAR) == false) { if (!fieldValues.containsKey(MONTH_OF_YEAR)) {
return null; return null;
} }
final long value = fieldValues.remove(this); final long value = fieldValues.remove(this);

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -199,8 +214,7 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
long epochSec = instant.getEpochSecond(); long epochSec = instant.getEpochSecond();
// check if using last rules // check if using last rules
if (lastRules.length > 0 && if (lastRules.length > 0 && epochSec > savingsInstantTransitions[savingsInstantTransitions.length - 1]) {
epochSec > savingsInstantTransitions[savingsInstantTransitions.length - 1]) {
int year = findYear(epochSec, wallOffsets[wallOffsets.length - 1]); int year = findYear(epochSec, wallOffsets[wallOffsets.length - 1]);
ZoneOffsetTransition[] transArray = findTransitionArray(year); ZoneOffsetTransition[] transArray = findTransitionArray(year);
ZoneOffsetTransition trans = null; ZoneOffsetTransition trans = null;
@ -245,13 +259,12 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
@Override @Override
public ZoneOffsetTransition getTransition(LocalDateTime localDateTime) { public ZoneOffsetTransition getTransition(LocalDateTime localDateTime) {
Object info = getOffsetInfo(localDateTime); Object info = getOffsetInfo(localDateTime);
return (info instanceof ZoneOffsetTransition ? (ZoneOffsetTransition) info : null); return info instanceof ZoneOffsetTransition ? (ZoneOffsetTransition) info : null;
} }
private Object getOffsetInfo(LocalDateTime dt) { private Object getOffsetInfo(LocalDateTime dt) {
// check if using last rules // check if using last rules
if (lastRules.length > 0 && if (lastRules.length > 0 && dt.isAfter(savingsLocalTransitions[savingsLocalTransitions.length - 1])) {
dt.isAfter(savingsLocalTransitions[savingsLocalTransitions.length - 1])) {
ZoneOffsetTransition[] transArray = findTransitionArray(dt.getYear()); ZoneOffsetTransition[] transArray = findTransitionArray(dt.getYear());
Object info = null; Object info = null;
for (ZoneOffsetTransition trans : transArray) { for (ZoneOffsetTransition trans : transArray) {
@ -272,8 +285,8 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
if (index < 0) { if (index < 0) {
// switch negative insert position to start of matched range // switch negative insert position to start of matched range
index = -index - 2; index = -index - 2;
} else if (index < savingsLocalTransitions.length - 1 && } else if (index < savingsLocalTransitions.length - 1
savingsLocalTransitions[index].equals(savingsLocalTransitions[index + 1])) { && savingsLocalTransitions[index].equals(savingsLocalTransitions[index + 1])) {
// handle overlap immediately following gap // handle overlap immediately following gap
index++; index++;
} }
@ -315,7 +328,7 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
return trans.getOffsetAfter(); return trans.getOffsetAfter();
} }
} else { } else {
if (dt.isBefore(localTransition) == false) { if (!dt.isBefore(localTransition)) {
return trans.getOffsetAfter(); return trans.getOffsetAfter();
} }
if (dt.isBefore(trans.getDateTimeAfter())) { if (dt.isBefore(trans.getDateTimeAfter())) {
@ -376,7 +389,7 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
@Override @Override
public boolean isDaylightSavings(Instant instant) { public boolean isDaylightSavings(Instant instant) {
return (getStandardOffset(instant).equals(getOffset(instant)) == false); return !getStandardOffset(instant).equals(getOffset(instant));
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -459,7 +472,8 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
if (index <= 0) { if (index <= 0) {
return null; return null;
} }
return new ZoneOffsetTransition(savingsInstantTransitions[index - 1], wallOffsets[index - 1], wallOffsets[index]); return new ZoneOffsetTransition(savingsInstantTransitions[index - 1], wallOffsets[index - 1],
wallOffsets[index]);
} }
private int findYear(long epochSecond, ZoneOffset offset) { private int findYear(long epochSecond, ZoneOffset offset) {
@ -492,11 +506,11 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
} }
if (obj instanceof StandardZoneRules) { if (obj instanceof StandardZoneRules) {
StandardZoneRules other = (StandardZoneRules) obj; StandardZoneRules other = (StandardZoneRules) obj;
return Arrays.equals(standardTransitions, other.standardTransitions) && return Arrays.equals(standardTransitions, other.standardTransitions)
Arrays.equals(standardOffsets, other.standardOffsets) && && Arrays.equals(standardOffsets, other.standardOffsets)
Arrays.equals(savingsInstantTransitions, other.savingsInstantTransitions) && && Arrays.equals(savingsInstantTransitions, other.savingsInstantTransitions)
Arrays.equals(wallOffsets, other.wallOffsets) && && Arrays.equals(wallOffsets, other.wallOffsets)
Arrays.equals(lastRules, other.lastRules); && Arrays.equals(lastRules, other.lastRules);
} }
if (obj instanceof Fixed) { if (obj instanceof Fixed) {
return isFixedOffset() && getOffset(Instant.EPOCH).equals(((Fixed) obj).getOffset(Instant.EPOCH)); return isFixedOffset() && getOffset(Instant.EPOCH).equals(((Fixed) obj).getOffset(Instant.EPOCH));
@ -506,11 +520,11 @@ final class StandardZoneRules extends ZoneRules implements Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
return Arrays.hashCode(standardTransitions) ^ return Arrays.hashCode(standardTransitions)
Arrays.hashCode(standardOffsets) ^ ^ Arrays.hashCode(standardOffsets)
Arrays.hashCode(savingsInstantTransitions) ^ ^ Arrays.hashCode(savingsInstantTransitions)
Arrays.hashCode(wallOffsets) ^ ^ Arrays.hashCode(wallOffsets)
Arrays.hashCode(lastRules); ^ Arrays.hashCode(lastRules);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -1,329 +0,0 @@
/*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.threeten.bp.zone;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamCorruptedException;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
* Loads time-zone rules for 'TZDB'.
* <p>
* This class is public for the service loader to access.
*
* <h3>Specification for implementors</h3>
* This class is immutable and thread-safe.
*/
public final class TzdbZoneRulesProvider extends ZoneRulesProvider {
// TODO: can this be private/hidden in any way?
// service loader seems to need it to be public
/**
* All the regions that are available.
*/
private List<String> regionIds;
/**
* All the versions that are available.
*/
private final ConcurrentNavigableMap<String, Version> versions = new ConcurrentSkipListMap<String, Version>();
/**
* All the URLs that have been loaded.
* Uses String to avoid equals() on URL.
*/
private Set<String> loadedUrls = new CopyOnWriteArraySet<String>();
/**
* Creates an instance.
* Created by the {@code ServiceLoader}.
*
* @throws ZoneRulesException if unable to load
*/
public TzdbZoneRulesProvider() {
super();
if (load(ZoneRulesProvider.class.getClassLoader()) == false) {
throw new ZoneRulesException("No time-zone rules found for 'TZDB'");
}
}
/**
* Creates an instance and loads the specified URL.
* <p>
* This could be used to wrap this provider in another instance.
*
* @param url the URL to load, not null
* @throws ZoneRulesException if unable to load
*/
public TzdbZoneRulesProvider(URL url) {
super();
try {
if (load(url) == false) {
throw new ZoneRulesException("No time-zone rules found: " + url);
}
} catch (Exception ex) {
throw new ZoneRulesException("Unable to load TZDB time-zone rules: " + url, ex);
}
}
/**
* Creates an instance and loads the specified input stream.
* <p>
* This could be used to wrap this provider in another instance.
*
* @param stream the stream to load, not null, not closed after use
* @throws ZoneRulesException if unable to load
*/
public TzdbZoneRulesProvider(InputStream stream) {
super();
try {
load(stream);
} catch (Exception ex) {
throw new ZoneRulesException("Unable to load TZDB time-zone rules", ex);
}
}
//-----------------------------------------------------------------------
@Override
protected Set<String> provideZoneIds() {
return new HashSet<String>(regionIds);
}
@Override
protected ZoneRules provideRules(String zoneId, boolean forCaching) {
Objects.requireNonNull(zoneId, "zoneId");
ZoneRules rules = versions.lastEntry().getValue().getRules(zoneId);
if (rules == null) {
throw new ZoneRulesException("Unknown time-zone ID: " + zoneId);
}
return rules;
}
@Override
protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
TreeMap<String, ZoneRules> map = new TreeMap<String, ZoneRules>();
for (Version version : versions.values()) {
ZoneRules rules = version.getRules(zoneId);
if (rules != null) {
map.put(version.versionId, rules);
}
}
return map;
}
//-------------------------------------------------------------------------
/**
* Loads the rules.
*
* @param classLoader the class loader to use, not null
* @return true if updated
* @throws ZoneRulesException if unable to load
*/
private boolean load(ClassLoader classLoader) {
boolean updated = false;
URL url = null;
try {
Enumeration<URL> en = classLoader.getResources("org/threeten/bp/TZDB.dat");
while (en.hasMoreElements()) {
url = en.nextElement();
updated |= load(url);
}
} catch (Exception ex) {
throw new ZoneRulesException("Unable to load TZDB time-zone rules: " + url, ex);
}
return updated;
}
/**
* Loads the rules from a URL, often in a jar file.
*
* @param url the jar file to load, not null
* @return true if updated
* @throws ClassNotFoundException if a classpath error occurs
* @throws IOException if an IO error occurs
* @throws ZoneRulesException if the data is already loaded for the version
*/
private boolean load(URL url) throws ClassNotFoundException, IOException, ZoneRulesException {
boolean updated = false;
if (loadedUrls.add(url.toExternalForm())) {
InputStream in = null;
try {
in = url.openStream();
updated |= load(in);
} finally {
if (in != null) {
in.close();
}
}
}
return updated;
}
/**
* Loads the rules from an input stream.
*
* @param in the stream to load, not null, not closed after use
* @throws Exception if an error occurs
*/
private boolean load(InputStream in) throws IOException, StreamCorruptedException {
boolean updated = false;
Iterable<Version> loadedVersions = loadData(in);
for (Version loadedVersion : loadedVersions) {
// see https://github.com/ThreeTen/threetenbp/pull/28 for issue wrt
// multiple versions of lib on classpath
Version existing = versions.putIfAbsent(loadedVersion.versionId, loadedVersion);
if (existing != null && !existing.versionId.equals(loadedVersion.versionId)) {
throw new ZoneRulesException("Data already loaded for TZDB time-zone rules version: " + loadedVersion.versionId);
}
updated = true;
}
return updated;
}
/**
* Loads the rules from an input stream.
*
* @param in the stream to load, not null, not closed after use
* @throws Exception if an error occurs
*/
private Iterable<Version> loadData(InputStream in) throws IOException, StreamCorruptedException {
DataInputStream dis = new DataInputStream(in);
if (dis.readByte() != 1) {
throw new StreamCorruptedException("File format not recognised");
}
// group
String groupId = dis.readUTF();
if ("TZDB".equals(groupId) == false) {
throw new StreamCorruptedException("File format not recognised");
}
// versions
int versionCount = dis.readShort();
String[] versionArray = new String[versionCount];
for (int i = 0; i < versionCount; i++) {
versionArray[i] = dis.readUTF();
}
// regions
int regionCount = dis.readShort();
String[] regionArray = new String[regionCount];
for (int i = 0; i < regionCount; i++) {
regionArray[i] = dis.readUTF();
}
regionIds = Arrays.asList(regionArray);
// rules
int ruleCount = dis.readShort();
Object[] ruleArray = new Object[ruleCount];
for (int i = 0; i < ruleCount; i++) {
byte[] bytes = new byte[dis.readShort()];
dis.readFully(bytes);
ruleArray[i] = bytes;
}
AtomicReferenceArray<Object> ruleData = new AtomicReferenceArray<Object>(ruleArray);
// link version-region-rules
Set<Version> versionSet = new HashSet<Version>(versionCount);
for (int i = 0; i < versionCount; i++) {
int versionRegionCount = dis.readShort();
String[] versionRegionArray = new String[versionRegionCount];
short[] versionRulesArray = new short[versionRegionCount];
for (int j = 0; j < versionRegionCount; j++) {
versionRegionArray[j] = regionArray[dis.readShort()];
versionRulesArray[j] = dis.readShort();
}
versionSet.add(new Version(versionArray[i], versionRegionArray, versionRulesArray, ruleData));
}
return versionSet;
}
@Override
public String toString() {
return "TZDB";
}
//-----------------------------------------------------------------------
/**
* A version of the TZDB rules.
*/
static class Version {
private final String versionId;
private final String[] regionArray;
private final short[] ruleIndices;
private final AtomicReferenceArray<Object> ruleData;
Version(String versionId, String[] regionIds, short[] ruleIndices, AtomicReferenceArray<Object> ruleData) {
this.ruleData = ruleData;
this.versionId = versionId;
this.regionArray = regionIds;
this.ruleIndices = ruleIndices;
}
ZoneRules getRules(String regionId) {
int regionIndex = Arrays.binarySearch(regionArray, regionId);
if (regionIndex < 0) {
return null;
}
try {
return createRule(ruleIndices[regionIndex]);
} catch (Exception ex) {
throw new ZoneRulesException("Invalid binary time-zone data: TZDB:" + regionId + ", version: " + versionId, ex);
}
}
ZoneRules createRule(short index) throws Exception {
Object obj = ruleData.get(index);
if (obj instanceof byte[]) {
byte[] bytes = (byte[]) obj;
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
obj = null; //Ser.read(dis);
ruleData.set(index, obj);
}
return (ZoneRules) obj;
}
@Override
public String toString() {
return versionId;
}
}
}

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -36,7 +51,6 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Duration; import org.threeten.bp.Duration;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime; import org.threeten.bp.LocalDateTime;
@ -315,8 +329,8 @@ public final class ZoneOffsetTransition
} }
if (other instanceof ZoneOffsetTransition) { if (other instanceof ZoneOffsetTransition) {
ZoneOffsetTransition d = (ZoneOffsetTransition) other; ZoneOffsetTransition d = (ZoneOffsetTransition) other;
return transition.equals(d.transition) && return transition.equals(d.transition)
offsetBefore.equals(d.offsetBefore) && offsetAfter.equals(d.offsetAfter); && offsetBefore.equals(d.offsetBefore) && offsetAfter.equals(d.offsetAfter);
} }
return false; return false;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -33,9 +48,7 @@ package org.threeten.bp.zone;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import static org.threeten.bp.temporal.TemporalAdjusters.previousOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.previousOrSame;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -150,12 +163,14 @@ public final class ZoneOffsetTransitionRule implements Serializable {
Objects.requireNonNull(offsetBefore, "offsetBefore"); Objects.requireNonNull(offsetBefore, "offsetBefore");
Objects.requireNonNull(offsetAfter, "offsetAfter"); Objects.requireNonNull(offsetAfter, "offsetAfter");
if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) { if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) {
throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); throw new IllegalArgumentException("Day of month indicator must be between -28 and 31"
+ " inclusive excluding zero");
} }
if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { if (timeEndOfDay && !time.equals(LocalTime.MIDNIGHT)) {
throw new IllegalArgumentException("Time must be midnight when end of day flag is true"); throw new IllegalArgumentException("Time must be midnight when end of day flag is true");
} }
return new ZoneOffsetTransitionRule(month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay ? 1 : 0, timeDefnition, standardOffset, offsetBefore, offsetAfter); return new ZoneOffsetTransitionRule(month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay ? 1 : 0,
timeDefnition, standardOffset, offsetBefore, offsetAfter);
} }
/** /**
@ -354,13 +369,13 @@ public final class ZoneOffsetTransitionRule implements Serializable {
} }
if (otherRule instanceof ZoneOffsetTransitionRule) { if (otherRule instanceof ZoneOffsetTransitionRule) {
ZoneOffsetTransitionRule other = (ZoneOffsetTransitionRule) otherRule; ZoneOffsetTransitionRule other = (ZoneOffsetTransitionRule) otherRule;
return month == other.month && dom == other.dom && dow == other.dow && return month == other.month && dom == other.dom && dow == other.dow
timeDefinition == other.timeDefinition && && timeDefinition == other.timeDefinition
adjustDays == other.adjustDays && && adjustDays == other.adjustDays
time.equals(other.time) && && time.equals(other.time)
standardOffset.equals(other.standardOffset) && && standardOffset.equals(other.standardOffset)
offsetBefore.equals(other.offsetBefore) && && offsetBefore.equals(other.offsetBefore)
offsetAfter.equals(other.offsetAfter); && offsetAfter.equals(other.offsetAfter);
} }
return false; return false;
} }
@ -372,11 +387,10 @@ public final class ZoneOffsetTransitionRule implements Serializable {
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
int hash = ((time.toSecondOfDay() + adjustDays) << 15) + int hash = ((time.toSecondOfDay() + adjustDays) << 15)
(month.ordinal() << 11) + ((dom + 32) << 5) + + (month.ordinal() << 11) + ((dom + 32) << 5)
((dow == null ? 7 : dow.ordinal()) << 2) + (timeDefinition.ordinal()); + ((dow == null ? 7 : dow.ordinal()) << 2) + (timeDefinition.ordinal());
return hash ^ standardOffset.hashCode() ^ return hash ^ standardOffset.hashCode() ^ offsetBefore.hashCode() ^ offsetAfter.hashCode();
offsetBefore.hashCode() ^ offsetAfter.hashCode();
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -395,7 +409,8 @@ public final class ZoneOffsetTransitionRule implements Serializable {
if (dom == -1) { if (dom == -1) {
buf.append(dow.name()).append(" on or before last day of ").append(month.name()); buf.append(dow.name()).append(" on or before last day of ").append(month.name());
} else if (dom < 0) { } else if (dom < 0) {
buf.append(dow.name()).append(" on or before last day minus ").append(-dom - 1).append(" of ").append(month.name()); buf.append(dow.name()).append(" on or before last day minus ").append(-dom - 1)
.append(" of ").append(month.name());
} else { } else {
buf.append(dow.name()).append(" on or after ").append(month.name()).append(' ').append(dom); buf.append(dow.name()).append(" on or after ").append(month.name()).append(' ').append(dom);
} }
@ -436,7 +451,7 @@ public final class ZoneOffsetTransitionRule implements Serializable {
* <li>Relative to the wall offset (what you would see on a clock on the wall)</li> * <li>Relative to the wall offset (what you would see on a clock on the wall)</li>
* </ul><p> * </ul><p>
*/ */
public static enum TimeDefinition { public enum TimeDefinition {
/** The local date-time is expressed in terms of the UTC offset. */ /** The local date-time is expressed in terms of the UTC offset. */
UTC, UTC,
/** The local date-time is expressed in terms of the wall offset. */ /** The local date-time is expressed in terms of the wall offset. */

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -35,7 +50,6 @@ import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.Duration; import org.threeten.bp.Duration;
import org.threeten.bp.Instant; import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime; import org.threeten.bp.LocalDateTime;
@ -498,11 +512,7 @@ public abstract class ZoneRules {
@Override @Override
public int hashCode() { public int hashCode() {
return 1 ^ return 31 + offset.hashCode();
(31 + offset.hashCode()) ^
1 ^
(31 + offset.hashCode()) ^
1;
} }
@Override @Override

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -34,14 +49,12 @@ package org.threeten.bp.zone;
import static org.threeten.bp.temporal.ChronoField.YEAR; import static org.threeten.bp.temporal.ChronoField.YEAR;
import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.nextOrSame;
import static org.threeten.bp.temporal.TemporalAdjusters.previousOrSame; import static org.threeten.bp.temporal.TemporalAdjusters.previousOrSame;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.DayOfWeek; import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
@ -227,7 +240,8 @@ class ZoneRulesBuilder {
boolean timeEndOfDay, boolean timeEndOfDay,
TimeDefinition timeDefinition, TimeDefinition timeDefinition,
int savingAmountSecs) { int savingAmountSecs) {
return addRuleToWindow(year, year, month, dayOfMonthIndicator, null, time, timeEndOfDay, timeDefinition, savingAmountSecs); return addRuleToWindow(year, year, month, dayOfMonthIndicator, null, time, timeEndOfDay,
timeDefinition, savingAmountSecs);
} }
/** /**
@ -270,16 +284,18 @@ class ZoneRulesBuilder {
YEAR.checkValidValue(startYear); YEAR.checkValidValue(startYear);
YEAR.checkValidValue(endYear); YEAR.checkValidValue(endYear);
if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) { if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) {
throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 "
+ "inclusive excluding zero");
} }
if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { if (timeEndOfDay && !time.equals(LocalTime.MIDNIGHT)) {
throw new IllegalArgumentException("Time must be midnight when end of day flag is true"); throw new IllegalArgumentException("Time must be midnight when end of day flag is true");
} }
if (windowList.isEmpty()) { if (windowList.isEmpty()) {
throw new IllegalStateException("Must add a window before adding a rule"); throw new IllegalStateException("Must add a window before adding a rule");
} }
TZWindow window = windowList.get(windowList.size() - 1); TZWindow window = windowList.get(windowList.size() - 1);
window.addRule(startYear, endYear, month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay ? 1 : 0, timeDefinition, savingAmountSecs); window.addRule(startYear, endYear, month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay ? 1 : 0,
timeDefinition, savingAmountSecs);
return this; return this;
} }
@ -298,13 +314,15 @@ class ZoneRulesBuilder {
YEAR.checkValidValue(startYear); YEAR.checkValidValue(startYear);
YEAR.checkValidValue(endYear); YEAR.checkValidValue(endYear);
if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) { if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) {
throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 "
+ "inclusive excluding zero");
} }
if (windowList.isEmpty()) { if (windowList.isEmpty()) {
throw new IllegalStateException("Must add a window before adding a rule"); throw new IllegalStateException("Must add a window before adding a rule");
} }
TZWindow window = windowList.get(windowList.size() - 1); TZWindow window = windowList.get(windowList.size() - 1);
window.addRule(startYear, endYear, month, dayOfMonthIndicator, dayOfWeek, time, adjustDays, timeDefinition, savingAmountSecs); window.addRule(startYear, endYear, month, dayOfMonthIndicator, dayOfWeek, time, adjustDays,
timeDefinition, savingAmountSecs);
return this; return this;
} }
@ -354,7 +372,8 @@ class ZoneRulesBuilder {
if (firstWindow.fixedSavingAmountSecs != null) { if (firstWindow.fixedSavingAmountSecs != null) {
loopSavings = firstWindow.fixedSavingAmountSecs; loopSavings = firstWindow.fixedSavingAmountSecs;
} }
final ZoneOffset firstWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + loopSavings)); final ZoneOffset firstWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(
loopStandardOffset.getTotalSeconds() + loopSavings));
LocalDateTime loopWindowStart = deduplicate(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0)); LocalDateTime loopWindowStart = deduplicate(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0));
ZoneOffset loopWindowOffset = firstWallOffset; ZoneOffset loopWindowOffset = firstWallOffset;
@ -382,17 +401,19 @@ class ZoneRulesBuilder {
} }
// check if standard offset changed, and update it // check if standard offset changed, and update it
if (loopStandardOffset.equals(window.standardOffset) == false) { if (!loopStandardOffset.equals(window.standardOffset)) {
standardTransitionList.add(deduplicate( standardTransitionList.add(deduplicate(
new ZoneOffsetTransition( new ZoneOffsetTransition(
LocalDateTime.ofEpochSecond(loopWindowStart.toEpochSecond(loopWindowOffset), 0, loopStandardOffset), LocalDateTime.ofEpochSecond(loopWindowStart.toEpochSecond(loopWindowOffset), 0,
loopStandardOffset),
loopStandardOffset, window.standardOffset))); loopStandardOffset, window.standardOffset)));
loopStandardOffset = deduplicate(window.standardOffset); loopStandardOffset = deduplicate(window.standardOffset);
} }
// check if the start of the window represents a transition // check if the start of the window represents a transition
ZoneOffset effectiveWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + effectiveSavings)); ZoneOffset effectiveWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(
if (loopWindowOffset.equals(effectiveWallOffset) == false) { loopStandardOffset.getTotalSeconds() + effectiveSavings));
if (!loopWindowOffset.equals(effectiveWallOffset)) {
ZoneOffsetTransition trans = deduplicate( ZoneOffsetTransition trans = deduplicate(
new ZoneOffsetTransition(loopWindowStart, loopWindowOffset, effectiveWallOffset)); new ZoneOffsetTransition(loopWindowStart, loopWindowOffset, effectiveWallOffset));
transitionList.add(trans); transitionList.add(trans);
@ -402,9 +423,9 @@ class ZoneRulesBuilder {
// apply rules within the window // apply rules within the window
for (TZRule rule : window.ruleList) { for (TZRule rule : window.ruleList) {
ZoneOffsetTransition trans = deduplicate(rule.toTransition(loopStandardOffset, loopSavings)); ZoneOffsetTransition trans = deduplicate(rule.toTransition(loopStandardOffset, loopSavings));
if (trans.toEpochSecond() < loopWindowStart.toEpochSecond(loopWindowOffset) == false && if (trans.toEpochSecond() >= loopWindowStart.toEpochSecond(loopWindowOffset)
trans.toEpochSecond() < window.createDateTimeEpochSecond(loopSavings) && && trans.toEpochSecond() < window.createDateTimeEpochSecond(loopSavings)
trans.getOffsetBefore().equals(trans.getOffsetAfter()) == false) { && !trans.getOffsetBefore().equals(trans.getOffsetAfter())) {
transitionList.add(trans); transitionList.add(trans);
loopSavings = rule.savingAmountSecs; loopSavings = rule.savingAmountSecs;
} }
@ -412,7 +433,8 @@ class ZoneRulesBuilder {
// calculate last rules // calculate last rules
for (TZRule lastRule : window.lastRuleList) { for (TZRule lastRule : window.lastRuleList) {
ZoneOffsetTransitionRule transitionRule = deduplicate(lastRule.toTransitionRule(loopStandardOffset, loopSavings)); ZoneOffsetTransitionRule transitionRule = deduplicate(lastRule.toTransitionRule(loopStandardOffset,
loopSavings));
lastTransitionRuleList.add(transitionRule); lastTransitionRuleList.add(transitionRule);
loopSavings = lastRule.savingAmountSecs; loopSavings = lastRule.savingAmountSecs;
} }
@ -436,7 +458,7 @@ class ZoneRulesBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
<T> T deduplicate(T object) { <T> T deduplicate(T object) {
if (deduplicateMap.containsKey(object) == false) { if (!deduplicateMap.containsKey(object)) {
deduplicateMap.put(object, object); deduplicateMap.put(object, object);
} }
return (T) deduplicateMap.get(object); return (T) deduplicateMap.get(object);
@ -535,7 +557,8 @@ class ZoneRulesBuilder {
} }
int year = startYear; int year = startYear;
while (year <= endYear) { while (year <= endYear) {
TZRule rule = new TZRule(year, month, dayOfMonthIndicator, dayOfWeek, time, adjustDays, timeDefinition, savingAmountSecs); TZRule rule = new TZRule(year, month, dayOfMonthIndicator, dayOfWeek, time, adjustDays,
timeDefinition, savingAmountSecs);
if (lastRule) { if (lastRule) {
lastRuleList.add(rule); lastRuleList.add(rule);
maxLastRuleStartYear = Math.max(startYear, maxLastRuleStartYear); maxLastRuleStartYear = Math.max(startYear, maxLastRuleStartYear);
@ -554,8 +577,8 @@ class ZoneRulesBuilder {
*/ */
void validateWindowOrder(TZWindow previous) { void validateWindowOrder(TZWindow previous) {
if (windowEnd.isBefore(previous.windowEnd)) { if (windowEnd.isBefore(previous.windowEnd)) {
throw new IllegalStateException("Windows must be added in date-time order: " + throw new IllegalStateException("Windows must be added in date-time order: "
windowEnd + " < " + previous.windowEnd); + windowEnd + " < " + previous.windowEnd);
} }
} }
@ -577,7 +600,8 @@ class ZoneRulesBuilder {
maxLastRuleStartYear = Math.max(maxLastRuleStartYear, windowStartYear) + 1; maxLastRuleStartYear = Math.max(maxLastRuleStartYear, windowStartYear) + 1;
for (TZRule lastRule : lastRuleList) { for (TZRule lastRule : lastRuleList) {
addRule(lastRule.year, maxLastRuleStartYear, lastRule.month, lastRule.dayOfMonthIndicator, addRule(lastRule.year, maxLastRuleStartYear, lastRule.month, lastRule.dayOfMonthIndicator,
lastRule.dayOfWeek, lastRule.time, lastRule.adjustDays, lastRule.timeDefinition, lastRule.savingAmountSecs); lastRule.dayOfWeek, lastRule.time, lastRule.adjustDays, lastRule.timeDefinition,
lastRule.savingAmountSecs);
lastRule.year = maxLastRuleStartYear + 1; lastRule.year = maxLastRuleStartYear + 1;
} }
if (maxLastRuleStartYear == Year.MAX_VALUE) { if (maxLastRuleStartYear == Year.MAX_VALUE) {
@ -590,7 +614,8 @@ class ZoneRulesBuilder {
int endYear = windowEnd.getYear(); int endYear = windowEnd.getYear();
for (TZRule lastRule : lastRuleList) { for (TZRule lastRule : lastRuleList) {
addRule(lastRule.year, endYear + 1, lastRule.month, lastRule.dayOfMonthIndicator, addRule(lastRule.year, endYear + 1, lastRule.month, lastRule.dayOfMonthIndicator,
lastRule.dayOfWeek, lastRule.time, lastRule.adjustDays, lastRule.timeDefinition, lastRule.savingAmountSecs); lastRule.dayOfWeek, lastRule.time, lastRule.adjustDays, lastRule.timeDefinition,
lastRule.savingAmountSecs);
} }
lastRuleList.clear(); lastRuleList.clear();
maxLastRuleStartYear = Year.MAX_VALUE; maxLastRuleStartYear = Year.MAX_VALUE;
@ -612,8 +637,8 @@ class ZoneRulesBuilder {
* @return true if the window is only a standard offset * @return true if the window is only a standard offset
*/ */
boolean isSingleWindowStandardOffset() { boolean isSingleWindowStandardOffset() {
return windowEnd.equals(LocalDateTime.MAX) && timeDefinition == TimeDefinition.WALL && return windowEnd.equals(LocalDateTime.MAX) && timeDefinition == TimeDefinition.WALL
fixedSavingAmountSecs == null && lastRuleList.isEmpty() && ruleList.isEmpty(); && fixedSavingAmountSecs == null && lastRuleList.isEmpty() && ruleList.isEmpty();
} }
/** /**
@ -682,8 +707,8 @@ class ZoneRulesBuilder {
this.month = month; this.month = month;
this.dayOfMonthIndicator = dayOfMonthIndicator; this.dayOfMonthIndicator = dayOfMonthIndicator;
this.dayOfWeek = dayOfWeek; this.dayOfWeek = dayOfWeek;
this.time= time; this.time = time;
this.adjustDays= adjustDays; this.adjustDays = adjustDays;
this.timeDefinition = timeDefinition; this.timeDefinition = timeDefinition;
this.savingAmountSecs = savingAfterSecs; this.savingAmountSecs = savingAfterSecs;
} }
@ -700,9 +725,11 @@ class ZoneRulesBuilder {
LocalDate date = toLocalDate(); LocalDate date = toLocalDate();
date = deduplicate(date); date = deduplicate(date);
LocalDateTime ldt = deduplicate(LocalDateTime.of(date.plusDays(adjustDays), time)); LocalDateTime ldt = deduplicate(LocalDateTime.of(date.plusDays(adjustDays), time));
ZoneOffset wallOffset = deduplicate(ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingsBeforeSecs)); ZoneOffset wallOffset = deduplicate(ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds()
+ savingsBeforeSecs));
LocalDateTime dt = deduplicate(timeDefinition.createDateTime(ldt, standardOffset, wallOffset)); LocalDateTime dt = deduplicate(timeDefinition.createDateTime(ldt, standardOffset, wallOffset));
ZoneOffset offsetAfter = deduplicate(ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingAmountSecs)); ZoneOffset offsetAfter = deduplicate(ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds()
+ savingAmountSecs));
return new ZoneOffsetTransition(dt, wallOffset, offsetAfter); return new ZoneOffsetTransition(dt, wallOffset, offsetAfter);
} }
@ -728,9 +755,10 @@ class ZoneRulesBuilder {
standardOffset, trans.getOffsetBefore(), trans.getOffsetAfter()); standardOffset, trans.getOffsetBefore(), trans.getOffsetAfter());
} }
@Override
public int compareTo(TZRule other) { public int compareTo(TZRule other) {
int cmp = year - other.year; int cmp = year - other.year;
cmp = (cmp == 0 ? month.compareTo(other.month) : cmp); cmp = cmp == 0 ? month.compareTo(other.month) : cmp;
if (cmp == 0) { if (cmp == 0) {
// convert to date to handle dow/domIndicator/timeEndOfDay // convert to date to handle dow/domIndicator/timeEndOfDay
LocalDate thisDate = toLocalDate(); LocalDate thisDate = toLocalDate();

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *

View File

@ -1,3 +1,18 @@
/*
* Copyright 2020 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* /*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* *
@ -39,7 +54,6 @@ import java.util.Map;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.threeten.bp.DateTimeException; import org.threeten.bp.DateTimeException;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
import org.threeten.bp.ZonedDateTime; import org.threeten.bp.ZonedDateTime;
@ -205,8 +219,8 @@ public abstract class ZoneRulesProvider {
ZoneRulesProvider old = ZONES.putIfAbsent(zoneId, provider); ZoneRulesProvider old = ZONES.putIfAbsent(zoneId, provider);
if (old != null) { if (old != null) {
throw new ZoneRulesException( throw new ZoneRulesException(
"Unable to register zone as one already registered with that ID: " + zoneId + "Unable to register zone as one already registered with that ID: " + zoneId
", currently loading from provider: " + provider); + ", currently loading from provider: " + provider);
} }
} }
} }

View File

@ -55,8 +55,7 @@ import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit; import java.time.temporal.TemporalUnit;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import org.threeten.bp.jdk8.Jdk8Methods;
/** /**
* Mock period of time measured using a single unit, such as {@code 3 Days}. * Mock period of time measured using a single unit, such as {@code 3 Days}.
@ -97,7 +96,7 @@ public final class MockSimplePeriod
} }
private MockSimplePeriod(long amount, TemporalUnit unit) { private MockSimplePeriod(long amount, TemporalUnit unit) {
Jdk8Methods.requireNonNull(unit, "unit"); Objects.requireNonNull(unit, "unit");
if (unit == FOREVER) { if (unit == FOREVER) {
throw new DateTimeException("Cannot create a period of the Forever unit"); throw new DateTimeException("Cannot create a period of the Forever unit");
} }
@ -145,7 +144,7 @@ public final class MockSimplePeriod
if (!unit.equals(otherPeriod.getUnit())) { if (!unit.equals(otherPeriod.getUnit())) {
throw new IllegalArgumentException("Units cannot be compared: " + unit + " and " + otherPeriod.getUnit()); throw new IllegalArgumentException("Units cannot be compared: " + unit + " and " + otherPeriod.getUnit());
} }
return Jdk8Methods.compareLongs(amount, otherPeriod.amount); return Long.compare(amount, otherPeriod.amount);
} }
@Override @Override

View File

@ -375,7 +375,7 @@ public class TestDateTimesImplementation {
int a = values[i]; int a = values[i];
for (int j = 0; j < values.length; j++) { for (int j = 0; j < values.length; j++) {
int b = values[j]; int b = values[j];
assertEquals(Jdk8Methods.compareInts(a, b), a < b ? -1 : (a > b ? 1 : 0), a + " <=> " + b); assertEquals(Integer.compare(a, b), a < b ? -1 : (a > b ? 1 : 0), a + " <=> " + b);
} }
} }
} }
@ -407,7 +407,7 @@ public class TestDateTimesImplementation {
long a = values[i]; long a = values[i];
for (int j = 0; j < values.length; j++) { for (int j = 0; j < values.length; j++) {
long b = values[j]; long b = values[j];
assertEquals(Jdk8Methods.compareLongs(a, b), a < b ? -1 : (a > b ? 1 : 0), a + " <=> " + b); assertEquals(Long.compare(a, b), a < b ? -1 : (a > b ? 1 : 0), a + " <=> " + b);
} }
} }
} }

View File

@ -50,7 +50,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.time.DateTimeException; import java.time.DateTimeException;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -58,23 +57,22 @@ import java.time.LocalTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.TextStyle;
import java.time.temporal.TemporalAccessor;
import java.time.zone.ZoneOffsetTransition;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import java.util.TimeZone; import java.util.TimeZone;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.teavm.junit.TeaVMTestRunner; import org.teavm.junit.TeaVMTestRunner;
import org.teavm.junit.WholeClassCompilation; import org.teavm.junit.WholeClassCompilation;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.time.format.TextStyle;
import java.time.temporal.TemporalAccessor;
import java.time.zone.ZoneOffsetTransition;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesException;
/** /**
* Test ZoneId. * Test ZoneId.
@ -249,15 +247,15 @@ public class TestZoneId extends AbstractTest {
{"+0", ""}, {"+0", ""},
{"+5", "+05:00"}, {"+5", "+05:00"},
{"+01", "+01:00"}, {"+01", "+01:00"},
{"+0100", "+01:00"},{"+01:00", "+01:00"}, {"+0100", "+01:00"}, {"+01:00", "+01:00"},
{"+010000", "+01:00"},{"+01:00:00", "+01:00"}, {"+010000", "+01:00"}, {"+01:00:00", "+01:00"},
{"+12", "+12:00"}, {"+12", "+12:00"},
{"+1234", "+12:34"},{"+12:34", "+12:34"}, {"+1234", "+12:34"}, {"+12:34", "+12:34"},
{"+123456", "+12:34:56"},{"+12:34:56", "+12:34:56"}, {"+123456", "+12:34:56"}, { "+12:34:56", "+12:34:56"},
{"-02", "-02:00"}, {"-02", "-02:00"},
{"-5", "-05:00"}, {"-5", "-05:00"},
{"-0200", "-02:00"},{"-02:00", "-02:00"}, {"-0200", "-02:00"}, {"-02:00", "-02:00"},
{"-020000", "-02:00"},{"-02:00:00", "-02:00"}, {"-020000", "-02:00"}, {"-02:00:00", "-02:00"},
}; };
} }
@ -447,8 +445,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
// cutover at 01:00Z // cutover at 01:00Z
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(0)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)),
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); ZoneOffset.ofHours(0));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)),
ZoneOffset.ofHours(1));
} }
public void test_London_getOffset_fromDST() { public void test_London_getOffset_fromDST() {
@ -462,8 +462,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(0)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
// cutover at 01:00Z // cutover at 01:00Z
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)),
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(0)); ZoneOffset.ofHours(1));
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)),
ZoneOffset.ofHours(0));
} }
public void test_London_getOffsetInfo() { public void test_London_getOffsetInfo() {
@ -602,8 +604,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(2)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
// cutover at 01:00Z // cutover at 01:00Z
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)),
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(2)); ZoneOffset.ofHours(1));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)),
ZoneOffset.ofHours(2));
} }
public void test_Paris_getOffset_fromDST() { public void test_Paris_getOffset_fromDST() {
@ -617,8 +621,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
// cutover at 01:00Z // cutover at 01:00Z
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(2)); assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)),
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1)); ZoneOffset.ofHours(2));
assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)),
ZoneOffset.ofHours(1));
} }
public void test_Paris_getOffsetInfo() { public void test_Paris_getOffsetInfo() {
@ -766,8 +772,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4));
// cutover at 02:00 local // cutover at 02:00 local
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5)); assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)),
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4)); ZoneOffset.ofHours(-5));
assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)),
ZoneOffset.ofHours(-4));
} }
public void test_NewYork_getOffset_fromDST() { public void test_NewYork_getOffset_fromDST() {
@ -781,8 +789,10 @@ public class TestZoneId extends AbstractTest {
assertEquals(test.getRules().getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5)); assertEquals(test.getRules().getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5));
assertEquals(test.getRules().getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5)); assertEquals(test.getRules().getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5));
// cutover at 02:00 local // cutover at 02:00 local
assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4)); assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)),
assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5)); ZoneOffset.ofHours(-4));
assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)),
ZoneOffset.ofHours(-5));
} }
public void test_NewYork_getOffsetInfo() { public void test_NewYork_getOffsetInfo() {

View File

@ -65,9 +65,7 @@ import static org.threeten.bp.Month.SEPTEMBER;
import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.STANDARD; import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.STANDARD;
import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.UTC; import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.UTC;
import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.WALL; import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.WALL;
import java.util.List; import java.util.List;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.teavm.junit.TeaVMTestRunner; import org.teavm.junit.TeaVMTestRunner;
import org.teavm.junit.WholeClassCompilation; import org.teavm.junit.WholeClassCompilation;
@ -103,13 +101,13 @@ public class TestZoneRulesBuilder {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// toRules() // toRules()
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_toRules_noWindows() { public void test_toRules_noWindows() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.toRules("Europe/London"); b.toRules("Europe/London");
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_toRules_null() { public void test_toRules_null() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_2_30); b.addWindowForever(OFFSET_2_30);
@ -369,7 +367,8 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, DATE_TIME_LAST, plus2); assertOffsetInfo(test, DATE_TIME_LAST, plus2);
assertGap(test, 2010, 9, 10, 12, 0, plus2, plus3); // jump forward from 12:00 to 13:00 on Tue 10th Sep assertGap(test, 2010, 9, 10, 12, 0, plus2, plus3); // jump forward from 12:00 to 13:00 on Tue 10th Sep
assertOverlap(test, 2010, 9, 10, 23, 0, plus3, plus2); // overlaps from Wed 11th Sep 00:00 back to Tue 10th Sep 23:00 // overlaps from Wed 11th Sep 00:00 back to Tue 10th Sep 23:00
assertOverlap(test, 2010, 9, 10, 23, 0, plus3, plus2);
} }
@Test @Test
@ -387,7 +386,8 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, DATE_TIME_LAST, plus2); assertOffsetInfo(test, DATE_TIME_LAST, plus2);
assertGap(test, 2010, 9, 28, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Tue 28th Sep assertGap(test, 2010, 9, 28, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Tue 28th Sep
assertOverlap(test, 2010, 9, 29, 23, 0, plus3, plus2); // overlaps from Thu 30th Sep 00:00 back to Wed 29th Sep 23:00 // overlaps from Thu 30th Sep 00:00 back to Wed 29th Sep 23:00
assertOverlap(test, 2010, 9, 29, 23, 0, plus3, plus2);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -475,7 +475,8 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, DATE_TIME_LAST, plus2); assertOffsetInfo(test, DATE_TIME_LAST, plus2);
assertGap(test, 2010, 9, 10, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Fri 10th Sep assertGap(test, 2010, 9, 10, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Fri 10th Sep
assertOverlap(test, 2010, 9, 30, 23, 0, plus3, plus2); // overlaps from Fri 1st Oct 00:00 back to Thu 30th Sep 23:00 (!!!) // overlaps from Fri 1st Oct 00:00 back to Thu 30th Sep 23:00 (!!!)
assertOverlap(test, 2010, 9, 30, 23, 0, plus3, plus2);
} }
@Test @Test
@ -748,19 +749,19 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_1); assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_1);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addWindow_nullOffset() { public void test_addWindow_nullOffset() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindow((ZoneOffset) null, dateTime(2008, 6, 30, 0, 0), STANDARD); b.addWindow((ZoneOffset) null, dateTime(2008, 6, 30, 0, 0), STANDARD);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addWindow_nullTime() { public void test_addWindow_nullTime() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindow(OFFSET_1, (LocalDateTime) null, STANDARD); b.addWindow(OFFSET_1, (LocalDateTime) null, STANDARD);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addWindow_nullTimeDefinition() { public void test_addWindow_nullTimeDefinition() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindow(OFFSET_1, dateTime(2008, 6, 30, 0, 0), (TimeDefinition) null); b.addWindow(OFFSET_1, dateTime(2008, 6, 30, 0, 0), (TimeDefinition) null);
@ -795,7 +796,7 @@ public class TestZoneRulesBuilder {
assertOverlap(test, 2008, 10, 26, 0, 20, OFFSET_2_30, OFFSET_1); assertOverlap(test, 2008, 10, 26, 0, 20, OFFSET_2_30, OFFSET_1);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addWindowForever_nullOffset() { public void test_addWindowForever_nullOffset() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever((ZoneOffset) null); b.addWindowForever((ZoneOffset) null);
@ -828,13 +829,13 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2_30); assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2_30);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_setFixedSavingsToWindow_noWindow() { public void test_setFixedSavingsToWindow_noWindow() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_setFixedSavingsToWindow_cannotMixSavingsWithRule() { public void test_setFixedSavingsToWindow_cannotMixSavingsWithRule() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -842,7 +843,7 @@ public class TestZoneRulesBuilder {
b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_setFixedSavingsToWindow_cannotMixSavingsWithLastRule() { public void test_setFixedSavingsToWindow_cannotMixSavingsWithLastRule() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -919,13 +920,13 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, dateTime(2002, 7, 1, 0, 0), OFFSET_1); assertOffsetInfo(test, dateTime(2002, 7, 1, 0, 0), OFFSET_1);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_addRuleToWindow_noWindow() { public void test_addRuleToWindow_noWindow() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_addRuleToWindow_cannotMixRuleWithSavings() { public void test_addRuleToWindow_cannotMixRuleWithSavings() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -933,67 +934,68 @@ public class TestZoneRulesBuilder {
b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=DateTimeException.class) @Test(expectedExceptions = DateTimeException.class)
public void test_addRuleToWindow_illegalYear1() { public void test_addRuleToWindow_illegalYear1() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(Year.MIN_VALUE - 1, 2008, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(Year.MIN_VALUE - 1, 2008, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=DateTimeException.class) @Test(expectedExceptions = DateTimeException.class)
public void test_addRuleToWindow_illegalYear2() { public void test_addRuleToWindow_illegalYear2() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, Year.MIN_VALUE - 1, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MIN_VALUE - 1, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_illegalDayOfMonth_tooSmall() { public void test_addRuleToWindow_illegalDayOfMonth_tooSmall() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, 2008, MARCH, -29, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, 2008, MARCH, -29, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_illegalDayOfMonth_zero() { public void test_addRuleToWindow_illegalDayOfMonth_zero() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, 2008, MARCH, 0, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, 2008, MARCH, 0, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_illegalDayOfMonth_tooLarge() { public void test_addRuleToWindow_illegalDayOfMonth_tooLarge() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, 2008, MARCH, 32, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, 2008, MARCH, 32, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_nullMonth() { public void test_addRuleToWindow_nullMonth() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, Year.MAX_VALUE, (Month) null, 31, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MAX_VALUE, (Month) null, 31, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_nullTime() { public void test_addRuleToWindow_nullTime() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_illegalEndOfDayTime() { public void test_addRuleToWindow_illegalEndOfDayTime() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, 2008, MARCH, 1, SUNDAY, time(1, 0), true, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, 2008, MARCH, 1, SUNDAY, time(1, 0), true, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_nullTimeDefinition() { public void test_addRuleToWindow_nullTimeDefinition() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, (TimeDefinition) null, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, (TimeDefinition) null,
PERIOD_1HOUR30MIN);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -1016,14 +1018,14 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1); assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_singleYearObject_nullTime() { public void test_addRuleToWindow_singleYearObject_nullTime() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow((LocalDateTime) null, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow((LocalDateTime) null, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_singleYearObject_nullTimeDefinition() { public void test_addRuleToWindow_singleYearObject_nullTimeDefinition() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -1050,13 +1052,13 @@ public class TestZoneRulesBuilder {
assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1); assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_addRuleToWindow_singleYear_noWindow() { public void test_addRuleToWindow_singleYear_noWindow() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void test_addRuleToWindow_singleYear_cannotMixRuleWithSavings() { public void test_addRuleToWindow_singleYear_cannotMixRuleWithSavings() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -1064,49 +1066,49 @@ public class TestZoneRulesBuilder {
b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=DateTimeException.class) @Test(expectedExceptions = DateTimeException.class)
public void test_addRuleToWindow_singleYear_illegalYear() { public void test_addRuleToWindow_singleYear_illegalYear() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(Year.MIN_VALUE - 1, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(Year.MIN_VALUE - 1, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooSmall() { public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooSmall() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, MARCH, -29, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, -29, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_singleYear_illegalDayOfMonth_zero() { public void test_addRuleToWindow_singleYear_illegalDayOfMonth_zero() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, MARCH, 0, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, 0, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)
public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooLarge() { public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooLarge() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, MARCH, 32, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, 32, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_singleYear_nullMonth() { public void test_addRuleToWindow_singleYear_nullMonth() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, (Month) null, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, (Month) null, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_singleYear_nullTime() { public void test_addRuleToWindow_singleYear_nullTime() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
b.addRuleToWindow(2000, MARCH, 31, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN); b.addRuleToWindow(2000, MARCH, 31, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN);
} }
@Test(expectedExceptions=NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void test_addRuleToWindow_singleYear_nullTimeDefinition() { public void test_addRuleToWindow_singleYear_nullTimeDefinition() {
ZoneRulesBuilder b = new ZoneRulesBuilder(); ZoneRulesBuilder b = new ZoneRulesBuilder();
b.addWindowForever(OFFSET_1); b.addWindowForever(OFFSET_1);
@ -1114,7 +1116,8 @@ public class TestZoneRulesBuilder {
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
private static void assertGap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after) { private static void assertGap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before,
ZoneOffset after) {
LocalDateTime dt = dateTime(y, m, d, hr, min); LocalDateTime dt = dateTime(y, m, d, hr, min);
ZoneOffsetTransition zot = test.getTransition(dt); ZoneOffsetTransition zot = test.getTransition(dt);
assertNotNull(zot); assertNotNull(zot);
@ -1123,7 +1126,8 @@ public class TestZoneRulesBuilder {
assertEquals(zot.getOffsetAfter(), after); assertEquals(zot.getOffsetAfter(), after);
} }
private static void assertOverlap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after) { private static void assertOverlap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before,
ZoneOffset after) {
LocalDateTime dt = dateTime(y, m, d, hr, min); LocalDateTime dt = dateTime(y, m, d, hr, min);
ZoneOffsetTransition zot = test.getTransition(dt); ZoneOffsetTransition zot = test.getTransition(dt);
assertNotNull(zot); assertNotNull(zot);