Skip to content

Instantly share code, notes, and snippets.

@jodastephen
Created January 31, 2013 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jodastephen/4684361 to your computer and use it in GitHub Desktop.
Save jodastephen/4684361 to your computer and use it in GitHub Desktop.
APPLIED. Patch to ThreeTen for Period/Duration #248
diff --git a/src/share/classes/java/time/Duration.java b/src/share/classes/java/time/Duration.java
--- a/src/share/classes/java/time/Duration.java
+++ b/src/share/classes/java/time/Duration.java
@@ -62,9 +62,13 @@
package java.time;
import static java.time.LocalTime.SECONDS_PER_DAY;
+import static java.time.LocalTime.SECONDS_PER_HOUR;
+import static java.time.LocalTime.SECONDS_PER_MINUTE;
import static java.time.temporal.ChronoField.INSTANT_SECONDS;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.NANOS;
+import static java.time.temporal.ChronoUnit.SECONDS;
import java.io.DataInput;
import java.io.DataOutput;
@@ -76,22 +80,24 @@
import java.math.BigInteger;
import java.math.RoundingMode;
import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
- * A duration between two instants on the time-line.
+ * A time-based amount of time, such as '34.5 seconds'.
* <p>
- * This class models a duration of time and is not tied to any instant.
- * The model is of a directed duration, meaning that the duration may be negative.
+ * This class models a quantity or amount of time in terms of seconds and nanoseconds.
+ * It can be accessed using other duration-based units, such as minutes and hours.
+ * In addition, the {@link ChronoUnit#DAYS DAYS} unit can be used and is treated as
+ * exactly equal to 24 hours, thus ignoring daylight savings effects.
+ * See {@link Period} for the date-based equivalent to this class.
* <p>
* A physical duration could be of infinite length.
* For practicality, the duration is stored with constraints similar to {@link Instant}.
@@ -101,6 +107,7 @@
* The range of a duration requires the storage of a number larger than a {@code long}.
* To achieve this, the class stores a {@code long} representing seconds and an {@code int}
* representing nanosecond-of-second, which will always be between 0 and 999,999,999.
+ * The model is of a directed duration, meaning that the duration may be negative.
* <p>
* The duration is measured in "seconds", but these are not necessarily identical to
* the scientific "SI second" definition based on atomic clocks.
@@ -145,6 +152,52 @@
//-----------------------------------------------------------------------
/**
+ * Obtains an instance of {@code Duration} from a number of standard 24 hour days.
+ * <p>
+ * The seconds are calculated based on the standard definition of a day,
+ * where each day is 86400 seconds which implies a 24 hour day.
+ * The nanosecond in second field is set to zero.
+ *
+ * @param days the number of days, positive or negative
+ * @return a {@code Duration}, not null
+ * @throws ArithmeticException if the input days exceeds the capacity of {@code Duration}
+ */
+ public static Duration ofDays(long days) {
+ return create(Math.multiplyExact(days, SECONDS_PER_DAY), 0);
+ }
+
+ /**
+ * Obtains an instance of {@code Duration} from a number of standard length hours.
+ * <p>
+ * The seconds are calculated based on the standard definition of an hour,
+ * where each hour is 3600 seconds.
+ * The nanosecond in second field is set to zero.
+ *
+ * @param hours the number of hours, positive or negative
+ * @return a {@code Duration}, not null
+ * @throws ArithmeticException if the input hours exceeds the capacity of {@code Duration}
+ */
+ public static Duration ofHours(long hours) {
+ return create(Math.multiplyExact(hours, SECONDS_PER_HOUR), 0);
+ }
+
+ /**
+ * Obtains an instance of {@code Duration} from a number of standard length minutes.
+ * <p>
+ * The seconds are calculated based on the standard definition of a minute,
+ * where each minute is 60 seconds.
+ * The nanosecond in second field is set to zero.
+ *
+ * @param minutes the number of minutes, positive or negative
+ * @return a {@code Duration}, not null
+ * @throws ArithmeticException if the input minutes exceeds the capacity of {@code Duration}
+ */
+ public static Duration ofMinutes(long minutes) {
+ return create(Math.multiplyExact(minutes, SECONDS_PER_MINUTE), 0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
* Obtains an instance of {@code Duration} from a number of seconds.
* <p>
* The nanosecond in second field is set to zero.
@@ -177,7 +230,7 @@
*/
public static Duration ofSeconds(long seconds, long nanoAdjustment) {
long secs = Math.addExact(seconds, Math.floorDiv(nanoAdjustment, NANOS_PER_SECOND));
- int nos = (int)Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
+ int nos = (int) Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
return create(secs, nos);
}
@@ -221,52 +274,6 @@
//-----------------------------------------------------------------------
/**
- * Obtains an instance of {@code Duration} from a number of standard length minutes.
- * <p>
- * The seconds are calculated based on the standard definition of a minute,
- * where each minute is 60 seconds.
- * The nanosecond in second field is set to zero.
- *
- * @param minutes the number of minutes, positive or negative
- * @return a {@code Duration}, not null
- * @throws ArithmeticException if the input minutes exceeds the capacity of {@code Duration}
- */
- public static Duration ofMinutes(long minutes) {
- return create(Math.multiplyExact(minutes, 60), 0);
- }
-
- /**
- * Obtains an instance of {@code Duration} from a number of standard length hours.
- * <p>
- * The seconds are calculated based on the standard definition of an hour,
- * where each hour is 3600 seconds.
- * The nanosecond in second field is set to zero.
- *
- * @param hours the number of hours, positive or negative
- * @return a {@code Duration}, not null
- * @throws ArithmeticException if the input hours exceeds the capacity of {@code Duration}
- */
- public static Duration ofHours(long hours) {
- return create(Math.multiplyExact(hours, 3600), 0);
- }
-
- /**
- * Obtains an instance of {@code Duration} from a number of standard 24 hour days.
- * <p>
- * The seconds are calculated based on the standard definition of a day,
- * where each day is 86400 seconds which implies a 24 hour day.
- * The nanosecond in second field is set to zero.
- *
- * @param days the number of days, positive or negative
- * @return a {@code Duration}, not null
- * @throws ArithmeticException if the input days exceeds the capacity of {@code Duration}
- */
- public static Duration ofDays(long days) {
- return create(Math.multiplyExact(days, 86400), 0);
- }
-
- //-----------------------------------------------------------------------
- /**
* Obtains an instance of {@code Duration} from a duration in the specified unit.
* <p>
* The parameters represent the two parts of a phrase like '6 Hours'. For example:
@@ -290,54 +297,6 @@
//-----------------------------------------------------------------------
/**
- * Gets the value of the seconds or nanos of Duration.
- * @param unit the requested unit either {@code ChronoUnit.SECONDS} or
- * {@code ChronoUnit.NANOS}, not null
- * @return the value of the requested unit
- * @throws DateTimeException if the unit is not {@code ChronoUnit.SECONDS} or
- * {@code ChronoUnit.NANOS}
- */
- @Override
- public long get(TemporalUnit unit) {
- if (unit == ChronoUnit.SECONDS) {
- return seconds;
- } else if (unit == ChronoUnit.NANOS) {
- return nanos;
- } else {
- throw new DateTimeException("Unsupported unit: " + unit.getName());
- }
- }
-
- /**
- * Private class to delay initialization of Duration Units until needed.
- * The circular dependency between Duration and ChronoUnit prevents
- * the simple initialization in Duration.
- */
- private static class DurationUnits {
- private final static List<TemporalUnit> supportedUnits;
- static {
- ArrayList<TemporalUnit> tmp = new ArrayList<>(2);
- tmp.add(ChronoUnit.SECONDS);
- tmp.add(ChronoUnit.NANOS);
- supportedUnits = Collections.unmodifiableList(tmp);
- }
- static List<TemporalUnit> getUnits() {
- return supportedUnits;
- }
- }
-
- /**
- * Gets the set of ChronoUnits supported by {@code Duration}.
- * @return the {@code Set<TemporalUnit>} containing {@code ChronoUnit.SECONDS}
- * and {@code ChronoUnit.NANOS}.
- */
- @Override
- public List<TemporalUnit> getUnits() {
- return DurationUnits.getUnits();
- }
-
- //-----------------------------------------------------------------------
- /**
* Obtains an instance of {@code Duration} representing the duration between two instants.
* <p>
* A {@code Duration} represents a directed distance between two points on the time-line.
@@ -472,6 +431,56 @@
//-----------------------------------------------------------------------
/**
+ * Gets the value of the requested unit.
+ * <p>
+ * This returns a value for each of the two supported units,
+ * {@link ChronoUnit#SECONDS SECONDS} and {@link ChronoUnit#NANOS NANOS}.
+ * All other units throw an exception.
+ *
+ * @param unit the {@code TemporalUnit} for which to return the value
+ * @return the long value of the unit
+ * @throws DateTimeException if the unit is not supported
+ */
+ @Override
+ public long get(TemporalUnit unit) {
+ if (unit == SECONDS) {
+ return seconds;
+ } else if (unit == NANOS) {
+ return nanos;
+ } else {
+ throw new DateTimeException("Unsupported unit: " + unit.getName());
+ }
+ }
+
+ /**
+ * Gets the set of units supported by this duration.
+ * <p>
+ * The supported units are {@link ChronoUnit#SECONDS SECONDS},
+ * and {@link ChronoUnit#NANOS NANOS}.
+ * They are returned in the order seconds, nanos.
+ * <p>
+ * This set can be used in conjunction with {@link #get(TemporalUnit)}
+ * to access the entire state of the period.
+ *
+ * @return a list containing the seconds and nanos units, not null
+ */
+ @Override
+ public List<TemporalUnit> getUnits() {
+ return DurationUnits.UNITS;
+ }
+
+ /**
+ * Private class to delay initialization of this list until needed.
+ * The circular dependency between Duration and ChronoUnit prevents
+ * the simple initialization in Duration.
+ */
+ private static class DurationUnits {
+ final static List<TemporalUnit> UNITS =
+ Collections.unmodifiableList(Arrays.<TemporalUnit>asList(SECONDS, NANOS));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
* Checks if this duration is zero length.
* <p>
* A {@code Duration} represents a directed distance between two points on
@@ -485,19 +494,6 @@
}
/**
- * Checks if this duration is positive, excluding zero.
- * <p>
- * A {@code Duration} represents a directed distance between two points on
- * the time-line and can therefore be positive, zero or negative.
- * This method checks whether the length is greater than zero.
- *
- * @return true if this duration has a total length greater than zero
- */
- public boolean isPositive() {
- return seconds >= 0 && ((seconds | nanos) != 0);
- }
-
- /**
* Checks if this duration is negative, excluding zero.
* <p>
* A {@code Duration} represents a directed distance between two points on
@@ -549,6 +545,39 @@
//-----------------------------------------------------------------------
/**
+ * Returns a copy of this duration with the specified amount of seconds.
+ * <p>
+ * This returns a duration with the specified seconds, retaining the
+ * nano-of-second part of this duration.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param seconds the seconds to represent, may be negative
+ * @return a {@code Duration} based on this period with the requested seconds, not null
+ */
+ public Duration withSeconds(long seconds) {
+ return create(seconds, nanos);
+ }
+
+ /**
+ * Returns a copy of this duration with the specified nano-of-second.
+ * <p>
+ * This returns a duration with the specified nano-of-second, retaining the
+ * seconds part of this duration.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999
+ * @return a {@code Duration} based on this period with the requested nano-of-second, not null
+ * @throws DateTimeException if the nano-of-second is invalid
+ */
+ public Duration withNanos(int nanoOfSecond) {
+ NANO_OF_SECOND.checkValidIntValue(nanoOfSecond);
+ return create(seconds, nanoOfSecond);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
* Returns a copy of this duration with the specified duration added.
* <p>
* This instance is immutable and unaffected by this method call.
@@ -602,6 +631,48 @@
//-----------------------------------------------------------------------
/**
+ * Returns a copy of this duration with the specified duration in standard 24 hour days added.
+ * <p>
+ * The number of days is multiplied by 86400 to obtain the number of seconds to add.
+ * This is based on the standard definition of a day as 24 hours.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param daysToAdd the days to add, positive or negative
+ * @return a {@code Duration} based on this duration with the specified days added, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration plusDays(long daysToAdd) {
+ return plus(Math.multiplyExact(daysToAdd, SECONDS_PER_DAY), 0);
+ }
+
+ /**
+ * Returns a copy of this duration with the specified duration in hours added.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param hoursToAdd the hours to add, positive or negative
+ * @return a {@code Duration} based on this duration with the specified hours added, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration plusHours(long hoursToAdd) {
+ return plus(Math.multiplyExact(hoursToAdd, SECONDS_PER_HOUR), 0);
+ }
+
+ /**
+ * Returns a copy of this duration with the specified duration in minutes added.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param minutesToAdd the minutes to add, positive or negative
+ * @return a {@code Duration} based on this duration with the specified minutes added, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration plusMinutes(long minutesToAdd) {
+ return plus(Math.multiplyExact(minutesToAdd, SECONDS_PER_MINUTE), 0);
+ }
+
+ /**
* Returns a copy of this duration with the specified duration in seconds added.
* <p>
* This instance is immutable and unaffected by this method call.
@@ -701,6 +772,52 @@
//-----------------------------------------------------------------------
/**
+ * Returns a copy of this duration with the specified duration in standard 24 hour days subtracted.
+ * <p>
+ * The number of days is multiplied by 86400 to obtain the number of seconds to subtract.
+ * This is based on the standard definition of a day as 24 hours.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param daysToSubtract the days to subtract, positive or negative
+ * @return a {@code Duration} based on this duration with the specified days subtracted, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration minusDays(long daysToSubtract) {
+ return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
+ }
+
+ /**
+ * Returns a copy of this duration with the specified duration in hours subtracted.
+ * <p>
+ * The number of hours is multiplied by 3600 to obtain the number of seconds to subtract.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param hoursToSubtract the hours to subtract, positive or negative
+ * @return a {@code Duration} based on this duration with the specified hours subtracted, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration minusHours(long hoursToSubtract) {
+ return (hoursToSubtract == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hoursToSubtract));
+ }
+
+ /**
+ * Returns a copy of this duration with the specified duration in minutes subtracted.
+ * <p>
+ * The number of hours is multiplied by 60 to obtain the number of seconds to subtract.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param minutesToSubtract the minutes to subtract, positive or negative
+ * @return a {@code Duration} based on this duration with the specified minutes subtracted, not null
+ * @throws ArithmeticException if numeric overflow occurs
+ */
+ public Duration minusMinutes(long minutesToSubtract) {
+ return (minutesToSubtract == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutesToSubtract));
+ }
+
+ /**
* Returns a copy of this duration with the specified duration in seconds subtracted.
* <p>
* This instance is immutable and unaffected by this method call.
@@ -766,8 +883,7 @@
*
* @param divisor the value to divide the duration by, positive or negative, not zero
* @return a {@code Duration} based on this duration divided by the specified divisor, not null
- * @throws ArithmeticException if the divisor is zero
- * @throws ArithmeticException if numeric overflow occurs
+ * @throws ArithmeticException if the divisor is zero or if numeric overflow occurs
*/
public Duration dividedBy(long divisor) {
if (divisor == 0) {
@@ -851,8 +967,8 @@
* dateTime = dateTime.plus(thisDuration);
* </pre>
* <p>
- * A {@code Duration} can only be added to a {@code Temporal} that
- * represents an instant and can supply {@link ChronoField#INSTANT_SECONDS}.
+ * The calculation will add the seconds, then nanos.
+ * Only non-zero amounts will be added.
* <p>
* This instance is immutable and unaffected by this method call.
*
@@ -863,13 +979,13 @@
*/
@Override
public Temporal addTo(Temporal temporal) {
- long instantSecs = temporal.getLong(INSTANT_SECONDS);
- long instantNanos = temporal.getLong(NANO_OF_SECOND);
- instantSecs = Math.addExact(instantSecs, seconds);
- instantNanos = Math.addExact(instantNanos, nanos);
- instantSecs = Math.addExact(instantSecs, Math.floorDiv(instantNanos, NANOS_PER_SECOND));
- instantNanos = Math.floorMod(instantNanos, NANOS_PER_SECOND);
- return temporal.with(INSTANT_SECONDS, instantSecs).with(NANO_OF_SECOND, instantNanos);
+ if (seconds != 0) {
+ temporal = temporal.plus(seconds, SECONDS);
+ }
+ if (nanos != 0) {
+ temporal = temporal.plus(nanos, NANOS);
+ }
+ return temporal;
}
/**
@@ -886,8 +1002,8 @@
* dateTime = dateTime.minus(thisDuration);
* </pre>
* <p>
- * A {@code Duration} can only be subtracted from a {@code Temporal} that
- * represents an instant and can supply {@link ChronoField#INSTANT_SECONDS}.
+ * The calculation will subtract the seconds, then nanos.
+ * Only non-zero amounts will be added.
* <p>
* This instance is immutable and unaffected by this method call.
*
@@ -898,17 +1014,60 @@
*/
@Override
public Temporal subtractFrom(Temporal temporal) {
- long instantSecs = temporal.getLong(INSTANT_SECONDS);
- long instantNanos = temporal.getLong(NANO_OF_SECOND);
- instantSecs = Math.subtractExact(instantSecs, seconds);
- instantNanos = Math.subtractExact(instantNanos, nanos);
- instantSecs = Math.addExact(instantSecs, Math.floorDiv(instantNanos, NANOS_PER_SECOND));
- instantNanos = Math.floorMod(instantNanos, NANOS_PER_SECOND);
- return temporal.with(INSTANT_SECONDS, instantSecs).with(NANO_OF_SECOND, instantNanos);
+ if (seconds != 0) {
+ temporal = temporal.minus(seconds, SECONDS);
+ }
+ if (nanos != 0) {
+ temporal = temporal.minus(nanos, NANOS);
+ }
+ return temporal;
}
//-----------------------------------------------------------------------
/**
+ * Gets the number of minutes in this duration.
+ * <p>
+ * This returns the total number of minutes in the duration by dividing the
+ * number of seconds by 86400.
+ * This is based on the standard definition of a day as 24 hours.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @return the number of minutes in the duration, may be negative
+ */
+ public long toDays() {
+ return seconds / SECONDS_PER_DAY;
+ }
+
+ /**
+ * Gets the number of minutes in this duration.
+ * <p>
+ * This returns the total number of minutes in the duration by dividing the
+ * number of seconds by 3600.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @return the number of minutes in the duration, may be negative
+ */
+ public long toHours() {
+ return seconds / SECONDS_PER_HOUR;
+ }
+
+ /**
+ * Gets the number of minutes in this duration.
+ * <p>
+ * This returns the total number of minutes in the duration by dividing the
+ * number of seconds by 60.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @return the number of minutes in the duration, may be negative
+ */
+ public long toMinutes() {
+ return seconds / SECONDS_PER_MINUTE;
+ }
+
+ /**
* Converts this duration to the total length in milliseconds.
* <p>
* If this duration is too large to fit in a {@code long} milliseconds, then an
@@ -961,30 +1120,6 @@
return nanos - otherDuration.nanos;
}
- /**
- * Checks if this duration is greater than the specified {@code Duration}.
- * <p>
- * The comparison is based on the total length of the durations.
- *
- * @param otherDuration the other duration to compare to, not null
- * @return true if this duration is greater than the specified duration
- */
- public boolean isGreaterThan(Duration otherDuration) {
- return compareTo(otherDuration) > 0;
- }
-
- /**
- * Checks if this duration is less than the specified {@code Duration}.
- * <p>
- * The comparison is based on the total length of the durations.
- *
- * @param otherDuration the other duration to compare to, not null
- * @return true if this duration is less than the specified duration
- */
- public boolean isLessThan(Duration otherDuration) {
- return compareTo(otherDuration) < 0;
- }
-
//-----------------------------------------------------------------------
/**
* Checks if this duration is equal to the specified {@code Duration}.
diff --git a/src/share/classes/java/time/Period.java b/src/share/classes/java/time/Period.java
--- a/src/share/classes/java/time/Period.java
+++ b/src/share/classes/java/time/Period.java
@@ -61,70 +61,79 @@
*/
package java.time;
-import static java.time.LocalTime.NANOS_PER_DAY;
-import static java.time.LocalTime.NANOS_PER_HOUR;
-import static java.time.LocalTime.NANOS_PER_MINUTE;
-import static java.time.LocalTime.NANOS_PER_SECOND;
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.EPOCH_MONTH;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.NANO_OF_DAY;
-import static java.time.temporal.ChronoField.YEAR;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
import static java.time.temporal.ChronoUnit.YEARS;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
import java.io.Serializable;
import java.time.chrono.Chronology;
import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ValueRange;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
- * A period of time, measured using the most common units, such as '3 Months, 4 Days and 7 Hours'.
+ * A date-based amount of time, such as '2 years, 3 months and 4 days'.
* <p>
- * A {@code Period} represents an amount of time measured in terms of the most commonly used units:
- * <p><ul>
- * <li>{@link ChronoUnit#YEARS YEARS}</li>
- * <li>{@link ChronoUnit#MONTHS MONTHS}</li>
- * <li>{@link ChronoUnit#DAYS DAYS}</li>
- * <li>time units with an {@linkplain TemporalUnit#isDurationEstimated() exact duration}</li>
- * </ul><p>
- * The period may be used with any calendar system with the exception of methods with an "ISO" suffix.
- * The meaning of a "year" or a "month" is only applied when the object is added to a date.
+ * This class models a quantity or amount of time in terms of years, months and days.
+ * See {@link Duration} for the time-based equivalent to this class.
+ * <p>
+ * Durations and period differ in their treatment of daylight savings time
+ * when added to {@link ZonedDateTime}. A {@code Duration} will add an exact
+ * number of seconds, thus a duration of one day is always exactly 24 hours.
+ * By contrast, a {@code Period} will add a conceptual day, trying to maintain
+ * the local time.
+ * <p>
+ * For example, consider adding a period of one day and a duration of one day to
+ * 18:00 on the evening before a daylight savings gap. The {@code Period} will add
+ * the conceptual day and result in a {@code ZonedDateTime} at 18:00 the following day.
+ * By contrast, the {@code Duration} will add exactly 24 hours, resulting in a
+ * {@code ZonedDateTime} at 19:00 the following day (assuming a one hour DST gap).
+ * <p>
+ * The supported units of a period are {@link ChronoUnit#YEARS YEARS},
+ * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+ * All three fields are always present, but may be set to zero.
+ * <p>
+ * The period may be used with any calendar system.
+ * The meaning of a "year" or "month" is only applied when the object is added to a date.
* <p>
* The period is modeled as a directed amount of time, meaning that individual parts of the
* period may be negative.
+ * <p>
+ * The months and years fields may be {@linkplain #normalized() normalized}.
+ * The normalization assumes a 12 month year, so is not appropriate for all calendar systems.
*
* <h3>Specification for implementors</h3>
* This class is immutable and thread-safe.
- * The maximum number of hours that can be stored is about 2.5 million, limited by storing
- * a single {@code long} nanoseconds for all time units internally.
*
* @since 1.8
*/
public final class Period
implements TemporalAmount, Serializable {
- // maximum hours is 2,562,047
/**
* A constant for a period of zero.
*/
- public static final Period ZERO = new Period(0, 0, 0, 0);
+ public static final Period ZERO = new Period(0, 0, 0);
/**
* Serialization version.
*/
- private static final long serialVersionUID = -8290556941213247973L;
+ private static final long serialVersionUID = -3587258372562876L;
/**
* The number of years.
@@ -138,321 +147,158 @@
* The number of days.
*/
private final int days;
- /**
- * The number of nanoseconds.
- */
- private final long nanos;
/**
- * The static final set of ChronoUnits supported by Period.
+ * The pattern for parsing.
*/
- private final static List<TemporalUnit> SUPPORTED_UNITS;
-
- static {
- ArrayList<TemporalUnit> tmp = new ArrayList<>(7);
- tmp.add(ChronoUnit.YEARS);
- tmp.add(ChronoUnit.MONTHS);
- tmp.add(ChronoUnit.DAYS);
- tmp.add(ChronoUnit.HOURS);
- tmp.add(ChronoUnit.MINUTES);
- tmp.add(ChronoUnit.SECONDS);
- tmp.add(ChronoUnit.NANOS);
- SUPPORTED_UNITS = Collections.unmodifiableList(tmp);
- }
+ private final static Pattern PATTERN =
+ Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE);
+ /**
+ * The set of supported units.
+ */
+ private final static List<TemporalUnit> SUPPORTED_UNITS =
+ Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code Period} from a number of years.
* <p>
* The resulting period will have the specified years.
- * The months, days and time fields will be zero.
+ * The months and days units will be zero.
*
* @param years the number of years, positive or negative
- * @return a {@code Period}, not null
+ * @return the period of years, not null
*/
public static Period ofYears(int years) {
- return create(years, 0, 0, 0);
+ return create(years, 0, 0);
}
/**
* Obtains an instance of {@code Period} from a number of months.
* <p>
* The resulting period will have the specified months.
- * The years, days and time fields will be zero.
+ * The years and days units will be zero.
*
* @param months the number of months, positive or negative
- * @return a {@code Period}, not null
+ * @return the period of months, not null
*/
public static Period ofMonths(int months) {
- return create(0, months, 0, 0);
+ return create(0, months, 0);
}
/**
* Obtains an instance of {@code Period} from a number of days.
* <p>
* The resulting period will have the specified days.
- * The years, months and time fields will be zero.
+ * The years and months units will be zero.
*
* @param days the number of days, positive or negative
- * @return a {@code Period}, not null
+ * @return the period of days, not null
*/
public static Period ofDays(int days) {
- return create(0, 0, days, 0);
- }
-
- /**
- * Obtains an instance of {@code Period} from a number of hours.
- * <p>
- * The resulting period will have the specified hours.
- * The years, months and days fields will be zero.
- * <p>
- * Within a period, the time fields are always normalized, thus
- * the hours are held in the time field measured in nanoseconds
- *
- * @param hours the number of hours, positive or negative
- * @return a {@code Period}, not null
- * @throws ArithmeticException if a numeric overflow occurs
- */
- public static Period ofHours(int hours) {
- return ofTime(hours, 0, 0, 0);
- }
-
- /**
- * Obtains an instance of {@code Period} from a number of minutes.
- * <p>
- * The resulting period will have the specified minutes.
- * The years, months and days fields will be zero.
- * <p>
- * Within a period, the time fields are always normalized, thus
- * the minutes are held in the time field measured in nanoseconds
- *
- * @param minutes the number of minutes, positive or negative
- * @return a {@code Period}, not null
- * @throws ArithmeticException if a numeric overflow occurs
- */
- public static Period ofMinutes(int minutes) {
- return ofTime(0, minutes, 0, 0);
- }
-
- /**
- * Obtains an instance of {@code Period} from a number of seconds.
- * <p>
- * The resulting period will have the specified seconds.
- * The years, months and days fields will be zero.
- * <p>
- * Within a period, the time fields are always normalized, thus
- * the seconds are held in the time field measured in nanoseconds
- *
- * @param seconds the number of seconds, positive or negative
- * @return a {@code Period}, not null
- */
- public static Period ofSeconds(int seconds) {
- return ofTime(0, 0, seconds, 0);
+ return create(0, 0, days);
}
//-----------------------------------------------------------------------
/**
- * Obtains a {@code Period} from date-based and time-based fields.
- * <p>
- * This creates an instance based on years, months, days, hours, minutes, seconds and nanoseconds.
- * Within a period, the time fields are always normalized.
- *
- * @param years the amount of years, may be negative
- * @param months the amount of months, may be negative
- * @param days the amount of days, may be negative
- * @param hours the amount of hours, may be negative
- * @param minutes the amount of minutes, may be negative
- * @param seconds the amount of seconds, may be negative
- * @param nanos the amount of nanos, may be negative
- * @return the period, not null
- */
- public static Period of(int years, int months, int days, int hours, int minutes, int seconds, long nanos) {
- if ((years | months | days | hours | minutes | seconds | nanos) == 0) {
- return ZERO;
- }
- long totSecs = Math.addExact(hours * 3600L, minutes * 60L) + seconds;
- long totNanos = Math.addExact(Math.multiplyExact(totSecs, 1_000_000_000L), nanos);
- return create(years, months, days, totNanos);
- }
-
- /**
- * Obtains a {@code Period} from date-based fields.
+ * Obtains a {@code Period} from the years, months and days units.
* <p>
* This creates an instance based on years, months and days.
*
* @param years the amount of years, may be negative
* @param months the amount of months, may be negative
* @param days the amount of days, may be negative
- * @return the period, not null
+ * @return the period of years, months and days, not null
*/
- public static Period ofDate(int years, int months, int days) {
- return of(years, months, days, 0, 0, 0, 0);
+ public static Period of(int years, int months, int days) {
+ return create(years, months, days);
}
- /**
- * Obtains a {@code Period} from time-based fields.
- * <p>
- * This creates an instance based on hours, minutes, seconds and nanoseconds.
- * Within a period, the time fields are always normalized.
- *
- * @param hours the amount of hours, may be negative
- * @param minutes the amount of minutes, may be negative
- * @param seconds the amount of seconds, may be negative
- * @param nanos the amount of nanos, may be negative
- * @return the period, not null
- * @throws ArithmeticException if a numeric overflow occurs
- */
- public static Period ofTime(int hours, int minutes, int seconds, long nanos) {
- return of(0, 0, 0, hours, minutes, seconds, nanos);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Obtains an instance of {@code Period} from a period in the specified unit.
- * <p>
- * The parameters represent the two parts of a phrase like '6 Days'. For example:
- * <pre>
- * Period.of(3, SECONDS);
- * Period.of(5, YEARS);
- * </pre>
- * The specified unit must be one of the supported units from {@link ChronoUnit},
- * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
- * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
- * Other units throw an exception.
- *
- * @param amount the amount of the period, measured in terms of the unit, positive or negative
- * @param unit the unit that the period is measured in, must have an exact duration, not null
- * @return the period, not null
- * @throws DateTimeException if the period unit is invalid
- * @throws ArithmeticException if a numeric overflow occurs
- */
- public static Period of(long amount, TemporalUnit unit) {
- return ZERO.plus(amount, unit);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Obtains a {@code Period} from a {@code Duration}.
- * <p>
- * This converts the duration to a period.
- * Within a period, the time fields are always normalized.
- * The years, months and days fields will be zero.
- * <p>
- * To populate the days field, call {@link #normalizedHoursToDays()} on the created period.
- *
- * @param duration the duration to convert, not null
- * @return the period, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public static Period of(Duration duration) {
- Objects.requireNonNull(duration, "duration");
- if (duration.isZero()) {
- return ZERO;
- }
- return new Period(0, 0, 0, duration.toNanos());
- }
-
- //-----------------------------------------------------------------------
- @Override
- public long get(TemporalUnit unit) {
- if (unit == ChronoUnit.YEARS) {
- return getYears();
- } else if (unit == ChronoUnit.MONTHS) {
- return getMonths();
- } else if (unit == ChronoUnit.DAYS) {
- return getDays();
- } else if (unit == ChronoUnit.HOURS) {
- return getHours();
- } else if (unit == ChronoUnit.MINUTES) {
- return getMinutes();
- } else if (unit == ChronoUnit.SECONDS) {
- return getSeconds();
- } else if (unit == ChronoUnit.NANOS) {
- return getNanos();
- } else {
- throw new DateTimeException("Unsupported unit: " + unit.getName());
- }
- }
-
- /**
- * Gets the set of ChronoUnits supported by {@code Period}.
- * @return a {@code List<TemporalUnit>} containing
- * {@link java.time.temporal.ChronoUnit#YEARS YEARS},
- * {@link java.time.temporal.ChronoUnit#MONTHS MONTHS},
- * {@link java.time.temporal.ChronoUnit#DAYS DAYS},
- * {@link java.time.temporal.ChronoUnit#HOURS HOURS},
- * {@link java.time.temporal.ChronoUnit#MINUTES MINUTES},
- * {@link java.time.temporal.ChronoUnit#SECONDS SECONDS}
- * and {@link java.time.temporal.ChronoUnit#NANOS NANOS}.
- */
- @Override
- public List<TemporalUnit> getUnits() {
- return SUPPORTED_UNITS;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a {@code Period} consisting of the number of years, months, days,
- * hours, minutes, seconds, and nanoseconds between two {@code TemporalAccessor} instances.
- * <p>
- * The start date is included, but the end date is not. Only whole years count.
- * For example, from {@code 2010-01-15} to {@code 2011-03-18} is one year, two months and three days.
- * <p>
- * This method examines the {@link ChronoField fields} {@code YEAR}, {@code MONTH_OF_YEAR},
- * {@code DAY_OF_MONTH} and {@code NANO_OF_DAY}
- * The difference between each of the fields is calculated independently from the others.
- * At least one of the four fields must be present.
- * <p>
- * The four units are typically retained without normalization.
- * However, years and months are normalized if the range of months is fixed, as it is with ISO.
- * <p>
- * The result of this method can be a negative period if the end is before the start.
- * The negative sign can be different in each of the four major units.
- *
- * @param start the start date, inclusive, not null
- * @param end the end date, exclusive, not null
- * @return the period between the date-times, not null
- * @throws DateTimeException if the two date-times do have similar available fields
- * @throws ArithmeticException if numeric overflow occurs
- */
- public static Period between(TemporalAccessor start, TemporalAccessor end) {
- if (Chronology.from(start).equals(Chronology.from(end)) == false) {
- throw new DateTimeException("Unable to calculate period as date-times have different chronologies");
- }
- int years = 0;
- int months = 0;
- int days = 0;
- long nanos = 0;
- boolean valid = false;
- if (start.isSupported(YEAR)) {
- years = Math.toIntExact(Math.subtractExact(end.getLong(YEAR), start.getLong(YEAR)));
- valid = true;
- }
- if (start.isSupported(MONTH_OF_YEAR)) {
- months = Math.toIntExact(Math.subtractExact(end.getLong(MONTH_OF_YEAR), start.getLong(MONTH_OF_YEAR)));
- ValueRange startRange = Chronology.from(start).range(MONTH_OF_YEAR);
- ValueRange endRange = Chronology.from(end).range(MONTH_OF_YEAR);
- if (startRange.isFixed() && startRange.isIntValue() && startRange.equals(endRange)) {
- int monthCount = (int) (startRange.getMaximum() - startRange.getMinimum() + 1);
- long totMonths = ((long) months) + years * monthCount;
- months = (int) (totMonths % monthCount);
- years = Math.toIntExact(totMonths / monthCount);
- }
- valid = true;
- }
- if (start.isSupported(DAY_OF_MONTH)) {
- days = Math.toIntExact(Math.subtractExact(end.getLong(DAY_OF_MONTH), start.getLong(DAY_OF_MONTH)));
- valid = true;
- }
- if (start.isSupported(NANO_OF_DAY)) {
- nanos = Math.subtractExact(end.getLong(NANO_OF_DAY), start.getLong(NANO_OF_DAY));
- valid = true;
- }
- if (valid == false) {
- throw new DateTimeException("Unable to calculate period as date-times do not have any valid fields");
- }
- return create(years, months, days, nanos);
- }
+// //-----------------------------------------------------------------------
+// /**
+// * Obtains an instance of {@code Period} from a period in the specified unit.
+// * <p>
+// * The parameters represent the two parts of a phrase like '6 Days'. For example:
+// * <pre>
+// * Period.of(3, DAYS);
+// * Period.of(5, YEARS);
+// * </pre>
+// * The specified unit must be one of the supported units from {@link ChronoUnit} -
+// * {@code YEARS}, {@code MONTHS} or {@code DAYS}.
+// *
+// * @param amount the amount of the period, measured in terms of the unit, positive or negative
+// * @param unit the unit that the period is measured in, must have an exact duration, not null
+// * @return the period, not null
+// * @throws DateTimeException if the period unit is invalid
+// * @throws ArithmeticException if a numeric overflow occurs
+// */
+// public static Period of(long amount, TemporalUnit unit) {
+// return ZERO.plus(amount, unit);
+// }
+//
+// //-----------------------------------------------------------------------
+// /**
+// * Returns a {@code Period} consisting of the number of years, months, days,
+// * hours, minutes, seconds, and nanoseconds between two {@code TemporalAccessor} instances.
+// * <p>
+// * The start date is included, but the end date is not. Only whole years count.
+// * For example, from {@code 2010-01-15} to {@code 2011-03-18} is one year, two months and three days.
+// * <p>
+// * This method examines the {@link ChronoField fields} {@code YEAR}, {@code MONTH_OF_YEAR},
+// * {@code DAY_OF_MONTH} and {@code NANO_OF_DAY}
+// * The difference between each of the fields is calculated independently from the others.
+// * At least one of the four fields must be present.
+// * <p>
+// * The four units are typically retained without normalization.
+// * However, years and months are normalized if the range of months is fixed, as it is with ISO.
+// * <p>
+// * The result of this method can be a negative period if the end is before the start.
+// * The negative sign can be different in each of the four major units.
+// *
+// * @param start the start date, inclusive, not null
+// * @param end the end date, exclusive, not null
+// * @return the period between the date-times, not null
+// * @throws DateTimeException if the two date-times do have similar available fields
+// * @throws ArithmeticException if numeric overflow occurs
+// */
+// public static Period between(TemporalAccessor start, TemporalAccessor end) {
+// if (Chronology.from(start).equals(Chronology.from(end)) == false) {
+// throw new DateTimeException("Unable to calculate period as date-times have different chronologies");
+// }
+// int years = 0;
+// int months = 0;
+// int days = 0;
+// long nanos = 0;
+// boolean valid = false;
+// if (start.isSupported(YEAR)) {
+// years = Math.toIntExact(Math.subtractExact(end.getLong(YEAR), start.getLong(YEAR)));
+// valid = true;
+// }
+// if (start.isSupported(MONTH_OF_YEAR)) {
+// months = Math.toIntExact(Math.subtractExact(end.getLong(MONTH_OF_YEAR), start.getLong(MONTH_OF_YEAR)));
+// ValueRange startRange = Chronology.from(start).range(MONTH_OF_YEAR);
+// ValueRange endRange = Chronology.from(end).range(MONTH_OF_YEAR);
+// if (startRange.isFixed() && startRange.isIntValue() && startRange.equals(endRange)) {
+// int monthCount = (int) (startRange.getMaximum() - startRange.getMinimum() + 1);
+// long totMonths = ((long) months) + years * monthCount;
+// months = (int) (totMonths % monthCount);
+// years = Math.toIntExact(totMonths / monthCount);
+// }
+// valid = true;
+// }
+// if (start.isSupported(DAY_OF_MONTH)) {
+// days = Math.toIntExact(Math.subtractExact(end.getLong(DAY_OF_MONTH), start.getLong(DAY_OF_MONTH)));
+// valid = true;
+// }
+// if (start.isSupported(NANO_OF_DAY)) {
+// nanos = Math.subtractExact(end.getLong(NANO_OF_DAY), start.getLong(NANO_OF_DAY));
+// valid = true;
+// }
+// if (valid == false) {
+// throw new DateTimeException("Unable to calculate period as date-times do not have any valid fields");
+// }
+// return create(years, months, days, nanos);
+// }
//-----------------------------------------------------------------------
/**
@@ -474,7 +320,7 @@
* @return the period between the dates, not null
* @throws ArithmeticException if numeric overflow occurs
*/
- public static Period betweenIso(LocalDate startDate, LocalDate endDate) {
+ public static Period between(LocalDate startDate, LocalDate endDate) {
long startMonth = startDate.getLong(EPOCH_MONTH);
long endMonth = endDate.getLong(EPOCH_MONTH);
long totalMonths = endMonth - startMonth; // safe
@@ -489,56 +335,63 @@
}
long years = totalMonths / 12; // safe
int months = (int) (totalMonths % 12); // safe
- return ofDate(Math.toIntExact(years), months, days);
+ return create(Math.toIntExact(years), months, days);
}
//-----------------------------------------------------------------------
/**
- * Obtains a {@code Period} consisting of the number of hours, minutes,
- * seconds and nanoseconds between two times.
- * <p>
- * The start time is included, but the end time is not.
- * The period is calculated from the difference between the nano-of-day values
- * of the two times. For example, from {@code 13:45:00} to {@code 14:50:30.123456789}
- * is {@code P1H5M30.123456789S}.
- * <p>
- * The result of this method can be a negative period if the end is before the start.
- *
- * @param startTime the start time, inclusive, not null
- * @param endTime the end time, exclusive, not null
- * @return the period between the times, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public static Period betweenIso(LocalTime startTime, LocalTime endTime) {
- return create(0, 0, 0, endTime.toNanoOfDay() - startTime.toNanoOfDay());
- }
-
- //-----------------------------------------------------------------------
- /**
- * Obtains a {@code Period} from a text string such as {@code PnYnMnDTnHnMn.nS}.
+ * Obtains a {@code Period} from a text string such as {@code PnYnMnD}.
* <p>
* This will parse the string produced by {@code toString()} which is
- * a subset of the ISO-8601 period format {@code PnYnMnDTnHnMn.nS}.
+ * based on the ISO-8601 period format {@code PnYnMnD}.
* <p>
- * The string consists of a series of numbers with a suffix identifying their meaning.
- * The values, and suffixes, must be in the sequence year, month, day, hour, minute, second.
- * Any of the number/suffix pairs may be omitted providing at least one is present.
- * If the period is zero, the value is normally represented as {@code PT0S}.
- * The numbers must consist of ASCII digits.
- * Any of the numbers may be negative. Negative zero is not accepted.
- * The number of nanoseconds is expressed as an optional fraction of the seconds.
- * There must be at least one digit before any decimal point.
- * There must be between 1 and 9 inclusive digits after any decimal point.
- * The letters will all be accepted in upper or lower case.
- * The decimal point may be either a dot or a comma.
+ * The string starts with an optional sign, denoted by the ASCII negative
+ * or positive symbol. If negative, the whole period is negated.
+ * The ASCII letter "P" is next in upper or lower case.
+ * There are then three sections, each consisting of a number and a suffix.
+ * At least one of the three sections must be present.
+ * The sections have suffixes in ASCII of "Y", "M" and "D" for
+ * years, months and days, accepted in upper or lower case.
+ * The suffixes must occur in order.
+ * The number part of each section must consist of ASCII digits.
+ * The number may be prefixed by the ASCII negative or positive symbol.
+ * The number must parse to an {@ocde int}.
*
* @param text the text to parse, not null
* @return the parsed period, not null
* @throws DateTimeParseException if the text cannot be parsed to a period
*/
- public static Period parse(final CharSequence text) {
+ public static Period parse(CharSequence text) {
Objects.requireNonNull(text, "text");
- return new PeriodParser(text).parse();
+ Matcher matcher = PATTERN.matcher(text);
+ if (matcher.matches()) {
+ int negate = ("-".equals(matcher.group(1)) ? -1 : 1);
+ String yearMatch = matcher.group(2);
+ String monthMatch = matcher.group(3);
+ String dayMatch = matcher.group(4);
+ if (yearMatch != null || monthMatch != null || dayMatch != null) {
+ try {
+ return create(parseNumber(text, yearMatch, negate),
+ parseNumber(text, monthMatch, negate),
+ parseNumber(text, dayMatch, negate));
+ } 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);
+ }
+
+ private static int parseNumber(CharSequence text, String str, int negate) {
+ if (str == null) {
+ return 0;
+ }
+ int val = Integer.parseInt(str);
+ try {
+ return Math.multiplyExact(val, negate);
+ } catch (ArithmeticException ex) {
+ throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex);
+ }
}
//-----------------------------------------------------------------------
@@ -548,13 +401,12 @@
* @param years the amount
* @param months the amount
* @param days the amount
- * @param nanos the amount
*/
- private static Period create(int years, int months, int days, long nanos) {
- if ((years | months | days | nanos) == 0) {
+ private static Period create(int years, int months, int days) {
+ if ((years | months | days) == 0) {
return ZERO;
}
- return new Period(years, months, days, nanos);
+ return new Period(years, months, days);
}
/**
@@ -563,30 +415,61 @@
* @param years the amount
* @param months the amount
* @param days the amount
- * @param nanos the amount
*/
- private Period(int years, int months, int days, long nanos) {
+ private Period(int years, int months, int days) {
this.years = years;
this.months = months;
this.days = days;
- this.nanos = nanos;
- }
-
- /**
- * Resolves singletons.
- *
- * @return the resolved instance
- */
- private Object readResolve() {
- if ((years | months | days | nanos) == 0) {
- return ZERO;
- }
- return this;
}
//-----------------------------------------------------------------------
/**
- * Checks if this period is zero-length.
+ * Gets the value of the requested unit.
+ * <p>
+ * This returns a value for each of the three supported units,
+ * {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS} and
+ * {@link ChronoUnit#DAYS DAYS}.
+ * All other units throw an exception.
+ *
+ * @param unit the {@code TemporalUnit} for which to return the value
+ * @return the long value of the unit
+ * @throws DateTimeException if the unit is not supported
+ */
+ @Override
+ public long get(TemporalUnit unit) {
+ if (unit == ChronoUnit.YEARS) {
+ return getYears();
+ } else if (unit == ChronoUnit.MONTHS) {
+ return getMonths();
+ } else if (unit == ChronoUnit.DAYS) {
+ return getDays();
+ } else {
+ throw new DateTimeException("Unsupported unit: " + unit.getName());
+ }
+ }
+
+ /**
+ * Gets the set of units supported by this period.
+ * <p>
+ * The supported units are {@link ChronoUnit#YEARS YEARS},
+ * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+ * They are returned in the order years, months, days.
+ * <p>
+ * This set can be used in conjunction with {@link #get(TemporalUnit)}
+ * to access the entire state of the period.
+ *
+ * @return a list containing the years, months and days units, not null
+ */
+ @Override
+ public List<TemporalUnit> getUnits() {
+ return SUPPORTED_UNITS;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks if all three units of this period are zero.
+ * <p>
+ * A zero period has the value zero for the years, months and days units.
*
* @return true if this period is zero-length
*/
@@ -595,22 +478,27 @@
}
/**
- * Checks if this period is fully positive, excluding zero.
+ * Checks if any of the three units of this period are negative.
* <p>
- * This checks whether all the amounts in the period are positive,
- * defined as greater than zero.
+ * This checks whether the years, months or days units are less than zero.
*
- * @return true if this period is fully positive excluding zero
+ * @return true if any unit of this period is negative
*/
- public boolean isPositive() {
- return ((years | months | days | nanos) > 0);
+ public boolean isNegative() {
+ return years < 0 || months < 0 || days < 0;
}
//-----------------------------------------------------------------------
/**
* Gets the amount of years of this period.
+ * <p>
+ * This returns the years unit.
+ * <p>
+ * The months unit is not normalized with the years unit.
+ * This means that a period of "15 months" is different to a period
+ * of "1 year and 3 months".
*
- * @return the amount of years of this period
+ * @return the amount of years of this period, may be negative
*/
public int getYears() {
return years;
@@ -618,8 +506,14 @@
/**
* Gets the amount of months of this period.
+ * <p>
+ * This returns the months unit.
+ * <p>
+ * The months unit is not normalized with the years unit.
+ * This means that a period of "15 months" is different to a period
+ * of "1 year and 3 months".
*
- * @return the amount of months of this period
+ * @return the amount of months of this period, may be negative
*/
public int getMonths() {
return months;
@@ -627,158 +521,76 @@
/**
* Gets the amount of days of this period.
+ * <p>
+ * This returns the days unit.
*
- * @return the amount of days of this period
+ * @return the amount of days of this period, may be negative
*/
public int getDays() {
return days;
}
- /**
- * Gets the amount of hours of this period.
- * <p>
- * Within a period, the time fields are always normalized.
- *
- * @return the amount of hours of this period
- */
- public int getHours() {
- return (int) (nanos / NANOS_PER_HOUR);
- }
-
- /**
- * Gets the amount of minutes within an hour of this period.
- * <p>
- * Within a period, the time fields are always normalized.
- *
- * @return the amount of minutes within an hour of this period
- */
- public int getMinutes() {
- return (int) ((nanos / NANOS_PER_MINUTE) % 60);
- }
-
- /**
- * Gets the amount of seconds within a minute of this period.
- * <p>
- * Within a period, the time fields are always normalized.
- *
- * @return the amount of seconds within a minute of this period
- */
- public int getSeconds() {
- return (int) ((nanos / NANOS_PER_SECOND) % 60);
- }
-
- /**
- * Gets the amount of nanoseconds within a second of this period.
- * <p>
- * Within a period, the time fields are always normalized.
- *
- * @return the amount of nanoseconds within a second of this period
- */
- public int getNanos() {
- return (int) (nanos % NANOS_PER_SECOND); // safe from overflow
- }
-
- /**
- * Gets the total amount of the time units of this period, measured in nanoseconds.
- * <p>
- * Within a period, the time fields are always normalized.
- *
- * @return the total amount of time unit nanoseconds of this period
- */
- public long getTimeNanos() {
- return nanos;
- }
-
//-----------------------------------------------------------------------
/**
* Returns a copy of this period with the specified amount of years.
* <p>
- * This method will only affect the years field.
- * All other units are unaffected.
+ * This sets the amount of the years unit in a copy of this period.
+ * The months and days units are unaffected.
+ * <p>
+ * The months unit is not normalized with the years unit.
+ * This means that a period of "15 months" is different to a period
+ * of "1 year and 3 months".
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @param years the years to represent
+ * @param years the years to represent, may be negative
* @return a {@code Period} based on this period with the requested years, not null
*/
public Period withYears(int years) {
if (years == this.years) {
return this;
}
- return create(years, months, days, nanos);
+ return create(years, months, days);
}
/**
* Returns a copy of this period with the specified amount of months.
* <p>
- * This method will only affect the months field.
- * All other units are unaffected.
+ * This sets the amount of the months unit in a copy of this period.
+ * The years and days units are unaffected.
+ * <p>
+ * The months unit is not normalized with the years unit.
+ * This means that a period of "15 months" is different to a period
+ * of "1 year and 3 months".
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @param months the months to represent
+ * @param months the months to represent, may be negative
* @return a {@code Period} based on this period with the requested months, not null
*/
public Period withMonths(int months) {
if (months == this.months) {
return this;
}
- return create(years, months, days, nanos);
+ return create(years, months, days);
}
/**
* Returns a copy of this period with the specified amount of days.
* <p>
- * This method will only affect the days field.
- * All other units are unaffected.
+ * This sets the amount of the days unit in a copy of this period.
+ * The years and months units are unaffected.
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @param days the days to represent
+ * @param days the days to represent, may be negative
* @return a {@code Period} based on this period with the requested days, not null
*/
public Period withDays(int days) {
if (days == this.days) {
return this;
}
- return create(years, months, days, nanos);
- }
-
- /**
- * Returns a copy of this period with the specified total amount of time units
- * expressed in nanoseconds.
- * <p>
- * Within a period, the time fields are always normalized.
- * This method will affect all the time units - hours, minutes, seconds and nanos.
- * The date units are unaffected.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param nanos the nanoseconds to represent
- * @return a {@code Period} based on this period with the requested nanoseconds, not null
- */
- public Period withTimeNanos(long nanos) {
- if (nanos == this.nanos) {
- return this;
- }
- return create(years, months, days, nanos);
- }
-
- /**
- * Returns a copy of this period with the specified duration replacing the time units.
- * <p>
- * Within a period, the time fields are always normalized and equivalent to a duration.
- * Calling this method will return a new period with the time fields replaced.
- * This method will affect all the time units - hours, minutes, seconds and nanos.
- * The date units are unaffected.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param duration the duration to represent, not null
- * @return a {@code Period} based on this period with the time fields set to the specified duration, not null
- */
- public Period withTime(Duration duration) {
- return withTimeNanos(duration.toNanos());
+ return create(years, months, days);
}
//-----------------------------------------------------------------------
@@ -788,6 +600,9 @@
* This operates separately on the years, months, days and the normalized time.
* There is no further normalization beyond the normalized time.
* <p>
+ * For example, "1 year, 6 months and 3 days" plus "2 years, 2 months and 2 days"
+ * returns "3 years, 8 months and 5 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToAdd the period to add, not null
@@ -798,56 +613,59 @@
return create(
Math.addExact(years, amountToAdd.years),
Math.addExact(months, amountToAdd.months),
- Math.addExact(days, amountToAdd.days),
- Math.addExact(nanos, amountToAdd.nanos));
+ Math.addExact(days, amountToAdd.days));
}
- /**
- * Returns a copy of this period with the specified period added.
- * <p>
- * The specified unit must be one of the supported units from {@link ChronoUnit},
- * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
- * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
- * Other units throw an exception.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param amountToAdd the amountToAdd to add, positive or negative
- * @param unit the unit that the amountToAdd is expressed in, not null
- * @return a {@code Period} based on this period with the requested amountToAdd added, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period plus(long amountToAdd, TemporalUnit unit) {
- Objects.requireNonNull(unit, "unit");
- if (unit instanceof ChronoUnit) {
- if (unit == YEARS || unit == MONTHS || unit == DAYS || unit.isDurationEstimated() == false) {
- if (amountToAdd == 0) {
- return this;
- }
- switch((ChronoUnit) unit) {
- case NANOS: return plusNanos(amountToAdd);
- case MICROS: return plusNanos(Math.multiplyExact(amountToAdd, 1000L));
- case MILLIS: return plusNanos(Math.multiplyExact(amountToAdd, 1000_000L));
- case SECONDS: return plusSeconds(amountToAdd);
- case MINUTES: return plusMinutes(amountToAdd);
- case HOURS: return plusHours(amountToAdd);
- case HALF_DAYS: return plusNanos(Math.multiplyExact(amountToAdd, 12 * NANOS_PER_HOUR));
- case DAYS: return plusDays(amountToAdd);
- case MONTHS: return plusMonths(amountToAdd);
- case YEARS: return plusYears(amountToAdd);
- default: throw new DateTimeException("Unsupported unit: " + unit.getName());
- }
- }
- }
- if (unit.isDurationEstimated()) {
- throw new DateTimeException("Unsupported unit: " + unit.getName());
- }
- return plusNanos(Duration.of(amountToAdd, unit).toNanos());
- }
+// /**
+// * Returns a copy of this period with the specified period added.
+// * <p>
+// * The specified unit must be one of the supported units from {@link ChronoUnit},
+// * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
+// * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
+// * Other units throw an exception.
+// * <p>
+// * This instance is immutable and unaffected by this method call.
+// *
+// * @param amountToAdd the amountToAdd to add, positive or negative
+// * @param unit the unit that the amountToAdd is expressed in, not null
+// * @return a {@code Period} based on this period with the requested amountToAdd added, not null
+// * @throws ArithmeticException if numeric overflow occurs
+// */
+// public Period plus(long amountToAdd, TemporalUnit unit) {
+// Objects.requireNonNull(unit, "unit");
+// if (unit instanceof ChronoUnit) {
+// if (unit == YEARS || unit == MONTHS || unit == DAYS || unit.isDurationEstimated() == false) {
+// if (amountToAdd == 0) {
+// return this;
+// }
+// switch((ChronoUnit) unit) {
+// case NANOS: return plusNanos(amountToAdd);
+// case MICROS: return plusNanos(Math.multiplyExact(amountToAdd, 1000L));
+// case MILLIS: return plusNanos(Math.multiplyExact(amountToAdd, 1000_000L));
+// case SECONDS: return plusSeconds(amountToAdd);
+// case MINUTES: return plusMinutes(amountToAdd);
+// case HOURS: return plusHours(amountToAdd);
+// case HALF_DAYS: return plusNanos(Math.multiplyExact(amountToAdd, 12 * NANOS_PER_HOUR));
+// case DAYS: return plusDays(amountToAdd);
+// case MONTHS: return plusMonths(amountToAdd);
+// case YEARS: return plusYears(amountToAdd);
+// default: throw new DateTimeException("Unsupported unit: " + unit.getName());
+// }
+// }
+// }
+// if (unit.isDurationEstimated()) {
+// throw new DateTimeException("Unsupported unit: " + unit.getName());
+// }
+// return plusNanos(Duration.of(amountToAdd, unit).toNanos());
+// }
/**
* Returns a copy of this period with the specified years added.
* <p>
+ * This adds the amount to the years unit in a copy of this period.
+ * The months and days units are unaffected.
+ * For example, "1 year, 6 months and 3 days" plus 2 years returns "3 years, 6 months and 3 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param yearsToAdd the years to add, positive or negative
@@ -858,12 +676,16 @@
if (yearsToAdd == 0) {
return this;
}
- return create(Math.toIntExact(Math.addExact(years, yearsToAdd)), months, days, nanos);
+ return create(Math.toIntExact(Math.addExact(years, yearsToAdd)), months, days);
}
/**
* Returns a copy of this period with the specified months added.
* <p>
+ * This adds the amount to the months unit in a copy of this period.
+ * The years and days units are unaffected.
+ * For example, "1 year, 6 months and 3 days" plus 2 months returns "1 year, 8 months and 3 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param monthsToAdd the months to add, positive or negative
@@ -874,12 +696,16 @@
if (monthsToAdd == 0) {
return this;
}
- return create(years, Math.toIntExact(Math.addExact(months, monthsToAdd)), days, nanos);
+ return create(years, Math.toIntExact(Math.addExact(months, monthsToAdd)), days);
}
/**
* Returns a copy of this period with the specified days added.
* <p>
+ * This adds the amount to the days unit in a copy of this period.
+ * The years and months units are unaffected.
+ * For example, "1 year, 6 months and 3 days" plus 2 days returns "1 year, 6 months and 5 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param daysToAdd the days to add, positive or negative
@@ -890,71 +716,7 @@
if (daysToAdd == 0) {
return this;
}
- return create(years, months, Math.toIntExact(Math.addExact(days, daysToAdd)), nanos);
- }
-
- /**
- * Returns a copy of this period with the specified hours added.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param hoursToAdd the hours to add, positive or negative
- * @return a {@code Period} based on this period with the specified hours added, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period plusHours(long hoursToAdd) {
- if (hoursToAdd == 0) {
- return this;
- }
- return plusNanos(Math.multiplyExact(hoursToAdd, NANOS_PER_HOUR));
- }
-
- /**
- * Returns a copy of this period with the specified minutes added.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param minutesToAdd the minutes to add, positive or negative
- * @return a {@code Period} based on this period with the specified minutes added, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period plusMinutes(long minutesToAdd) {
- if (minutesToAdd == 0) {
- return this;
- }
- return plusNanos(Math.multiplyExact(minutesToAdd, NANOS_PER_MINUTE));
- }
-
- /**
- * Returns a copy of this period with the specified seconds added.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param secondsToAdd the seconds to add, positive or negative
- * @return a {@code Period} based on this period with the specified seconds added, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period plusSeconds(long secondsToAdd) {
- if (secondsToAdd == 0) {
- return this;
- }
- return plusNanos(Math.multiplyExact(secondsToAdd, NANOS_PER_SECOND));
- }
-
- /**
- * Returns a copy of this period with the specified nanoseconds added.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param nanosToAdd the nanoseconds to add, positive or negative
- * @return a {@code Period} based on this period with the specified nanoseconds added, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period plusNanos(long nanosToAdd) {
- if (nanosToAdd == 0) {
- return this;
- }
- return create(years, months, days, Math.addExact(nanos, nanosToAdd));
+ return create(years, months, Math.toIntExact(Math.addExact(days, daysToAdd)));
}
//-----------------------------------------------------------------------
@@ -964,6 +726,9 @@
* This operates separately on the years, months, days and the normalized time.
* There is no further normalization beyond the normalized time.
* <p>
+ * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days"
+ * returns "-1 years, 4 months and 1 day".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToSubtract the period to subtract, not null
@@ -974,32 +739,35 @@
return create(
Math.subtractExact(years, amountToSubtract.years),
Math.subtractExact(months, amountToSubtract.months),
- Math.subtractExact(days, amountToSubtract.days),
- Math.subtractExact(nanos, amountToSubtract.nanos));
+ Math.subtractExact(days, amountToSubtract.days));
}
- /**
- * Returns a copy of this period with the specified period subtracted.
- * <p>
- * The specified unit must be one of the supported units from {@link ChronoUnit},
- * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
- * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
- * Other units throw an exception.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param amountToSubtract the amountToSubtract to subtract, positive or negative
- * @param unit the unit that the amountToSubtract is expressed in, not null
- * @return a {@code Period} based on this period with the requested amountToSubtract subtracted, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period minus(long amountToSubtract, TemporalUnit unit) {
- return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
- }
+// /**
+// * Returns a copy of this period with the specified period subtracted.
+// * <p>
+// * The specified unit must be one of the supported units from {@link ChronoUnit},
+// * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
+// * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
+// * Other units throw an exception.
+// * <p>
+// * This instance is immutable and unaffected by this method call.
+// *
+// * @param amountToSubtract the amountToSubtract to subtract, positive or negative
+// * @param unit the unit that the amountToSubtract is expressed in, not null
+// * @return a {@code Period} based on this period with the requested amountToSubtract subtracted, not null
+// * @throws ArithmeticException if numeric overflow occurs
+// */
+// public Period minus(long amountToSubtract, TemporalUnit unit) {
+// return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
+// }
/**
* Returns a copy of this period with the specified years subtracted.
* <p>
+ * This subtracts the amount from the years unit in a copy of this period.
+ * The months and days units are unaffected.
+ * For example, "1 year, 6 months and 3 days" minus 2 years returns "-1 years, 6 months and 3 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param yearsToSubtract the years to subtract, positive or negative
@@ -1013,6 +781,10 @@
/**
* Returns a copy of this period with the specified months subtracted.
* <p>
+ * This subtracts the amount from the months unit in a copy of this period.
+ * The years and days units are unaffected.
+ * For example, "1 year, 6 months and 3 days" minus 2 months returns "1 year, 4 months and 3 days".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param monthsToSubtract the years to subtract, positive or negative
@@ -1026,6 +798,10 @@
/**
* Returns a copy of this period with the specified days subtracted.
* <p>
+ * This subtracts the amount from the days unit in a copy of this period.
+ * The years and months units are unaffected.
+ * For example, "1 year, 6 months and 3 days" minus 2 days returns "1 year, 6 months and 1 day".
+ * <p>
* This instance is immutable and unaffected by this method call.
*
* @param daysToSubtract the months to subtract, positive or negative
@@ -1036,65 +812,16 @@
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
}
- /**
- * Returns a copy of this period with the specified hours subtracted.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param hoursToSubtract the days to subtract, positive or negative
- * @return a {@code Period} based on this period with the specified hours subtracted, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period minusHours(long hoursToSubtract) {
- return (hoursToSubtract == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hoursToSubtract));
- }
-
- /**
- * Returns a copy of this period with the specified minutes subtracted.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param minutesToSubtract the hours to subtract, positive or negative
- * @return a {@code Period} based on this period with the specified minutes subtracted, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period minusMinutes(long minutesToSubtract) {
- return (minutesToSubtract == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutesToSubtract));
- }
-
- /**
- * Returns a copy of this period with the specified seconds subtracted.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param secondsToSubtract the years to subtract, positive or negative
- * @return a {@code Period} based on this period with the specified seconds subtracted, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period minusSeconds(long secondsToSubtract) {
- return (secondsToSubtract == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-secondsToSubtract));
- }
-
- /**
- * Returns a copy of this period with the specified nanoseconds subtracted.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @param nanosToSubtract the nanoseconds to subtract, positive or negative
- * @return a {@code Period} based on this period with the specified nanoseconds subtracted, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period minusNanos(long nanosToSubtract) {
- return (nanosToSubtract == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanosToSubtract));
- }
-
//-----------------------------------------------------------------------
/**
* Returns a new instance with each element in this period multiplied
* by the specified scalar.
* <p>
- * This simply multiplies each field, years, months, days and normalized time,
- * by the scalar. No normalization is performed.
+ * This returns a period with each of the years, months and days units
+ * individually multiplied.
+ * For example, a period of "2 years, -3 months and 4 days" multiplied by
+ * 3 will return "6 years, -9 months and 12 days".
+ * No normalization is performed.
*
* @param scalar the scalar to multiply by, not null
* @return a {@code Period} based on this period with the amounts multiplied by the scalar, not null
@@ -1107,15 +834,21 @@
return create(
Math.multiplyExact(years, scalar),
Math.multiplyExact(months, scalar),
- Math.multiplyExact(days, scalar),
- Math.multiplyExact(nanos, scalar));
+ Math.multiplyExact(days, scalar));
}
/**
* Returns a new instance with each amount in this period negated.
+ * <p>
+ * This returns a period with each of the years, months and days units
+ * individually negated.
+ * For example, a period of "2 years, -3 months and 4 days" will be
+ * negated to "-2 years, 3 months and -4 days".
+ * No normalization is performed.
*
* @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, which only happens if
+ * one of the units has the value {@code Long.MIN_VALUE}
*/
public Period negated() {
return multipliedBy(-1);
@@ -1123,137 +856,49 @@
//-----------------------------------------------------------------------
/**
- * Returns a copy of this period with the days and hours normalized using a 24 hour day.
+ * Returns a copy of this period with the years and months normalized
+ * using a 12 month year.
* <p>
- * This normalizes the days and hours units, leaving years and months unchanged.
- * The hours unit is adjusted to have an absolute value less than 23,
- * with the days unit being adjusted to compensate.
- * For example, a period of {@code P1DT27H} will be normalized to {@code P2DT3H}.
- * <p>
- * The sign of the days and hours units will be the same after normalization.
- * For example, a period of {@code P1DT-51H} will be normalized to {@code P-1DT-3H}.
- * Since all time units are always normalized, if the hours units changes sign then
- * other time units will also be affected.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @return a {@code Period} based on this period with excess hours normalized to days, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period normalizedHoursToDays() {
- // logic uses if statements to normalize signs to avoid unnecessary overflows
- long totalDays = (nanos / NANOS_PER_DAY) + days; // no overflow
- long splitNanos = nanos % NANOS_PER_DAY;
- if (totalDays > 0 && splitNanos < 0) {
- splitNanos += NANOS_PER_DAY;
- totalDays--;
- } else if (totalDays < 0 && splitNanos > 0) {
- splitNanos -= NANOS_PER_DAY;
- totalDays++;
- }
- if (totalDays == days && splitNanos == nanos) {
- return this;
- }
- return create(years, months, Math.toIntExact(totalDays), splitNanos);
- }
-
- /**
- * Returns a copy of this period with any days converted to hours using a 24 hour day.
- * <p>
- * The days unit is reduced to zero, with the hours unit increased by 24 times the
- * days unit to compensate. Other units are unaffected.
- * For example, a period of {@code P2DT4H} will be normalized to {@code PT52H}.
- * <p>
- * This can be used to calculate the total number of hours in a period, including
- * days but not months or years:
- * <pre>
- * int totalHours = period.normalizedDaysToHours().getHours();
- * </pre>
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @return a {@code Period} based on this period with days normalized to hours, not null
- * @throws ArithmeticException if numeric overflow occurs
- */
- public Period normalizedDaysToHours() {
- if (days == 0) {
- return this;
- }
- return create(years, months, 0, Math.addExact(Math.multiplyExact(days, NANOS_PER_DAY), nanos));
- }
-
- /**
- * Returns a copy of this period with the years and months normalized using a 12 month year.
- * <p>
- * This normalizes the years and months units, leaving other units unchanged.
+ * This normalizes the years and months units, leaving the days unit unchanged.
* The months unit is adjusted to have an absolute value less than 11,
- * with the years unit being adjusted to compensate.
- * For example, a period of {@code P1Y15M} will be normalized to {@code P2Y3M}.
+ * with the years unit being adjusted to compensate. For example, a period of
+ * "1 Year and 15 months" will be normalized to "2 years and 3 months".
* <p>
* The sign of the years and months units will be the same after normalization.
- * For example, a period of {@code P1Y-25M} will be normalized to {@code P-1Y-1M}.
+ * For example, a period of "1 year and -25 months" will be normalized to
+ * "-1 year and -1 month".
* <p>
- * This normalization uses a 12 month year it is not valid for all calendar systems.
+ * This normalization uses a 12 month year which is not valid for all calendar systems.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @return a {@code Period} based on this period with excess months normalized to years, not null
* @throws ArithmeticException if numeric overflow occurs
*/
- public Period normalizedMonthsToYears() {
- long totalMonths = years * 12L + months; // no overflow
+ public Period normalized() {
+ long totalMonths = toTotalMonths();
long splitYears = totalMonths / 12;
int splitMonths = (int) (totalMonths % 12); // no overflow
if (splitYears == years && splitMonths == months) {
return this;
}
- return create(Math.toIntExact(splitYears), splitMonths, days, nanos);
+ return create(Math.toIntExact(splitYears), splitMonths, days);
}
/**
- * Returns a copy of this period with any years converted to months using a 12 month year.
+ * Gets the total number of months in this period using a 12 month year.
* <p>
- * The years unit is reduced to zero, with the months unit increased by 12 times the
- * years unit to compensate. Other units are unaffected.
- * For example, a period of {@code P1Y15M} will be normalized to {@code P27M}.
+ * This returns the total number of months in the period by multiplying the
+ * number of years by 12 and adding the number of months.
* <p>
- * This can be used to calculate the total number of months in a period:
- * <pre>
- * int totalMonths = period.normalizedYearsToMonths().getMonths();
- * </pre>
- * <p>
- * This normalization uses a 12 month year it is not valid for all calendar systems.
+ * This uses a 12 month year which is not valid for all calendar systems.
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @return a {@code Period} based on this period with years normalized to months, not null
- * @throws ArithmeticException if numeric overflow occurs
+ * @return the total number of months in the period, may be negative
*/
- public Period normalizedYearsToMonths() {
- if (years == 0) {
- return this;
- }
- long totalMonths = years * 12L + months; // no overflow
- return create(0, Math.toIntExact(totalMonths), days, nanos);
- }
-
- //-------------------------------------------------------------------------
- /**
- * Converts this period to one that only has date units.
- * <p>
- * The resulting period will have the same years, months and days as this period
- * but the time units will all be zero. No normalization occurs in the calculation.
- * For example, a period of {@code P1Y3MT12H} will be converted to {@code P1Y3M}.
- * <p>
- * This instance is immutable and unaffected by this method call.
- *
- * @return a {@code Period} based on this period with the time units set to zero, not null
- */
- public Period toDateOnly() {
- if (nanos == 0) {
- return this;
- }
- return create(years, months, days, 0);
+ public long toTotalMonths() {
+ return years * 12L + months; // no overflow
}
//-------------------------------------------------------------------------
@@ -1271,7 +916,7 @@
* dateTime = dateTime.plus(thisPeriod);
* </pre>
* <p>
- * The calculation will add the years, then months, then days, then nanos.
+ * The calculation will add the years, then months, then days.
* Only non-zero amounts will be added.
* If the date-time has a calendar system with a fixed number of months in a
* year, then the years and months will be combined before being added.
@@ -1287,10 +932,9 @@
public Temporal addTo(Temporal temporal) {
Objects.requireNonNull(temporal, "temporal");
if ((years | months) != 0) {
- ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR);
- if (startRange.isFixed() && startRange.isIntValue()) {
- long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1;
- temporal = temporal.plus(years * monthCount + months, MONTHS);
+ long monthRange = monthRange(temporal);
+ if (monthRange >= 0) {
+ temporal = temporal.plus(years * monthRange + months, MONTHS);
} else {
if (years != 0) {
temporal = temporal.plus(years, YEARS);
@@ -1303,9 +947,6 @@
if (days != 0) {
temporal = temporal.plus(days, DAYS);
}
- if (nanos != 0) {
- temporal = temporal.plus(nanos, NANOS);
- }
return temporal;
}
@@ -1323,7 +964,7 @@
* dateTime = dateTime.minus(thisPeriod);
* </pre>
* <p>
- * The calculation will subtract the years, then months, then days, then nanos.
+ * The calculation will subtract the years, then months, then days.
* Only non-zero amounts will be subtracted.
* If the date-time has a calendar system with a fixed number of months in a
* year, then the years and months will be combined before being subtracted.
@@ -1339,10 +980,9 @@
public Temporal subtractFrom(Temporal temporal) {
Objects.requireNonNull(temporal, "temporal");
if ((years | months) != 0) {
- ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR);
- if (startRange.isFixed() && startRange.isIntValue()) {
- long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1;
- temporal = temporal.minus(years * monthCount + months, MONTHS);
+ long monthRange = monthRange(temporal);
+ if (monthRange >= 0) {
+ temporal = temporal.minus(years * monthRange + months, MONTHS);
} else {
if (years != 0) {
temporal = temporal.minus(years, YEARS);
@@ -1355,48 +995,21 @@
if (days != 0) {
temporal = temporal.minus(days, DAYS);
}
- if (nanos != 0) {
- temporal = temporal.minus(nanos, NANOS);
- }
return temporal;
}
- //-----------------------------------------------------------------------
/**
- * Converts this period to one that only has time units.
- * <p>
- * The resulting period will have the same time units as this period
- * but the date units will all be zero. No normalization occurs in the calculation.
- * For example, a period of {@code P1Y3MT12H} will be converted to {@code PT12H}.
- * <p>
- * This instance is immutable and unaffected by this method call.
+ * Calculates the range of months based on the temporal.
*
- * @return a {@code Period} based on this period with the date units set to zero, not null
+ * @param temporal the temporal, not null
+ * @return the month range, negative if not fixed range
*/
- public Period toTimeOnly() {
- if ((years | months | days) == 0) {
- return this;
+ private long monthRange(Temporal temporal) {
+ ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR);
+ if (startRange.isFixed() && startRange.isIntValue()) {
+ return startRange.getMaximum() - startRange.getMinimum() + 1;
}
- return create(0, 0, 0, nanos);
- }
-
- //-------------------------------------------------------------------------
- /**
- * Calculates the duration of this period.
- * <p>
- * The calculation uses the hours, minutes, seconds and nanoseconds fields.
- * If years, months or days are present an exception is thrown.
- * See {@link #toTimeOnly()} for a way to remove the date units and
- * {@link #normalizedDaysToHours()} for a way to convert days to hours.
- *
- * @return a {@code Duration} equivalent to this period, not null
- * @throws DateTimeException if the period cannot be converted as it contains years, months or days
- */
- public Duration toDuration() {
- if ((years | months | days) != 0) {
- throw new DateTimeException("Unable to convert period to duration as years/months/days are present: " + this);
- }
- return Duration.ofNanos(nanos);
+ return -1;
}
//-----------------------------------------------------------------------
@@ -1404,7 +1017,9 @@
* Checks if this period is equal to another period.
* <p>
* The comparison is based on the amounts held in the period.
- * To be equal, the years, months, days and normalized time fields must be equal.
+ * To be equal, the years, months and days units must be individually equal.
+ * Note that this means that a period of "15 Months" is not equal to a period
+ * of "1 Year and 3 Months".
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other period
@@ -1416,8 +1031,9 @@
}
if (obj instanceof Period) {
Period other = (Period) obj;
- return years == other.years && months == other.months &&
- days == other.days && nanos == other.nanos;
+ return years == other.years &&
+ months == other.months &&
+ days == other.days;
}
return false;
}
@@ -1429,25 +1045,22 @@
*/
@Override
public int hashCode() {
- // ordered such that overflow from one field doesn't immediately affect the next field
- return ((years << 27) | (years >>> 5)) ^
- ((days << 21) | (days >>> 11)) ^
- ((months << 17) | (months >>> 15)) ^
- ((int) (nanos ^ (nanos >>> 32)));
+ return years + Integer.rotateLeft(months, 8) + Integer.rotateLeft(days, 16);
}
//-----------------------------------------------------------------------
/**
- * Outputs this period as a {@code String}, such as {@code P6Y3M1DT12H}.
+ * Outputs this period as a {@code String}, such as {@code P6Y3M1D}.
* <p>
* The output will be in the ISO-8601 period format.
+ * A zero period will be represented as zero days, 'P0D'.
*
* @return a string representation of this period, not null
*/
@Override
public String toString() {
if (this == ZERO) {
- return "PT0S";
+ return "P0D";
} else {
StringBuilder buf = new StringBuilder();
buf.append('P');
@@ -1460,38 +1073,47 @@
if (days != 0) {
buf.append(days).append('D');
}
- if (nanos != 0) {
- buf.append('T');
- if (getHours() != 0) {
- buf.append(getHours()).append('H');
- }
- if (getMinutes() != 0) {
- buf.append(getMinutes()).append('M');
- }
- int secondPart = getSeconds();
- int nanoPart = getNanos();
- int secsNanosOr = secondPart | nanoPart;
- if (secsNanosOr != 0) { // if either non-zero
- if ((secsNanosOr & Integer.MIN_VALUE) != 0) { // if either less than zero
- buf.append('-');
- secondPart = Math.abs(secondPart);
- nanoPart = Math.abs(nanoPart);
- }
- buf.append(secondPart);
- if (nanoPart != 0) {
- int dotPos = buf.length();
- nanoPart += 1000_000_000;
- while (nanoPart % 10 == 0) {
- nanoPart /= 10;
- }
- buf.append(nanoPart);
- buf.setCharAt(dotPos, '.');
- }
- buf.append('S');
- }
- }
return buf.toString();
}
}
+ //-----------------------------------------------------------------------
+ /**
+ * Writes the object using a
+ * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
+ * <pre>
+ * out.writeByte(14); // identifies this as a Period
+ * out.writeInt(years);
+ * out.writeInt(months);
+ * out.writeInt(seconds);
+ * </pre>
+ *
+ * @return the instance of {@code Ser}, not null
+ */
+ private Object writeReplace() {
+ return new Ser(Ser.PERIOD_TYPE, this);
+ }
+
+ /**
+ * Defend against malicious streams.
+ * @return never
+ * @throws java.io.InvalidObjectException always
+ */
+ private Object readResolve() throws ObjectStreamException {
+ throw new InvalidObjectException("Deserialization via serialization delegate");
+ }
+
+ void writeExternal(DataOutput out) throws IOException {
+ out.writeInt(years);
+ out.writeInt(months);
+ out.writeInt(days);
+ }
+
+ static Period readExternal(DataInput in) throws IOException {
+ int years = in.readInt();
+ int months = in.readInt();
+ int days = in.readInt();
+ return Period.of(years, months, days);
+ }
+
}
diff --git a/src/share/classes/java/time/Ser.java b/src/share/classes/java/time/Ser.java
--- a/src/share/classes/java/time/Ser.java
+++ b/src/share/classes/java/time/Ser.java
@@ -106,6 +106,7 @@
static final byte YEAR_TYPE = 11;
static final byte YEAR_MONTH_TYPE = 12;
static final byte MONTH_DAY_TYPE = 13;
+ static final byte PERIOD_TYPE = 14;
/** The type being serialized. */
private byte type;
@@ -182,6 +183,9 @@
case MONTH_DAY_TYPE:
((MonthDay) object).writeExternal(out);
break;
+ case PERIOD_TYPE:
+ ((Period) object).writeExternal(out);
+ break;
default:
throw new InvalidClassException("Unknown serialized type");
}
@@ -218,6 +222,7 @@
case YEAR_TYPE: return Year.readExternal(in);
case YEAR_MONTH_TYPE: return YearMonth.readExternal(in);
case MONTH_DAY_TYPE: return MonthDay.readExternal(in);
+ case PERIOD_TYPE: return Period.readExternal(in);
default:
throw new StreamCorruptedException("Unknown serialized type");
}
diff --git a/test/java/time/tck/java/time/TCKDuration.java b/test/java/time/tck/java/time/TCKDuration.java
--- a/test/java/time/tck/java/time/TCKDuration.java
+++ b/test/java/time/tck/java/time/TCKDuration.java
@@ -623,7 +623,7 @@
//-----------------------------------------------------------------------
// isZero(), isPositive(), isPositiveOrZero(), isNegative(), isNegativeOrZero()
//-----------------------------------------------------------------------
- @Test(groups={"tck"})
+ @Test
public void test_isZero() {
assertEquals(Duration.ofNanos(0).isZero(), true);
assertEquals(Duration.ofSeconds(0).isZero(), true);
@@ -635,19 +635,7 @@
assertEquals(Duration.ofSeconds(-1, -1).isZero(), false);
}
- @Test(groups={"tck"})
- public void test_isPositive() {
- assertEquals(Duration.ofNanos(0).isPositive(), false);
- assertEquals(Duration.ofSeconds(0).isPositive(), false);
- assertEquals(Duration.ofNanos(1).isPositive(), true);
- assertEquals(Duration.ofSeconds(1).isPositive(), true);
- assertEquals(Duration.ofSeconds(1, 1).isPositive(), true);
- assertEquals(Duration.ofNanos(-1).isPositive(), false);
- assertEquals(Duration.ofSeconds(-1).isPositive(), false);
- assertEquals(Duration.ofSeconds(-1, -1).isPositive(), false);
- }
-
- @Test(groups={"tck"})
+ @Test
public void test_isNegative() {
assertEquals(Duration.ofNanos(0).isNegative(), false);
assertEquals(Duration.ofSeconds(0).isNegative(), false);
@@ -1992,18 +1980,12 @@
Duration b = durations[j];
if (i < j) {
assertEquals(a.compareTo(b)< 0, true, a + " <=> " + b);
- assertEquals(a.isLessThan(b), true, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
assertEquals(a.equals(b), false, a + " <=> " + b);
} else if (i > j) {
assertEquals(a.compareTo(b) > 0, true, a + " <=> " + b);
- assertEquals(a.isLessThan(b), false, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), true, a + " <=> " + b);
assertEquals(a.equals(b), false, a + " <=> " + b);
} else {
assertEquals(a.compareTo(b), 0, a + " <=> " + b);
- assertEquals(a.isLessThan(b), false, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
assertEquals(a.equals(b), true, a + " <=> " + b);
}
}
@@ -2016,18 +1998,6 @@
a.compareTo(null);
}
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_isLessThan_ObjectNull() {
- Duration a = Duration.ofSeconds(0L, 0);
- a.isLessThan(null);
- }
-
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_isGreaterThan_ObjectNull() {
- Duration a = Duration.ofSeconds(0L, 0);
- a.isGreaterThan(null);
- }
-
@Test(expectedExceptions=ClassCastException.class, groups={"tck"})
@SuppressWarnings({ "unchecked", "rawtypes" })
public void compareToNonDuration() {
diff --git a/test/java/time/tck/java/time/TCKInstant.java b/test/java/time/tck/java/time/TCKInstant.java
--- a/test/java/time/tck/java/time/TCKInstant.java
+++ b/test/java/time/tck/java/time/TCKInstant.java
@@ -84,7 +84,6 @@
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
-import java.time.Period;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
@@ -536,6 +535,49 @@
}
//-----------------------------------------------------------------------
+ // plus(TemporalAmount)
+ //-----------------------------------------------------------------------
+ @DataProvider(name="plusTemporalAmount")
+ Object[][] data_plusTemporalAmount() {
+ return new Object[][] {
+ {DAYS, MockSimplePeriod.of(1, DAYS), 86401, 0},
+ {HOURS, MockSimplePeriod.of(2, HOURS), 7201, 0},
+ {MINUTES, MockSimplePeriod.of(4, MINUTES), 241, 0},
+ {SECONDS, MockSimplePeriod.of(5, SECONDS), 6, 0},
+ {NANOS, MockSimplePeriod.of(6, NANOS), 1, 6},
+ {DAYS, MockSimplePeriod.of(10, DAYS), 864001, 0},
+ {HOURS, MockSimplePeriod.of(11, HOURS), 39601, 0},
+ {MINUTES, MockSimplePeriod.of(12, MINUTES), 721, 0},
+ {SECONDS, MockSimplePeriod.of(13, SECONDS), 14, 0},
+ {NANOS, MockSimplePeriod.of(14, NANOS), 1, 14},
+ {SECONDS, Duration.ofSeconds(20, 40), 21, 40},
+ {NANOS, Duration.ofSeconds(30, 300), 31, 300},
+ };
+ }
+
+ @Test(dataProvider="plusTemporalAmount")
+ public void test_plusTemporalAmount(TemporalUnit unit, TemporalAmount amount, int seconds, int nanos) {
+ Instant inst = Instant.ofEpochMilli(1000);
+ Instant actual = inst.plus(amount);
+ Instant expected = Instant.ofEpochSecond(seconds, nanos);
+ assertEquals(actual, expected, "plus(TemporalAmount) failed");
+ }
+
+ @DataProvider(name="badTemporalAmount")
+ Object[][] data_badPlusTemporalAmount() {
+ return new Object[][] {
+ {MockSimplePeriod.of(2, YEARS)},
+ {MockSimplePeriod.of(2, MONTHS)},
+ };
+ }
+
+ @Test(dataProvider="badTemporalAmount",expectedExceptions=DateTimeException.class)
+ public void test_badPlusTemporalAmount(TemporalAmount amount) {
+ Instant inst = Instant.ofEpochMilli(1000);
+ inst.plus(amount);
+ }
+
+ //-----------------------------------------------------------------------
@DataProvider(name="Plus")
Object[][] provider_plus() {
return new Object[][] {
@@ -1613,62 +1655,6 @@
}
//-----------------------------------------------------------------------
- // plus(TemporalAmount)
- //-----------------------------------------------------------------------
- @DataProvider(name="plusTemporalAmount")
- Object[][] data_plusTemporalAmount() {
- return new Object[][] {
- {DAYS, Period.of(1, DAYS), 86401, 0},
- {HOURS, Period.of(2, HOURS), 7201, 0},
- {MINUTES, Period.of(4, MINUTES), 241, 0},
- {SECONDS, Period.of(5, SECONDS), 6, 0},
- {NANOS, Period.of(6, NANOS), 1, 6},
- {DAYS, Period.of(10, DAYS), 864001, 0},
- {HOURS, Period.of(11, HOURS), 39601, 0},
- {MINUTES, Period.of(12, MINUTES), 721, 0},
- {SECONDS, Period.of(13, SECONDS), 14, 0},
- {NANOS, Period.of(14, NANOS), 1, 14},
- {SECONDS, Duration.ofSeconds(20, 40), 21, 40},
- {NANOS, Duration.ofSeconds(30, 300), 31, 300},
- };
- }
-
- @Test(dataProvider="plusTemporalAmount")
- public void test_plusTemporalAmount(TemporalUnit unit, TemporalAmount amount, int seconds, int nanos) {
- Instant inst = Instant.ofEpochMilli(1000);
- Instant actual = inst.plus(amount);
- Instant expected = Instant.ofEpochSecond(seconds, nanos);
- assertEquals(actual, expected, "plus(TemporalAmount) failed");
- }
-
- @DataProvider(name="badTemporalAmount")
- Object[][] data_badPlusTemporalAmount() {
- return new Object[][] {
- {Period.of(2, YEARS)},
- {Period.of(2, MONTHS)},
- };
- }
-
- @Test(dataProvider="badTemporalAmount",expectedExceptions=DateTimeException.class)
- public void test_badPlusTemporalAmount(TemporalAmount amount) {
- Instant inst = Instant.ofEpochMilli(1000);
- inst.plus(amount);
- }
-
- @Test(dataProvider="plusTemporalAmount")
- public void test_completeAndUnique(TemporalUnit theUnit, TemporalAmount amount, int seconds, int nanos) {
- Temporal inst = Instant.ofEpochMilli(1000);
- Temporal expected = inst.plus(amount);
- Temporal accum = inst;
- for (TemporalUnit unit: amount.getUnits()) {
- long delta = amount.get(unit);
- if (delta != 0) {
- accum = accum.plus(delta, unit);
- }
- }
- assertEquals(accum, expected, "adding individual units different than adding whole amoutn");
- }
- //-----------------------------------------------------------------------
// compareTo()
//-----------------------------------------------------------------------
@Test
diff --git a/test/java/time/tck/java/time/TCKLocalDateTime.java b/test/java/time/tck/java/time/TCKLocalDateTime.java
--- a/test/java/time/tck/java/time/TCKLocalDateTime.java
+++ b/test/java/time/tck/java/time/TCKLocalDateTime.java
@@ -88,8 +88,10 @@
import static java.time.temporal.ChronoField.YEAR;
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.MONTHS;
import static java.time.temporal.ChronoUnit.NANOS;
import static java.time.temporal.ChronoUnit.SECONDS;
+import static java.time.temporal.ChronoUnit.YEARS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertSame;
@@ -106,7 +108,6 @@
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
-import java.time.Period;
import java.time.Year;
import java.time.ZoneId;
import java.time.ZoneOffset;
@@ -133,7 +134,6 @@
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import test.java.time.MockSimplePeriod;
/**
* Test LocalDateTime.
@@ -1286,54 +1286,39 @@
}
//-----------------------------------------------------------------------
- // plus(adjuster)
+ // plus(TemporalAmount)
//-----------------------------------------------------------------------
- @Test(groups={"tck"})
- public void test_plus_adjuster() {
- Period p = Period.ofTime(0, 0, 62, 3);
- LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(p);
- assertEquals(t, LocalDateTime.of(2007, 7, 15, 12, 31, 42, 987654324));
- }
-
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_plus_adjuster_null() {
- TEST_2007_07_15_12_30_40_987654321.plus((TemporalAmount) null);
- }
-
- //-----------------------------------------------------------------------
- // plus(Period)
- //-----------------------------------------------------------------------
- @Test(groups={"tck"})
- public void test_plus_Period_positiveMonths() {
- MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+ @Test
+ public void test_plus_TemporalAmount_positiveMonths() {
+ MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
assertEquals(t, LocalDateTime.of(2008, 2, 15, 12, 30, 40, 987654321));
}
- @Test(groups={"tck"})
- public void test_plus_Period_negativeDays() {
- MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
+ @Test
+ public void test_plus_TemporalAmount_negativeDays() {
+ MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
assertEquals(t, LocalDateTime.of(2007, 6, 20, 12, 30, 40, 987654321));
}
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_plus_Period_null() {
- TEST_2007_07_15_12_30_40_987654321.plus((MockSimplePeriod) null);
- }
-
- @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
- public void test_plus_Period_invalidTooLarge() {
- MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_plus_TemporalAmount_invalidTooLarge() {
+ MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).plus(period);
}
- @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
- public void test_plus_Period_invalidTooSmall() {
- MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_plus_TemporalAmount_invalidTooSmall() {
+ MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).plus(period);
}
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_plus_TemporalAmount_null() {
+ TEST_2007_07_15_12_30_40_987654321.plus((TemporalAmount) null);
+ }
+
//-----------------------------------------------------------------------
// plus(long,TemporalUnit)
//-----------------------------------------------------------------------
@@ -1990,54 +1975,39 @@
}
//-----------------------------------------------------------------------
- // minus(adjuster)
+ // minus(TemporalAmount)
//-----------------------------------------------------------------------
- @Test(groups={"tck"})
- public void test_minus_adjuster() {
- Period p = Period.ofTime(0, 0, 62, 3);
- LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(p);
- assertEquals(t, LocalDateTime.of(2007, 7, 15, 12, 29, 38, 987654318));
- }
-
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_minus_adjuster_null() {
- TEST_2007_07_15_12_30_40_987654321.minus((TemporalAmount) null);
- }
-
- //-----------------------------------------------------------------------
- // minus(Period)
- //-----------------------------------------------------------------------
- @Test(groups={"tck"})
- public void test_minus_Period_positiveMonths() {
- MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+ @Test
+ public void test_minus_TemporalAmount_positiveMonths() {
+ MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
assertEquals(t, LocalDateTime.of(2006, 12, 15, 12, 30, 40, 987654321));
}
- @Test(groups={"tck"})
- public void test_minus_Period_negativeDays() {
- MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
+ @Test
+ public void test_minus_TemporalAmount_negativeDays() {
+ MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
assertEquals(t, LocalDateTime.of(2007, 8, 9, 12, 30, 40, 987654321));
}
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_minus_Period_null() {
- TEST_2007_07_15_12_30_40_987654321.minus((MockSimplePeriod) null);
- }
-
- @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
- public void test_minus_Period_invalidTooLarge() {
- MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_minus_TemporalAmount_invalidTooLarge() {
+ MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).minus(period);
}
- @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
- public void test_minus_Period_invalidTooSmall() {
- MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_minus_TemporalAmount_invalidTooSmall() {
+ MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).minus(period);
}
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_minus_TemporalAmount_null() {
+ TEST_2007_07_15_12_30_40_987654321.minus((TemporalAmount) null);
+ }
+
//-----------------------------------------------------------------------
// minus(long,TemporalUnit)
//-----------------------------------------------------------------------
diff --git a/test/java/time/tck/java/time/TCKLocalTime.java b/test/java/time/tck/java/time/TCKLocalTime.java
--- a/test/java/time/tck/java/time/TCKLocalTime.java
+++ b/test/java/time/tck/java/time/TCKLocalTime.java
@@ -125,7 +125,6 @@
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import test.java.time.MockSimplePeriod;
/**
* Test LocalTime.
@@ -1032,41 +1031,41 @@
//-----------------------------------------------------------------------
// plus(TemporalAmount)
//-----------------------------------------------------------------------
- @Test(groups={"tck"})
+ @Test
public void test_plus_TemporalAmount_positiveHours() {
TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
LocalTime t = TEST_12_30_40_987654321.plus(period);
assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
}
- @Test(groups={"tck"})
+ @Test
public void test_plus_TemporalAmount_negativeMinutes() {
TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
LocalTime t = TEST_12_30_40_987654321.plus(period);
assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
}
- @Test(groups={"tck"})
+ @Test
public void test_plus_TemporalAmount_zero() {
TemporalAmount period = Period.ZERO;
LocalTime t = TEST_12_30_40_987654321.plus(period);
assertEquals(t, TEST_12_30_40_987654321);
}
- @Test(groups={"tck"})
+ @Test
public void test_plus_TemporalAmount_wrap() {
- TemporalAmount p = Period.ofHours(1);
+ TemporalAmount p = MockSimplePeriod.of(1, HOURS);
LocalTime t = LocalTime.of(23, 30).plus(p);
assertEquals(t, LocalTime.of(0, 30));
}
- @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
+ @Test(expectedExceptions=DateTimeException.class)
public void test_plus_TemporalAmount_dateNotAllowed() {
TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
TEST_12_30_40_987654321.plus(period);
}
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+ @Test(expectedExceptions=NullPointerException.class)
public void test_plus_TemporalAmount_null() {
TEST_12_30_40_987654321.plus((TemporalAmount) null);
}
@@ -1466,55 +1465,41 @@
//-----------------------------------------------------------------------
// minus(TemporalAmount)
//-----------------------------------------------------------------------
- @Test(groups={"tck"})
- public void test_minus_TemporalAmount() {
- TemporalAmount p = Period.ofTime(0, 0, 62, 3);
- LocalTime t = TEST_12_30_40_987654321.minus(p);
- assertEquals(t, LocalTime.of(12, 29, 38, 987654318));
- }
-
- @Test(groups={"tck"})
+ @Test
public void test_minus_TemporalAmount_positiveHours() {
TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
LocalTime t = TEST_12_30_40_987654321.minus(period);
assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
}
- @Test(groups={"tck"})
+ @Test
public void test_minus_TemporalAmount_negativeMinutes() {
TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
LocalTime t = TEST_12_30_40_987654321.minus(period);
assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
}
- @Test(groups={"tck"})
- public void test_minus_TemporalAmount_big1() {
- TemporalAmount p = Period.ofTime(0, 0, 0, Long.MAX_VALUE);
- LocalTime t = TEST_12_30_40_987654321.minus(p);
- assertEquals(t, TEST_12_30_40_987654321.minusNanos(Long.MAX_VALUE));
- }
-
- @Test(groups={"tck"})
+ @Test
public void test_minus_TemporalAmount_zero() {
- TemporalAmount p = Period.ZERO;
- LocalTime t = TEST_12_30_40_987654321.minus(p);
+ TemporalAmount period = Period.ZERO;
+ LocalTime t = TEST_12_30_40_987654321.minus(period);
assertEquals(t, TEST_12_30_40_987654321);
}
- @Test(groups={"tck"})
+ @Test
public void test_minus_TemporalAmount_wrap() {
- TemporalAmount p = Period.ofHours(1);
+ TemporalAmount p = MockSimplePeriod.of(1, HOURS);
LocalTime t = LocalTime.of(0, 30).minus(p);
assertEquals(t, LocalTime.of(23, 30));
}
- @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
+ @Test(expectedExceptions=DateTimeException.class)
public void test_minus_TemporalAmount_dateNotAllowed() {
TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
TEST_12_30_40_987654321.minus(period);
}
- @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+ @Test(expectedExceptions=NullPointerException.class)
public void test_minus_TemporalAmount_null() {
TEST_12_30_40_987654321.minus((TemporalAmount) null);
}
diff --git a/test/java/time/tck/java/time/TCKPeriod.java b/test/java/time/tck/java/time/TCKPeriod.java
--- a/test/java/time/tck/java/time/TCKPeriod.java
+++ b/test/java/time/tck/java/time/TCKPeriod.java
@@ -59,25 +59,16 @@
*/
package tck.java.time;
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.HALF_DAYS;
-import static java.time.temporal.ChronoUnit.HOURS;
-import static java.time.temporal.ChronoUnit.MICROS;
-import static java.time.temporal.ChronoUnit.MILLIS;
-import static java.time.temporal.ChronoUnit.MINUTES;
-import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
-import static java.time.temporal.ChronoUnit.SECONDS;
-import static java.time.temporal.ChronoUnit.YEARS;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import java.time.Duration;
+import java.time.DateTimeException;
+import java.time.LocalDate;
import java.time.Period;
-import java.time.DateTimeException;
+import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.List;
+import java.util.Locale;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -89,418 +80,522 @@
public class TCKPeriod extends AbstractTCKTest {
//-----------------------------------------------------------------------
- // of(int7)
- //-----------------------------------------------------------------------
@Test
- public void factory_of_7ints() {
- assertPeriod(Period.of(1, 2, 3, 4, 5, 6, 0), 1, 2, 3, 4, 5, 6, 0);
- assertPeriod(Period.of(0, 2, 3, 4, 5, 6, 0), 0, 2, 3, 4, 5, 6, 0);
- assertPeriod(Period.of(1, 0, 0, 0, 0, 0, 0), 1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(0, 0, 0, 0, 0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, -2, -3, -4, -5, -6, 0), -1, -2, -3, -4, -5, -6, 0);
+ public void test_serialization() throws Exception {
+ assertSerializable(Period.ZERO);
+ assertSerializable(Period.ofDays(1));
+ assertSerializable(Period.of(1, 2, 3));
}
//-----------------------------------------------------------------------
- // ofDate(int3)
+ // ofYears(int)
//-----------------------------------------------------------------------
@Test
- public void factory_ofDate_ints() {
- assertPeriod(Period.ofDate(1, 2, 3), 1, 2, 3, 0, 0, 0, 0);
- assertPeriod(Period.ofDate(0, 2, 3), 0, 2, 3, 0, 0, 0, 0);
- assertPeriod(Period.ofDate(1, 0, 0), 1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofDate(0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofDate(-1, -2, -3), -1, -2, -3, 0, 0, 0, 0);
+ public void factory_ofYears_int() {
+ assertPeriod(Period.ofYears(0), 0, 0, 0);
+ assertPeriod(Period.ofYears(1), 1, 0, 0);
+ assertPeriod(Period.ofYears(234), 234, 0, 0);
+ assertPeriod(Period.ofYears(-100), -100, 0, 0);
+ assertPeriod(Period.ofYears(Integer.MAX_VALUE), Integer.MAX_VALUE, 0, 0);
+ assertPeriod(Period.ofYears(Integer.MIN_VALUE), Integer.MIN_VALUE, 0, 0);
}
//-----------------------------------------------------------------------
- // ofTime(int4)
+ // ofMonths(int)
//-----------------------------------------------------------------------
@Test
- public void factory_ofTime_4ints() {
- assertPeriod(Period.ofTime(1, 2, 3, 4), 0, 0, 0, 1, 2, 3, 4);
- assertPeriod(Period.ofTime(0, 2, 3, 4), 0, 0, 0, 0, 2, 3, 4);
- assertPeriod(Period.ofTime(1, 0, 0, 0), 0, 0, 0, 1, 0, 0, 0);
- assertPeriod(Period.ofTime(0, 0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofTime(-1, -2, -3, -4), 0, 0, 0, -1, -2, -3, -4);
+ public void factory_ofMonths_int() {
+ assertPeriod(Period.ofMonths(0), 0, 0, 0);
+ assertPeriod(Period.ofMonths(1), 0, 1, 0);
+ assertPeriod(Period.ofMonths(234), 0, 234, 0);
+ assertPeriod(Period.ofMonths(-100), 0, -100, 0);
+ assertPeriod(Period.ofMonths(Integer.MAX_VALUE), 0, Integer.MAX_VALUE, 0);
+ assertPeriod(Period.ofMonths(Integer.MIN_VALUE), 0, Integer.MIN_VALUE, 0);
}
//-----------------------------------------------------------------------
- // of(long,TemporalUnit)
+ // ofDays(int)
//-----------------------------------------------------------------------
@Test
- public void factory_of_longUnit() {
- assertEquals(Period.of(1, YEARS), Period.of(1, YEARS));
- assertEquals(Period.of(2, MONTHS), Period.of(2, MONTHS));
- assertEquals(Period.of(3, DAYS), Period.of(3, DAYS));
+ public void factory_ofDay_int() {
+ assertPeriod(Period.ofDays(0), 0, 0, 0);
+ assertPeriod(Period.ofDays(1), 0, 0, 1);
+ assertPeriod(Period.ofDays(234), 0, 0, 234);
+ assertPeriod(Period.ofDays(-100), 0, 0, -100);
+ assertPeriod(Period.ofDays(Integer.MAX_VALUE), 0, 0, Integer.MAX_VALUE);
+ assertPeriod(Period.ofDays(Integer.MIN_VALUE), 0, 0, Integer.MIN_VALUE);
+ }
- assertEquals(Period.of(1, HALF_DAYS), Period.of(12, HOURS));
- assertEquals(Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS), Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS));
- assertEquals(Period.of(-1, MINUTES), Period.of(-1, MINUTES));
- assertEquals(Period.of(-2, SECONDS), Period.of(-2, SECONDS));
- assertEquals(Period.of(Integer.MIN_VALUE, NANOS), Period.of(Integer.MIN_VALUE, NANOS));
- assertEquals(Period.of(2, MILLIS), Period.of(2000000, NANOS));
- assertEquals(Period.of(2, MICROS), Period.of(2000, NANOS));
+ //-----------------------------------------------------------------------
+ // of(int3)
+ //-----------------------------------------------------------------------
+ @Test
+ public void factory_of_ints() {
+ assertPeriod(Period.of(1, 2, 3), 1, 2, 3);
+ assertPeriod(Period.of(0, 2, 3), 0, 2, 3);
+ assertPeriod(Period.of(1, 0, 0), 1, 0, 0);
+ assertPeriod(Period.of(0, 0, 0), 0, 0, 0);
+ assertPeriod(Period.of(-1, -2, -3), -1, -2, -3);
+ }
+
+ //-----------------------------------------------------------------------
+ // parse(String)
+ //-----------------------------------------------------------------------
+ @DataProvider(name="parseSuccess")
+ Object[][] data_factory_parseSuccess() {
+ return new Object[][] {
+ {"P1Y", Period.ofYears(1)},
+ {"P12Y", Period.ofYears(12)},
+ {"P987654321Y", Period.ofYears(987654321)},
+ {"P+1Y", Period.ofYears(1)},
+ {"P+12Y", Period.ofYears(12)},
+ {"P+987654321Y", Period.ofYears(987654321)},
+ {"P+0Y", Period.ofYears(0)},
+ {"P0Y", Period.ofYears(0)},
+ {"P-0Y", Period.ofYears(0)},
+ {"P-25Y", Period.ofYears(-25)},
+ {"P-987654321Y", Period.ofYears(-987654321)},
+ {"P" + Integer.MAX_VALUE + "Y", Period.ofYears(Integer.MAX_VALUE)},
+ {"P" + Integer.MIN_VALUE + "Y", Period.ofYears(Integer.MIN_VALUE)},
+
+ {"P1M", Period.ofMonths(1)},
+ {"P12M", Period.ofMonths(12)},
+ {"P987654321M", Period.ofMonths(987654321)},
+ {"P+1M", Period.ofMonths(1)},
+ {"P+12M", Period.ofMonths(12)},
+ {"P+987654321M", Period.ofMonths(987654321)},
+ {"P+0M", Period.ofMonths(0)},
+ {"P0M", Period.ofMonths(0)},
+ {"P-0M", Period.ofMonths(0)},
+ {"P-25M", Period.ofMonths(-25)},
+ {"P-987654321M", Period.ofMonths(-987654321)},
+ {"P" + Integer.MAX_VALUE + "M", Period.ofMonths(Integer.MAX_VALUE)},
+ {"P" + Integer.MIN_VALUE + "M", Period.ofMonths(Integer.MIN_VALUE)},
+
+ {"P1D", Period.ofDays(1)},
+ {"P12D", Period.ofDays(12)},
+ {"P987654321D", Period.ofDays(987654321)},
+ {"P+1D", Period.ofDays(1)},
+ {"P+12D", Period.ofDays(12)},
+ {"P+987654321D", Period.ofDays(987654321)},
+ {"P+0D", Period.ofDays(0)},
+ {"P0D", Period.ofDays(0)},
+ {"P-0D", Period.ofDays(0)},
+ {"P-25D", Period.ofDays(-25)},
+ {"P-987654321D", Period.ofDays(-987654321)},
+ {"P" + Integer.MAX_VALUE + "D", Period.ofDays(Integer.MAX_VALUE)},
+ {"P" + Integer.MIN_VALUE + "D", Period.ofDays(Integer.MIN_VALUE)},
+
+ {"P0Y0M0D", Period.of(0, 0, 0)},
+ {"P2Y0M0D", Period.of(2, 0, 0)},
+ {"P0Y3M0D", Period.of(0, 3, 0)},
+ {"P0Y0M4D", Period.of(0, 0, 4)},
+ {"P2Y3M25D", Period.of(2, 3, 25)},
+ {"P-2Y3M25D", Period.of(-2, 3, 25)},
+ {"P2Y-3M25D", Period.of(2, -3, 25)},
+ {"P2Y3M-25D", Period.of(2, 3, -25)},
+ {"P-2Y-3M-25D", Period.of(-2, -3, -25)},
+ };
+ }
+
+ @Test(dataProvider="parseSuccess")
+ public void factory_parse(String text, Period expected) {
+ Period p = Period.parse(text);
+ assertEquals(p, expected);
+ }
+
+ @Test(dataProvider="parseSuccess")
+ public void factory_parse_plus(String text, Period expected) {
+ Period p = Period.parse("+" + text);
+ assertEquals(p, expected);
+ }
+
+ @Test(dataProvider="parseSuccess")
+ public void factory_parse_minus(String text, Period expected) {
+ Period p = null;
+ try {
+ p = Period.parse("-" + text);
+ } catch (DateTimeParseException ex) {
+ assertEquals(expected.getYears() == Integer.MIN_VALUE ||
+ expected.getMonths() == Integer.MIN_VALUE ||
+ expected.getDays() == Integer.MIN_VALUE, true);
+ return;
+ }
+ // not inside try/catch or it breaks test
+ assertEquals(p, expected.negated());
+ }
+
+ @Test(dataProvider="parseSuccess")
+ public void factory_parse_lowerCase(String text, Period expected) {
+ Period p = Period.parse(text.toLowerCase(Locale.ENGLISH));
+ assertEquals(p, expected);
+ }
+
+ @DataProvider(name="parseFailure")
+ Object[][] data_parseFailure() {
+ return new Object[][] {
+ {""},
+ {"PTD"},
+ {"AT0D"},
+ {"PA0D"},
+ {"PT0A"},
+
+ {"PT+D"},
+ {"PT-D"},
+ {"PT.D"},
+ {"PTAD"},
+
+ {"PT+0D"},
+ {"PT-0D"},
+ {"PT+1D"},
+ {"PT-.D"},
+
+ {"P1Y1MT1D"},
+ {"P1YMD"},
+ {"P1Y2Y"},
+ {"PT1M+3S"},
+
+ {"PT1S1"},
+ {"PT1S."},
+ {"PT1SA"},
+ {"PT1M1"},
+ {"PT1M."},
+ {"PT1MA"},
+
+ {"P"+ (((long) Integer.MAX_VALUE) + 1) + "Y"},
+ {"P"+ (((long) Integer.MAX_VALUE) + 1) + "M"},
+ {"P"+ (((long) Integer.MAX_VALUE) + 1) + "D"},
+ {"P"+ (((long) Integer.MIN_VALUE) - 1) + "Y"},
+ {"P"+ (((long) Integer.MIN_VALUE) - 1) + "M"},
+ {"P"+ (((long) Integer.MIN_VALUE) - 1) + "D"},
+
+ {"Rubbish"},
+ };
+ }
+
+ @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
+ public void factory_parseFailures(String text) {
+ try {
+ Period.parse(text);
+ } catch (DateTimeParseException ex) {
+ assertEquals(ex.getParsedString(), text);
+ throw ex;
+ }
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void factory_parse_null() {
+ Period.parse(null);
+ }
+
+ //-----------------------------------------------------------------------
+ // between(LocalDate,LocalDate)
+ //-----------------------------------------------------------------------
+ @DataProvider(name="between")
+ Object[][] data_between() {
+ return new Object[][] {
+ {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
+ {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
+ {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
+ {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
+ {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
+ {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
+ {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
+ {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
+ {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
+ {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
+
+ {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
+ {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
+ {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
+ {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
+ {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
+ {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
+ {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
+ {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
+ {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
+ {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
+ {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
+ {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
+ {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
+ {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
+ {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
+ {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
+ {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
+
+ {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
+ {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
+
+ {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
+ {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
+ {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
+
+ {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
+ {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
+ {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
+
+ {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
+ {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
+ {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
+
+ {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
+ {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
+ {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
+
+ {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
+ {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
+ {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
+ {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
+ {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
+ {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
+ {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
+ {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
+ {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
+
+ {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
+ {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
+ {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
+ {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
+ {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
+ {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
+ {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
+
+ {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
+ {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
+ {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
+
+ {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
+ {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
+ {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
+
+ {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
+ {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
+ {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
+
+ {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
+ {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
+ {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
+ };
+ }
+
+ @Test(dataProvider="between")
+ public void factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
+ LocalDate start = LocalDate.of(y1, m1, d1);
+ LocalDate end = LocalDate.of(y2, m2, d2);
+ Period test = Period.between(start, end);
+ assertPeriod(test, ye, me, de);
+ //assertEquals(start.plus(test), end);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void factory_between_LocalDate_nullFirst() {
+ Period.between((LocalDate) null, LocalDate.of(2010, 1, 1));
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void factory_between_LocalDate_nullSecond() {
+ Period.between(LocalDate.of(2010, 1, 1), (LocalDate) null);
+ }
+
+ //-----------------------------------------------------------------------
+ // isZero()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_isZero() {
+ assertEquals(Period.of(0, 0, 0).isZero(), true);
+ assertEquals(Period.of(1, 2, 3).isZero(), false);
+ assertEquals(Period.of(1, 0, 0).isZero(), false);
+ assertEquals(Period.of(0, 2, 0).isZero(), false);
+ assertEquals(Period.of(0, 0, 3).isZero(), false);
+ }
+
+ //-----------------------------------------------------------------------
+ // isNegative()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_isPositive() {
+ assertEquals(Period.of(0, 0, 0).isNegative(), false);
+ assertEquals(Period.of(1, 2, 3).isNegative(), false);
+ assertEquals(Period.of(1, 0, 0).isNegative(), false);
+ assertEquals(Period.of(0, 2, 0).isNegative(), false);
+ assertEquals(Period.of(0, 0, 3).isNegative(), false);
+
+ assertEquals(Period.of(-1, -2, -3).isNegative(), true);
+ assertEquals(Period.of(-1, -2, 3).isNegative(), true);
+ assertEquals(Period.of(1, -2, -3).isNegative(), true);
+ assertEquals(Period.of(-1, 2, -3).isNegative(), true);
+ assertEquals(Period.of(-1, 2, 3).isNegative(), true);
+ assertEquals(Period.of(1, -2, 3).isNegative(), true);
+ assertEquals(Period.of(1, 2, -3).isNegative(), true);
+ }
+
+ //-----------------------------------------------------------------------
+ // withYears()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_withYears() {
+ assertPeriod(Period.of(1, 2, 3).withYears(1), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).withYears(10), 10, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).withYears(-10), -10, 2, 3);
+ assertPeriod(Period.of(-1, -2, -3).withYears(10), 10, -2, -3);
+ assertPeriod(Period.of(1, 2, 3).withYears(0), 0, 2, 3);
+ }
+
+ //-----------------------------------------------------------------------
+ // withMonths()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_withMonths() {
+ assertPeriod(Period.of(1, 2, 3).withMonths(2), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).withMonths(10), 1, 10, 3);
+ assertPeriod(Period.of(1, 2, 3).withMonths(-10), 1, -10, 3);
+ assertPeriod(Period.of(-1, -2, -3).withMonths(10), -1, 10, -3);
+ assertPeriod(Period.of(1, 2, 3).withMonths(0), 1, 0, 3);
+ }
+
+ //-----------------------------------------------------------------------
+ // withDays()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_withDays() {
+ assertPeriod(Period.of(1, 2, 3).withDays(3), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).withDays(10), 1, 2, 10);
+ assertPeriod(Period.of(1, 2, 3).withDays(-10), 1, 2, -10);
+ assertPeriod(Period.of(-1, -2, -3).withDays(10), -1, -2, 10);
+ assertPeriod(Period.of(1, 2, 3).withDays(0), 1, 2, 0);
+ }
+
+ //-----------------------------------------------------------------------
+ // plusYears()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_plusYears() {
+ assertPeriod(Period.of(1, 2, 3).plusYears(0), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).plusYears(10), 11, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).plusYears(-10), -9, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).plusYears(-1), 0, 2, 3);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusYears_overflowTooBig() {
+ Period test = Period.ofYears(Integer.MAX_VALUE);
+ test.plusYears(1);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusYears_overflowTooSmall() {
+ Period test = Period.ofYears(Integer.MIN_VALUE);
+ test.plusYears(-1);
+ }
+
+ //-----------------------------------------------------------------------
+ // plusMonths()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_plusMonths() {
+ assertPeriod(Period.of(1, 2, 3).plusMonths(0), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).plusMonths(10), 1, 12, 3);
+ assertPeriod(Period.of(1, 2, 3).plusMonths(-10), 1, -8, 3);
+ assertPeriod(Period.of(1, 2, 3).plusMonths(-2), 1, 0, 3);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusMonths_overflowTooBig() {
+ Period test = Period.ofMonths(Integer.MAX_VALUE);
+ test.plusMonths(1);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusMonths_overflowTooSmall() {
+ Period test = Period.ofMonths(Integer.MIN_VALUE);
+ test.plusMonths(-1);
+ }
+
+ //-----------------------------------------------------------------------
+ // plusDays()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_plusDays() {
+ assertPeriod(Period.of(1, 2, 3).plusDays(0), 1, 2, 3);
+ assertPeriod(Period.of(1, 2, 3).plusDays(10), 1, 2, 13);
+ assertPeriod(Period.of(1, 2, 3).plusDays(-10), 1, 2, -7);
+ assertPeriod(Period.of(1, 2, 3).plusDays(-3), 1, 2, 0);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusDays_overflowTooBig() {
+ Period test = Period.ofDays(Integer.MAX_VALUE);
+ test.plusDays(1);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_plusDays_overflowTooSmall() {
+ Period test = Period.ofDays(Integer.MIN_VALUE);
+ test.plusDays(-1);
+ }
+
+ //-----------------------------------------------------------------------
+ // multipliedBy()
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_multipliedBy() {
+ Period test = Period.of(1, 2, 3);
+ assertPeriod(test.multipliedBy(0), 0, 0, 0);
+ assertPeriod(test.multipliedBy(1), 1, 2, 3);
+ assertPeriod(test.multipliedBy(2), 2, 4, 6);
+ assertPeriod(test.multipliedBy(-3), -3, -6, -9);
}
@Test
- public void factory_of_longUnit_years() {
- assertPeriod(Period.of(1, YEARS), 1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(0, YEARS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, YEARS), -1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MAX_VALUE, YEARS), Integer.MAX_VALUE, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MIN_VALUE, YEARS), Integer.MIN_VALUE, 0, 0, 0, 0, 0, 0);
+ public void test_multipliedBy_zeroBase() {
+ assertPeriod(Period.ZERO.multipliedBy(2), 0, 0, 0);
}
- @Test
- public void factory_of_longUnit_months() {
- assertPeriod(Period.of(1, MONTHS), 0, 1, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(0, MONTHS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, MONTHS), 0, -1, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MAX_VALUE, MONTHS), 0, Integer.MAX_VALUE, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MIN_VALUE, MONTHS), 0, Integer.MIN_VALUE, 0, 0, 0, 0, 0);
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_multipliedBy_overflowTooBig() {
+ Period test = Period.ofYears(Integer.MAX_VALUE / 2 + 1);
+ test.multipliedBy(2);
}
- @Test
- public void factory_of_longUnit_days() {
- assertPeriod(Period.of(1, DAYS), 0, 0, 1, 0, 0, 0, 0);
- assertPeriod(Period.of(0, DAYS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, DAYS), 0, 0, -1, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MAX_VALUE, DAYS), 0, 0, Integer.MAX_VALUE, 0, 0, 0, 0);
- assertPeriod(Period.of(Integer.MIN_VALUE, DAYS), 0, 0, Integer.MIN_VALUE, 0, 0, 0, 0);
- }
-
- @Test
- public void factory_of_longUnit_hours() {
- assertPeriod(Period.of(1, HOURS), 0, 0, 0, 1, 0, 0, 0);
- assertPeriod(Period.of(0, HOURS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, HOURS), 0, 0, 0, -1, 0, 0, 0);
- assertPeriod(Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS), 0, 0, 0, Integer.MAX_VALUE / (3600 * 8), 0, 0, 0);
- assertPeriod(Period.of(Integer.MIN_VALUE / (3600 * 8), HOURS), 0, 0, 0, Integer.MIN_VALUE / (3600 * 8), 0, 0, 0);
- }
-
- @Test
- public void factory_of_longUnit_minutes() {
- assertPeriod(Period.of(1, MINUTES), 0, 0, 0, 0, 1, 0, 0);
- assertPeriod(Period.of(0, MINUTES), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, MINUTES), 0, 0, 0, 0, -1, 0, 0);
- int val = Integer.MAX_VALUE / (60 * 8);
- assertPeriod(Period.of(val, MINUTES), 0, 0, 0,
- (int) (val / 60L),
- (int) (val % 60),
- 0, 0);
- val = Integer.MIN_VALUE / (60 * 8);
- assertPeriod(Period.of(val, MINUTES), 0, 0, 0,
- (int) (val / 60L),
- (int) (val % 60),
- 0, 0);
- }
-
- @Test
- public void factory_of_longUnit_seconds() {
- assertPeriod(Period.of(1, SECONDS), 0, 0, 0, 0, 0, 1, 0);
- assertPeriod(Period.of(0, SECONDS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, SECONDS), 0, 0, 0, 0, 0, -1, 0);
- assertPeriod(Period.of(Integer.MAX_VALUE, SECONDS), 0, 0, 0,
- (int) (Integer.MAX_VALUE / 3600L),
- (int) ((Integer.MAX_VALUE / 60L) % 60),
- (int) (Integer.MAX_VALUE % 60),
- 0);
- assertPeriod(Period.of(Integer.MIN_VALUE, SECONDS), 0, 0, 0,
- (int) (Integer.MIN_VALUE / 3600L),
- (int) ((Integer.MIN_VALUE / 60L) % 60),
- (int) (Integer.MIN_VALUE % 60),
- 0);
- }
-
- @Test
- public void factory_nanos() {
- assertPeriod(Period.of(1, NANOS), 0, 0, 0, 0, 0, 0, 1);
- assertPeriod(Period.of(0, NANOS), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.of(-1, NANOS), 0, 0, 0, 0, 0, 0, -1);
- assertPeriod(Period.of(Long.MAX_VALUE, NANOS), 0, 0, 0,
- (int) (Long.MAX_VALUE / 3600_000_000_000L),
- (int) ((Long.MAX_VALUE / 60_000_000_000L) % 60),
- (int) ((Long.MAX_VALUE / 1_000_000_000L) % 60),
- Long.MAX_VALUE % 1_000_000_000L);
- assertPeriod(Period.of(Long.MIN_VALUE, NANOS), 0, 0, 0,
- (int) (Long.MIN_VALUE / 3600_000_000_000L),
- (int) ((Long.MIN_VALUE / 60_000_000_000L) % 60),
- (int) ((Long.MIN_VALUE / 1_000_000_000L) % 60),
- Long.MIN_VALUE % 1_000_000_000L);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_of_longUnit_null() {
- Period.of(1, null);
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_multipliedBy_overflowTooSmall() {
+ Period test = Period.ofYears(Integer.MIN_VALUE / 2 - 1);
+ test.multipliedBy(2);
}
//-----------------------------------------------------------------------
+ // negated()
+ //-----------------------------------------------------------------------
@Test
- public void factory_ofYears() {
- assertPeriod(Period.ofYears(1), 1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofYears(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofYears(-1), -1, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofYears(Integer.MAX_VALUE), Integer.MAX_VALUE, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofYears(Integer.MIN_VALUE), Integer.MIN_VALUE, 0, 0, 0, 0, 0, 0);
+ public void test_negated() {
+ assertPeriod(Period.of(0, 0, 0).negated(), 0 ,0, 0);
+ assertPeriod(Period.of(1, 2, 3).negated(), -1, -2, -3);
+ assertPeriod(Period.of(-1, -2, -3).negated(), 1, 2, 3);
+ assertPeriod(Period.of(-1, 2, -3).negated(), 1, -2, 3);
+ assertPeriod(Period.of(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).negated(),
+ -Integer.MAX_VALUE, -Integer.MAX_VALUE, -Integer.MAX_VALUE);
}
- @Test
- public void factory_ofMonths() {
- assertPeriod(Period.ofMonths(1), 0, 1, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofMonths(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofMonths(-1), 0, -1, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofMonths(Integer.MAX_VALUE), 0, Integer.MAX_VALUE, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofMonths(Integer.MIN_VALUE), 0, Integer.MIN_VALUE, 0, 0, 0, 0, 0);
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_negated_overflow_years() {
+ Period.ofYears(Integer.MIN_VALUE).negated();
}
- @Test
- public void factory_ofDays() {
- assertPeriod(Period.ofDays(1), 0, 0, 1, 0, 0, 0, 0);
- assertPeriod(Period.ofDays(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofDays(-1), 0, 0, -1, 0, 0, 0, 0);
- assertPeriod(Period.ofDays(Integer.MAX_VALUE), 0, 0, Integer.MAX_VALUE, 0, 0, 0, 0);
- assertPeriod(Period.ofDays(Integer.MIN_VALUE), 0, 0, Integer.MIN_VALUE, 0, 0, 0, 0);
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_negated_overflow_months() {
+ Period.ofMonths(Integer.MIN_VALUE).negated();
}
- @Test
- public void factory_ofHours() {
- assertPeriod(Period.ofHours(1), 0, 0, 0, 1, 0, 0, 0);
- assertPeriod(Period.ofHours(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofHours(-1), 0, 0, 0, -1, 0, 0, 0);
- assertPeriod(Period.ofHours(Integer.MAX_VALUE / (3600 * 8)), 0, 0, 0, Integer.MAX_VALUE / (3600 * 8), 0, 0, 0);
- assertPeriod(Period.ofHours(Integer.MIN_VALUE / (3600 * 8)), 0, 0, 0, Integer.MIN_VALUE / (3600 * 8), 0, 0, 0);
- }
-
- @Test
- public void factory_ofMinutes() {
- assertPeriod(Period.ofMinutes(1), 0, 0, 0, 0, 1, 0, 0);
- assertPeriod(Period.ofMinutes(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofMinutes(-1), 0, 0, 0, 0, -1, 0, 0);
- int val = Integer.MAX_VALUE / (60 * 8);
- assertPeriod(Period.ofMinutes(val), 0, 0, 0,
- (int) (val / 60L),
- (int) (val % 60),
- 0, 0);
- val = Integer.MIN_VALUE / (60 * 8);
- assertPeriod(Period.ofMinutes(val), 0, 0, 0,
- (int) (val / 60L),
- (int) (val % 60),
- 0, 0);
- }
-
- @Test
- public void factory_ofSeconds() {
- assertPeriod(Period.ofSeconds(1), 0, 0, 0, 0, 0, 1, 0);
- assertPeriod(Period.ofSeconds(0), 0, 0, 0, 0, 0, 0, 0);
- assertPeriod(Period.ofSeconds(-1), 0, 0, 0, 0, 0, -1, 0);
- assertPeriod(Period.ofSeconds(Integer.MAX_VALUE), 0, 0, 0,
- (int) (Integer.MAX_VALUE / 3600L),
- (int) ((Integer.MAX_VALUE / 60L) % 60),
- (int) (Integer.MAX_VALUE % 60),
- 0);
- assertPeriod(Period.ofSeconds(Integer.MIN_VALUE), 0, 0, 0,
- (int) (Integer.MIN_VALUE / 3600L),
- (int) ((Integer.MIN_VALUE / 60L) % 60),
- (int) (Integer.MIN_VALUE % 60),
- 0);
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void test_negated_overflow_days() {
+ Period.ofDays(Integer.MIN_VALUE).negated();
}
//-----------------------------------------------------------------------
- // of(Duration)
+ // normalized()
//-----------------------------------------------------------------------
- @Test
- public void factory_duration() {
- assertPeriod(Period.of(Duration.ofSeconds(2, 3)), 0, 0, 0, 0, 0, 2, 3);
- assertPeriod(Period.of(Duration.ofSeconds(59, 3)), 0, 0, 0, 0, 0, 59, 3);
- assertPeriod(Period.of(Duration.ofSeconds(60, 3)), 0, 0, 0, 0, 1, 0, 3);
- assertPeriod(Period.of(Duration.ofSeconds(61, 3)), 0, 0, 0, 0, 1, 1, 3);
- assertPeriod(Period.of(Duration.ofSeconds(3599, 3)), 0, 0, 0, 0, 59, 59, 3);
- assertPeriod(Period.of(Duration.ofSeconds(3600, 3)), 0, 0, 0, 1, 0, 0, 3);
- }
-
- @Test
- public void factory_duration_negative() {
- assertPeriod(Period.of(Duration.ofSeconds(-2, 3)), 0, 0, 0, 0, 0, -1, -999999997);
- assertPeriod(Period.of(Duration.ofSeconds(-59, 3)), 0, 0, 0, 0, 0, -58, -999999997);
- assertPeriod(Period.of(Duration.ofSeconds(-60, 3)), 0, 0, 0, 0, 0, -59, -999999997);
- assertPeriod(Period.of(Duration.ofSeconds(-60, -3)), 0, 0, 0, 0, -1, 0, -3);
-
- assertPeriod(Period.of(Duration.ofSeconds(2, -3)), 0, 0, 0, 0, 0, 1, 999999997);
- }
-
- @Test
- public void factory_duration_big() {
- Duration dur = Duration.ofSeconds(Integer.MAX_VALUE, 3);
- long secs = Integer.MAX_VALUE;
- assertPeriod(Period.of(dur), 0, 0, 0, (int) (secs / 3600), (int) ((secs % 3600) / 60), (int) (secs % 60), 3);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_duration_null() {
- Period.of((Duration) null);
- }
-
- //-----------------------------------------------------------------------
- // withTime(Duration)
- //-----------------------------------------------------------------------
- @Test
- public void test_withTime_duration() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.withTime(Duration.ofSeconds(10)), 1, 2, 3, 0, 0, 10, 0);
- }
-
- @Test
- public void test_withTime_duration_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.withTime(Duration.ofNanos(((4 * 60 + 5) * 60 + 6) * 1_000_000_000L + 7)), test);
- }
-
- @Test
- public void test_withTime_duration_toZero() {
- Period test = Period.of(1, NANOS);
- assertEquals(test.withTime(Duration.ZERO), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // normalizedHoursToDays()
- //-----------------------------------------------------------------------
- @DataProvider(name="normalizedHoursToDays")
- Object[][] data_normalizedHoursToDays() {
- return new Object[][] {
- {0, 0, 0, 0},
- {1, 0, 1, 0},
- {-1, 0, -1, 0},
-
- {1, 1, 1, 1},
- {1, 23, 1, 23},
- {1, 24, 2, 0},
- {1, 25, 2, 1},
-
- {1, -1, 0, 23},
- {1, -23, 0, 1},
- {1, -24, 0, 0},
- {1, -25, 0, -1},
- {1, -47, 0, -23},
- {1, -48, -1, 0},
- {1, -49, -1, -1},
-
- {-1, 1, 0, -23},
- {-1, 23, 0, -1},
- {-1, 24, 0, 0},
- {-1, 25, 0, 1},
- {-1, 47, 0, 23},
- {-1, 48, 1, 0},
- {-1, 49, 1, 1},
-
- {-1, -1, -1, -1},
- {-1, -23, -1, -23},
- {-1, -24, -2, 0},
- {-1, -25, -2, -1},
- };
- }
-
- @Test(dataProvider="normalizedHoursToDays")
- public void test_normalizedHoursToDays(int inputDays, int inputHours, int expectedDays, int expectedHours) {
- assertPeriod(Period.of(0, 0, inputDays, inputHours, 0, 0, 0).normalizedHoursToDays(), 0, 0, expectedDays, expectedHours, 0, 0, 0);
- }
-
- @Test(dataProvider="normalizedHoursToDays")
- public void test_normalizedHoursToDays_yearsMonthsUnaffected(int inputDays, int inputHours, int expectedDays, int expectedHours) {
- assertPeriod(Period.of(12, 6, inputDays, inputHours, 0, 0, 0).normalizedHoursToDays(), 12, 6, expectedDays, expectedHours, 0, 0, 0);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedHoursToDays_min() {
- Period base = Period.of(0, 0, Integer.MIN_VALUE, -24, 0, 0, 0);
- base.normalizedHoursToDays();
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedHoursToDays_max() {
- Period base = Period.of(0, 0, Integer.MAX_VALUE, 24, 0, 0, 0);
- base.normalizedHoursToDays();
- }
-
- //-----------------------------------------------------------------------
- // normalizedDaysToHours()
- //-----------------------------------------------------------------------
- @DataProvider(name="normalizedDaysToHours")
- Object[][] data_normalizedDaysToHours() {
- return new Object[][] {
- {0, 0, 0, 0, 0},
-
- {1, 0, 0, 24, 0},
- {1, 1, 0, 25, 0},
- {1, 23, 0, 47, 0},
- {1, 24, 0, 48, 0},
- {1, 25, 0, 49, 0},
- {2, 23, 0, 71, 0},
- {2, 24, 0, 72, 0},
- {2, 25, 0, 73, 0},
-
- {1, 0, 0, 24, 0},
- {1, -1, 0, 23, 0},
- {1, -23, 0, 1, 0},
- {1, -24, 0, 0, 0},
- {1, -25, 0, -1, 0},
- {2, -23, 0, 25, 0},
- {2, -24, 0, 24, 0},
- {2, -25, 0, 23, 0},
-
- {-1, 0, 0, -24, 0},
- {-1, 1, 0, -23, 0},
- {-1, 23, 0, -1, 0},
- {-1, 24, 0, 0, 0},
- {-1, 25, 0, 1, 0},
- {-2, 23, 0, -25, 0},
- {-2, 24, 0, -24, 0},
- {-2, 25, 0, -23, 0},
-
- {-1, 0, 0, -24, 0},
- {-1, -1, 0, -25, 0},
- {-1, -23, 0, -47, 0},
- {-1, -24, 0, -48, 0},
- {-1, -25, 0, -49, 0},
-
- // minutes
- {1, -1, -1, 22, 59},
- {1, -23, -1, 0, 59},
- {1, -24, -1, 0, -1},
- {1, -25, -1, -1, -1},
- {-1, 1, 1, -22, -59},
- {-1, 23, 1, 0, -59},
- {-1, 24, 1, 0, 1},
- {-1, 25, 1, 1, 1},
- };
- }
-
- @Test(dataProvider="normalizedDaysToHours")
- public void test_normalizedDaysToHours(int inputDays, int inputHours, int inputMinutes, int expectedHours, int expectedMinutes) {
- assertPeriod(Period.of(0, 0, inputDays, inputHours, inputMinutes, 0, 0).normalizedDaysToHours(), 0, 0, 0, expectedHours, expectedMinutes, 0, 0);
- }
-
- @Test(dataProvider="normalizedDaysToHours")
- public void test_normalizedDaysToHours_yearsMonthsUnaffected(int inputDays, int inputHours, int inputMinutes, int expectedHours, int expectedMinutes) {
- assertPeriod(Period.of(12, 6, inputDays, inputHours, inputMinutes, 0, 0).normalizedDaysToHours(), 12, 6, 0, expectedHours, expectedMinutes, 0, 0);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedDaysToHours_min() {
- Period base = Period.of(0, 0, -1_000, -10_000_000, 0, 0, 0);
- base.normalizedDaysToHours();
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedDaysToHours_max() {
- Period base = Period.of(0, 0, 1_000, 10_000_000, 0, 0, 0);
- base.normalizedDaysToHours();
- }
-
- //-----------------------------------------------------------------------
- // normalizedMonthsToYears()
- //-----------------------------------------------------------------------
- @DataProvider(name="normalizedMonthsToYears")
- Object[][] data_normalizedMonthsToYears() {
+ @DataProvider(name="normalized")
+ Object[][] data_normalized() {
return new Object[][] {
{0, 0, 0, 0},
{1, 0, 1, 0},
@@ -542,160 +637,270 @@
};
}
- @Test(dataProvider="normalizedMonthsToYears")
- public void test_normalizedMonthsToYears(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
- assertPeriod(Period.ofDate(inputYears, inputMonths, 0).normalizedMonthsToYears(), expectedYears, expectedMonths, 0, 0, 0, 0, 0);
+ @Test(dataProvider="normalized")
+ public void test_normalized(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
+ assertPeriod(Period.of(inputYears, inputMonths, 0).normalized(), expectedYears, expectedMonths, 0);
}
- @Test(dataProvider="normalizedMonthsToYears")
- public void test_normalizedMonthsToYears_daysTimeUnaffected(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
- assertPeriod(Period.of(inputYears, inputMonths, 5, 12, 30, 0, 0).normalizedMonthsToYears(), expectedYears, expectedMonths, 5, 12, 30, 0, 0);
+ @Test(dataProvider="normalized")
+ public void test_normalized_daysUnaffected(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
+ assertPeriod(Period.of(inputYears, inputMonths, 5).normalized(), expectedYears, expectedMonths, 5);
}
@Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedMonthsToYears_min() {
- Period base = Period.ofDate(Integer.MIN_VALUE, -12, 0);
- base.normalizedMonthsToYears();
+ public void test_normalized_min() {
+ Period base = Period.of(Integer.MIN_VALUE, -12, 0);
+ base.normalized();
}
@Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedMonthsToYears_max() {
- Period base = Period.ofDate(Integer.MAX_VALUE, 12, 0);
- base.normalizedMonthsToYears();
+ public void test_normalized_max() {
+ Period base = Period.of(Integer.MAX_VALUE, 12, 0);
+ base.normalized();
}
//-----------------------------------------------------------------------
- // normalizedYearsToMonths()
+ // addTo()
//-----------------------------------------------------------------------
- @DataProvider(name="normalizedYearsToMonths")
- Object[][] data_normalizedYearsToMonths() {
+ @DataProvider(name="addTo")
+ Object[][] data_addTo() {
return new Object[][] {
- {0, 0, 0},
- {1, 0, 12},
- {-1, 0, -12},
+ {pymd(0, 0, 0), date(2012, 6, 30), date(2012, 6, 30)},
- {1, 1, 13},
- {1, 2, 14},
- {1, 11, 23},
- {1, 12, 24},
- {1, 13, 25},
- {1, 23, 35},
- {1, 24, 36},
- {1, 25, 37},
+ {pymd(1, 0, 0), date(2012, 6, 10), date(2013, 6, 10)},
+ {pymd(0, 1, 0), date(2012, 6, 10), date(2012, 7, 10)},
+ {pymd(0, 0, 1), date(2012, 6, 10), date(2012, 6, 11)},
- {1, -1, 11},
- {1, -2, 10},
- {1, -11, 1},
- {1, -12, 0},
- {1, -13, -1},
- {1, -23, -11},
- {1, -24, -12},
- {1, -25, -13},
- {1, -35, -23},
- {1, -36, -24},
- {1, -37, -25},
+ {pymd(-1, 0, 0), date(2012, 6, 10), date(2011, 6, 10)},
+ {pymd(0, -1, 0), date(2012, 6, 10), date(2012, 5, 10)},
+ {pymd(0, 0, -1), date(2012, 6, 10), date(2012, 6, 9)},
- {-1, 1, -11},
- {-1, 11, -1},
- {-1, 12, 0},
- {-1, 13, 1},
- {-1, 23, 11},
- {-1, 24, 12},
- {-1, 25, 13},
+ {pymd(1, 2, 3), date(2012, 6, 27), date(2013, 8, 30)},
+ {pymd(1, 2, 3), date(2012, 6, 28), date(2013, 8, 31)},
+ {pymd(1, 2, 3), date(2012, 6, 29), date(2013, 9, 1)},
+ {pymd(1, 2, 3), date(2012, 6, 30), date(2013, 9, 2)},
+ {pymd(1, 2, 3), date(2012, 7, 1), date(2013, 9, 4)},
- {-1, -1, -13},
- {-1, -11, -23},
- {-1, -12, -24},
- {-1, -13, -25},
+ {pymd(1, 0, 0), date(2011, 2, 28), date(2012, 2, 28)},
+ {pymd(4, 0, 0), date(2011, 2, 28), date(2015, 2, 28)},
+ {pymd(1, 0, 0), date(2012, 2, 29), date(2013, 2, 28)},
+ {pymd(4, 0, 0), date(2012, 2, 29), date(2016, 2, 29)},
+
+ {pymd(1, 1, 0), date(2011, 1, 29), date(2012, 2, 29)},
+ {pymd(1, 2, 0), date(2012, 2, 29), date(2013, 4, 29)},
};
}
- @Test(dataProvider="normalizedYearsToMonths")
- public void test_normalizedYearsToMonths(int inputYears, int inputMonths, int expectedMonths) {
- assertPeriod(Period.ofDate(inputYears, inputMonths, 0).normalizedYearsToMonths(), 0, expectedMonths, 0, 0, 0, 0, 0);
+ @Test(dataProvider="addTo")
+ public void test_addTo(Period period, LocalDate baseDate, LocalDate expected) {
+ assertEquals(period.addTo(baseDate), expected);
}
- @Test(dataProvider="normalizedYearsToMonths")
- public void test_normalizedYearsToMonths_daysTimeUnaffected(int inputYears, int inputMonths, int expectedMonths) {
- assertPeriod(Period.of(inputYears, inputMonths, 5, 12, 30, 0, 0).normalizedYearsToMonths(), 0, expectedMonths, 5, 12, 30, 0, 0);
+ @Test(dataProvider="addTo")
+ public void test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected) {
+ assertEquals(baseDate.plus(period), expected);
}
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedYearsToMonths_min() {
- Period base = Period.ofDate(Integer.MIN_VALUE / 12, -12, 0);
- base.normalizedYearsToMonths();
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_addTo_nullZero() {
+ Period.ZERO.addTo(null);
}
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_normalizedYearsToMonths_max() {
- Period base = Period.ofDate(Integer.MAX_VALUE / 12, 12, 0);
- base.normalizedYearsToMonths();
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_addTo_nullNonZero() {
+ Period.ofDays(2).addTo(null);
}
//-----------------------------------------------------------------------
- @Test(groups="{tck}")
+ // subtractFrom()
+ //-----------------------------------------------------------------------
+ @DataProvider(name="subtractFrom")
+ Object[][] data_subtractFrom() {
+ return new Object[][] {
+ {pymd(0, 0, 0), date(2012, 6, 30), date(2012, 6, 30)},
+
+ {pymd(1, 0, 0), date(2012, 6, 10), date(2011, 6, 10)},
+ {pymd(0, 1, 0), date(2012, 6, 10), date(2012, 5, 10)},
+ {pymd(0, 0, 1), date(2012, 6, 10), date(2012, 6, 9)},
+
+ {pymd(-1, 0, 0), date(2012, 6, 10), date(2013, 6, 10)},
+ {pymd(0, -1, 0), date(2012, 6, 10), date(2012, 7, 10)},
+ {pymd(0, 0, -1), date(2012, 6, 10), date(2012, 6, 11)},
+
+ {pymd(1, 2, 3), date(2012, 8, 30), date(2011, 6, 27)},
+ {pymd(1, 2, 3), date(2012, 8, 31), date(2011, 6, 27)},
+ {pymd(1, 2, 3), date(2012, 9, 1), date(2011, 6, 28)},
+ {pymd(1, 2, 3), date(2012, 9, 2), date(2011, 6, 29)},
+ {pymd(1, 2, 3), date(2012, 9, 3), date(2011, 6, 30)},
+ {pymd(1, 2, 3), date(2012, 9, 4), date(2011, 7, 1)},
+
+ {pymd(1, 0, 0), date(2011, 2, 28), date(2010, 2, 28)},
+ {pymd(4, 0, 0), date(2011, 2, 28), date(2007, 2, 28)},
+ {pymd(1, 0, 0), date(2012, 2, 29), date(2011, 2, 28)},
+ {pymd(4, 0, 0), date(2012, 2, 29), date(2008, 2, 29)},
+
+ {pymd(1, 1, 0), date(2013, 3, 29), date(2012, 2, 29)},
+ {pymd(1, 2, 0), date(2012, 2, 29), date(2010, 12, 29)},
+ };
+ }
+
+ @Test(dataProvider="subtractFrom")
+ public void test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected) {
+ assertEquals(period.subtractFrom(baseDate), expected);
+ }
+
+ @Test(dataProvider="subtractFrom")
+ public void test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected) {
+ assertEquals(baseDate.minus(period), expected);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_subtractFrom_nullZero() {
+ Period.ZERO.subtractFrom(null);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void test_subtractFrom_nullNonZero() {
+ Period.ofDays(2).subtractFrom(null);
+ }
+
+ //-----------------------------------------------------------------------
+ // get units
+ //-----------------------------------------------------------------------
+ @Test
public void test_Period_getUnits() {
- Period period = Period.ofDate(2012, 1, 1);
+ Period period = Period.of(2012, 1, 1);
List<TemporalUnit> units = period.getUnits();
- assertEquals(units.size(), 7, "Period.getUnits should return 7 units");
+ assertEquals(units.size(), 3, "Period.getUnits should return 3 units");
assertEquals(units.get(0), ChronoUnit.YEARS, "Period.getUnits contains ChronoUnit.YEARS");
assertEquals(units.get(1), ChronoUnit.MONTHS, "Period.getUnits contains ChronoUnit.MONTHS");
assertEquals(units.get(2), ChronoUnit.DAYS, "Period.getUnits contains ChronoUnit.DAYS");
- assertEquals(units.get(3), ChronoUnit.HOURS, "Period.getUnits contains ChronoUnit.HOURS");
- assertEquals(units.get(4), ChronoUnit.MINUTES, "Period.getUnits contains ChronoUnit.MINUTES");
- assertEquals(units.get(5), ChronoUnit.SECONDS, "Period.getUnits contains ChronoUnit.SECONDS");
- assertEquals(units.get(6), ChronoUnit.NANOS, "contains ChronoUnit.NANOS");
}
@DataProvider(name="GoodTemporalUnit")
- Object[][] provider_factory_of_goodTemporalUnit() {
+ Object[][] data_goodTemporalUnit() {
return new Object[][] {
- {0, ChronoUnit.NANOS},
- {0, ChronoUnit.SECONDS},
- {0, ChronoUnit.MINUTES},
- {0, ChronoUnit.HOURS},
- {0, ChronoUnit.DAYS},
- {0, ChronoUnit.MONTHS},
- {0, ChronoUnit.YEARS},
+ {2, ChronoUnit.DAYS},
+ {2, ChronoUnit.MONTHS},
+ {2, ChronoUnit.YEARS},
};
}
@Test(dataProvider="GoodTemporalUnit")
public void test_good_getUnit(long amount, TemporalUnit unit) {
- Period period = Period.of(amount, unit);
+ Period period = Period.of(2, 2, 2);
long actual = period.get(unit);
assertEquals(actual, amount, "Value of unit: " + unit);
}
@DataProvider(name="BadTemporalUnit")
- Object[][] provider_factory_of_badTemporalUnit() {
+ Object[][] data_badTemporalUnit() {
return new Object[][] {
- {0, ChronoUnit.MICROS},
- {0, ChronoUnit.MILLIS},
- {0, ChronoUnit.HALF_DAYS},
- {0, ChronoUnit.DECADES},
- {0, ChronoUnit.CENTURIES},
- {0, ChronoUnit.MILLENNIA},
+ {ChronoUnit.MICROS},
+ {ChronoUnit.MILLIS},
+ {ChronoUnit.HALF_DAYS},
+ {ChronoUnit.DECADES},
+ {ChronoUnit.CENTURIES},
+ {ChronoUnit.MILLENNIA},
};
}
@Test(dataProvider="BadTemporalUnit", expectedExceptions=DateTimeException.class)
- public void test_bad_getUnit(long amount, TemporalUnit unit) {
- Period t = Period.of(amount, unit);
- long actual = t.get(unit);
+ public void test_bad_getUnit(TemporalUnit unit) {
+ Period period = Period.of(2, 2, 2);
+ period.get(unit);
}
//-----------------------------------------------------------------------
- private void assertPeriod(Period test, int y, int mo, int d, int h, int mn, int s, long n) {
+ // equals() / hashCode()
+ //-----------------------------------------------------------------------
+ public void test_equals() {
+ assertEquals(Period.of(1, 0, 0).equals(Period.ofYears(1)), true);
+ assertEquals(Period.of(0, 1, 0).equals(Period.ofMonths(1)), true);
+ assertEquals(Period.of(0, 0, 1).equals(Period.ofDays(1)), true);
+ assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 3)), true);
+
+ assertEquals(Period.ofYears(1).equals(Period.ofYears(1)), true);
+ assertEquals(Period.ofYears(1).equals(Period.ofYears(2)), false);
+
+ assertEquals(Period.ofMonths(1).equals(Period.ofMonths(1)), true);
+ assertEquals(Period.ofMonths(1).equals(Period.ofMonths(2)), false);
+
+ assertEquals(Period.ofDays(1).equals(Period.ofDays(1)), true);
+ assertEquals(Period.ofDays(1).equals(Period.ofDays(2)), false);
+
+ assertEquals(Period.of(1, 2, 3).equals(Period.of(0, 2, 3)), false);
+ assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 0, 3)), false);
+ assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 0)), false);
+ }
+
+ public void test_equals_self() {
+ Period test = Period.of(1, 2, 3);
+ assertEquals(test.equals(test), true);
+ }
+
+ public void test_equals_null() {
+ Period test = Period.of(1, 2, 3);
+ assertEquals(test.equals(null), false);
+ }
+
+ public void test_equals_otherClass() {
+ Period test = Period.of(1, 2, 3);
+ assertEquals(test.equals(""), false);
+ }
+
+ //-----------------------------------------------------------------------
+ public void test_hashCode() {
+ Period test5 = Period.ofDays(5);
+ Period test6 = Period.ofDays(6);
+ Period test5M = Period.ofMonths(5);
+ Period test5Y = Period.ofYears(5);
+ assertEquals(test5.hashCode() == test5.hashCode(), true);
+ assertEquals(test5.hashCode() == test6.hashCode(), false);
+ }
+
+ //-----------------------------------------------------------------------
+ // toString()
+ //-----------------------------------------------------------------------
+ @DataProvider(name="toStringAndParse")
+ Object[][] data_toString() {
+ return new Object[][] {
+ {Period.ZERO, "P0D"},
+ {Period.ofDays(0), "P0D"},
+ {Period.ofYears(1), "P1Y"},
+ {Period.ofMonths(1), "P1M"},
+ {Period.ofDays(1), "P1D"},
+ {Period.of(1, 2, 0), "P1Y2M"},
+ {Period.of(0, 2, 3), "P2M3D"},
+ {Period.of(1, 2, 3), "P1Y2M3D"},
+ };
+ }
+
+ @Test(dataProvider="toStringAndParse")
+ public void test_toString(Period input, String expected) {
+ assertEquals(input.toString(), expected);
+ }
+
+ @Test(dataProvider="toStringAndParse")
+ public void test_parse(Period test, String expected) {
+ assertEquals(Period.parse(expected), test);
+ }
+
+ //-----------------------------------------------------------------------
+ private void assertPeriod(Period test, int y, int m, int d) {
assertEquals(test.getYears(), y, "years");
- assertEquals(test.getMonths(), mo, "months");
+ assertEquals(test.getMonths(), m, "months");
assertEquals(test.getDays(), d, "days");
- assertEquals(test.getHours(), h, "hours");
- assertEquals(test.getMinutes(), mn, "mins");
- assertEquals(test.getSeconds(), s, "secs");
- assertEquals(test.getNanos(), n, "nanos");
- assertEquals(test.getTimeNanos(), (((h * 60L + mn) * 60 + s) * 1_000_000_000L + n), "total nanos");
+ assertEquals(test.toTotalMonths(), y * 12L + m, "totalMonths");
+ }
+
+ private static Period pymd(int y, int m, int d) {
+ return Period.of(y, m, d);
+ }
+
+ private static LocalDate date(int y, int m, int d) {
+ return LocalDate.of(y, m, d);
}
}
diff --git a/test/java/time/tck/java/time/TCKZonedDateTime.java b/test/java/time/tck/java/time/TCKZonedDateTime.java
--- a/test/java/time/tck/java/time/TCKZonedDateTime.java
+++ b/test/java/time/tck/java/time/TCKZonedDateTime.java
@@ -60,7 +60,6 @@
package tck.java.time;
import java.time.*;
-import test.java.time.MockSimplePeriod;
import static java.time.Month.JANUARY;
import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
@@ -1412,25 +1411,25 @@
}
//-----------------------------------------------------------------------
- // plus(adjuster)
+ // plus(TemporalAmount)
//-----------------------------------------------------------------------
@Test(groups={"tck"}, dataProvider="plusDays")
- public void test_plus_adjuster_Period_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
- assertEquals(base.plus(Period.of(amount, DAYS)), expected);
+ public void test_plus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
+ assertEquals(base.plus(Period.ofDays(amount)), expected);
}
@Test(groups={"tck"}, dataProvider="plusTime")
- public void test_plus_adjuster_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
- assertEquals(base.plus(Period.of(amount, HOURS)), expected);
+ public void test_plus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+ assertEquals(base.plus(MockSimplePeriod.of(amount, HOURS)), expected);
}
@Test(groups={"tck"}, dataProvider="plusTime")
- public void test_plus_adjuster_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+ public void test_plus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
assertEquals(base.plus(Duration.ofHours(amount)), expected);
}
@Test(groups={"tck"})
- public void test_plus_adjuster() {
+ public void test_plus_TemporalAmount() {
MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2009, 1, 1, 12, 30, 59, 500), ZONE_0100);
@@ -1438,7 +1437,7 @@
}
@Test(groups={"tck"})
- public void test_plus_adjuster_Duration() {
+ public void test_plus_TemporalAmount_Duration() {
Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 16, 36, 5, 500), ZONE_0100);
@@ -1446,19 +1445,19 @@
}
@Test(groups={"tck"})
- public void test_plus_adjuster_Period_zero() {
+ public void test_plus_TemporalAmount_Period_zero() {
ZonedDateTime t = TEST_DATE_TIME.plus(MockSimplePeriod.ZERO_DAYS);
assertEquals(t, TEST_DATE_TIME);
}
@Test(groups={"tck"})
- public void test_plus_adjuster_Duration_zero() {
+ public void test_plus_TemporalAmount_Duration_zero() {
ZonedDateTime t = TEST_DATE_TIME.plus(Duration.ZERO);
assertEquals(t, TEST_DATE_TIME);
}
@Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_plus_adjuster_null() {
+ public void test_plus_TemporalAmount_null() {
TEST_DATE_TIME.plus((TemporalAmount) null);
}
@@ -1617,25 +1616,25 @@
}
//-----------------------------------------------------------------------
- // minus(adjuster)
+ // minus(TemporalAmount)
//-----------------------------------------------------------------------
@Test(groups={"tck"}, dataProvider="plusDays")
- public void test_minus_adjuster_Period_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
- assertEquals(base.minus(Period.of(-amount, DAYS)), expected);
+ public void test_minus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
+ assertEquals(base.minus(Period.ofDays(-amount)), expected);
}
@Test(groups={"tck"}, dataProvider="plusTime")
- public void test_minus_adjuster_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
- assertEquals(base.minus(Period.of(-amount, HOURS)), expected);
+ public void test_minus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+ assertEquals(base.minus(MockSimplePeriod.of(-amount, HOURS)), expected);
}
@Test(groups={"tck"}, dataProvider="plusTime")
- public void test_minus_adjuster_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+ public void test_minus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
assertEquals(base.minus(Duration.ofHours(-amount)), expected);
}
@Test(groups={"tck"})
- public void test_minus_adjuster() {
+ public void test_minus_TemporalAmount() {
MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2007, 11, 1, 12, 30, 59, 500), ZONE_0100);
@@ -1643,7 +1642,7 @@
}
@Test(groups={"tck"})
- public void test_minus_adjuster_Duration() {
+ public void test_minus_TemporalAmount_Duration() {
Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 8, 25, 53, 500), ZONE_0100);
@@ -1651,19 +1650,19 @@
}
@Test(groups={"tck"})
- public void test_minus_adjuster_Period_zero() {
+ public void test_minus_TemporalAmount_Period_zero() {
ZonedDateTime t = TEST_DATE_TIME.minus(MockSimplePeriod.ZERO_DAYS);
assertEquals(t, TEST_DATE_TIME);
}
@Test(groups={"tck"})
- public void test_minus_adjuster_Duration_zero() {
+ public void test_minus_TemporalAmount_Duration_zero() {
ZonedDateTime t = TEST_DATE_TIME.minus(Duration.ZERO);
assertEquals(t, TEST_DATE_TIME);
}
@Test(expectedExceptions=NullPointerException.class, groups={"tck"})
- public void test_minus_adjuster_null() {
+ public void test_minus_TemporalAmount_null() {
TEST_DATE_TIME.minus((TemporalAmount) null);
}
diff --git a/test/java/time/test/java/time/TestDuration.java b/test/java/time/test/java/time/TestDuration.java
--- a/test/java/time/test/java/time/TestDuration.java
+++ b/test/java/time/test/java/time/TestDuration.java
@@ -218,18 +218,12 @@
Duration b = durations[j];
if (i < j) {
assertEquals(a.compareTo(b)< 0, true, a + " <=> " + b);
- assertEquals(a.isLessThan(b), true, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
assertEquals(a.equals(b), false, a + " <=> " + b);
} else if (i > j) {
assertEquals(a.compareTo(b) > 0, true, a + " <=> " + b);
- assertEquals(a.isLessThan(b), false, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), true, a + " <=> " + b);
assertEquals(a.equals(b), false, a + " <=> " + b);
} else {
assertEquals(a.compareTo(b), 0, a + " <=> " + b);
- assertEquals(a.isLessThan(b), false, a + " <=> " + b);
- assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
assertEquals(a.equals(b), true, a + " <=> " + b);
}
}
diff --git a/test/java/time/test/java/time/TestPeriod.java b/test/java/time/test/java/time/TestPeriod.java
--- a/test/java/time/test/java/time/TestPeriod.java
+++ b/test/java/time/test/java/time/TestPeriod.java
@@ -59,37 +59,11 @@
*/
package test.java.time;
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.HALF_DAYS;
-import static java.time.temporal.ChronoUnit.HOURS;
-import static java.time.temporal.ChronoUnit.MICROS;
-import static java.time.temporal.ChronoUnit.MILLIS;
-import static java.time.temporal.ChronoUnit.MINUTES;
-import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
-import static java.time.temporal.ChronoUnit.SECONDS;
-import static java.time.temporal.ChronoUnit.YEARS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
+import java.time.Period;
-import java.time.DateTimeException;
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.OffsetTime;
-import java.time.Period;
-import java.time.YearMonth;
-import java.time.ZoneOffset;
-
-import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
@@ -98,39 +72,6 @@
@Test
public class TestPeriod extends AbstractTest {
- //-----------------------------------------------------------------------
- // basics
- //-----------------------------------------------------------------------
- public void test_interfaces() {
- assertTrue(Serializable.class.isAssignableFrom(Period.class));
- }
-
- @DataProvider(name="serialization")
- Object[][] data_serialization() {
- return new Object[][] {
- {Period.ZERO},
- {Period.of(0, DAYS)},
- {Period.of(1, DAYS)},
- {Period.of(1, 2, 3, 4, 5, 6, 0)},
- };
- }
-
- @Test(dataProvider="serialization")
- public void test_serialization(Period period) throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(period);
- oos.close();
-
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
- baos.toByteArray()));
- if (period.isZero()) {
- assertSame(ois.readObject(), period);
- } else {
- assertEquals(ois.readObject(), period);
- }
- }
-
@Test
public void test_immutable() {
assertImmutable(Period.class);
@@ -144,1282 +85,21 @@
assertSame(Period.ofYears(0), Period.ZERO);
assertSame(Period.ofMonths(0), Period.ZERO);
assertSame(Period.ofDays(0), Period.ZERO);
- assertSame(Period.ofHours(0), Period.ZERO);
- assertSame(Period.ofMinutes(0), Period.ZERO);
- assertSame(Period.ofSeconds(0), Period.ZERO);
- assertSame(Period.of(0, 0, 0, 0, 0, 0, 0), Period.ZERO);
- assertSame(Period.ofDate(0, 0, 0), Period.ZERO);
- assertSame(Period.ofTime(0, 0, 0, 0), Period.ZERO);
- assertSame(Period.of(0, YEARS), Period.ZERO);
- assertSame(Period.of(0, MONTHS), Period.ZERO);
- assertSame(Period.of(0, DAYS), Period.ZERO);
- assertSame(Period.of(0, HOURS), Period.ZERO);
- assertSame(Period.of(0, MINUTES), Period.ZERO);
- assertSame(Period.of(0, SECONDS), Period.ZERO);
- assertSame(Period.of(0, NANOS), Period.ZERO);
+ assertSame(Period.of(0, 0, 0), Period.ZERO);
}
//-----------------------------------------------------------------------
- // between
- //-----------------------------------------------------------------------
- @DataProvider(name="betweenDates")
- Object[][] data_betweenDates() {
- return new Object[][] {
- {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
- {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
- {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
- {2010, 1, 1, 2010, 2, 2, 0, 1, 1},
- {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
-
- {2010, 6, 12, 2010, 1, 1, 0, -5, -11},
- {2010, 6, 12, 2010, 1, 2, 0, -5, -10},
- {2010, 6, 12, 2010, 2, 1, 0, -4, -11},
- {2010, 6, 12, 2010, 9, 24, 0, 3, 12},
-
- {2010, 6, 12, 2009, 1, 1, -1, -5, -11},
- {2010, 6, 12, 2009, 1, 2, -1, -5, -10},
- {2010, 6, 12, 2009, 2, 1, -1, -4, -11},
- {2010, 6, 12, 2009, 9, 24, 0, -9, 12},
-
- {2010, 6, 12, 2008, 1, 1, -2, -5, -11},
- {2010, 6, 12, 2008, 1, 2, -2, -5, -10},
- {2010, 6, 12, 2008, 2, 1, -2, -4, -11},
- {2010, 6, 12, 2008, 9, 24, -1, -9, 12},
- };
- }
-
- @Test(dataProvider="betweenDates")
- public void factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
- LocalDate start = LocalDate.of(y1, m1, d1);
- LocalDate end = LocalDate.of(y2, m2, d2);
- Period test = Period.between(start, end);
- assertPeriod(test, ye, me, de, 0, 0, 0, 0);
- //assertEquals(start.plus(test), end);
- }
-
- @DataProvider(name="betweenTimes")
- Object[][] data_betweenTimes() {
- return new Object[][] {
- {12, 30, 40, 12, 30, 45, 0, 0, 5},
- {12, 30, 40, 12, 35, 40, 0, 5, 0},
- {12, 30, 40, 13, 30, 40, 1, 0, 0},
-
- {12, 30, 40, 12, 30, 35, 0, 0, -5},
- {12, 30, 40, 12, 25, 40, 0, -5, 0},
- {12, 30, 40, 11, 30, 40, -1, 0, 0},
- };
- }
-
- @Test(dataProvider="betweenTimes")
- public void factory_between_LocalTime(int h1, int m1, int s1, int h2, int m2, int s2, int he, int me, int se) {
- LocalTime start = LocalTime.of(h1, m1, s1);
- LocalTime end = LocalTime.of(h2, m2, s2);
- Period test = Period.between(start, end);
- assertPeriod(test, 0, 0, 0, he, me, se, 0);
- }
-
- @Test(dataProvider="betweenTimes")
- public void factory_between_OffsetTime(int h1, int m1, int s1, int h2, int m2, int s2, int he, int me, int se) {
- OffsetTime start = OffsetTime.of(LocalTime.of(h1, m1, s1), ZoneOffset.ofHours(1));
- OffsetTime end = OffsetTime.of(LocalTime.of(h2, m2, s2), ZoneOffset.ofHours(1));
- Period test = Period.between(start, end);
- assertPeriod(test, 0, 0, 0, he, me, se, 0);
- }
-
- public void factory_between_YearMonth() {
- assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2013, 7)), 1, 1, 0, 0, 0, 0, 0);
- assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2013, 3)), 0, 9, 0, 0, 0, 0, 0);
- assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2011, 7)), 0, -11, 0, 0, 0, 0, 0);
- }
-
- public void factory_between_Month() {
- assertPeriod(Period.between(Month.FEBRUARY, Month.MAY), 0, 3, 0, 0, 0, 0, 0);
- assertPeriod(Period.between(Month.NOVEMBER, Month.MAY), 0, -6, 0, 0, 0, 0, 0);
- }
-
- //-----------------------------------------------------------------------
- // betweenIso
- //-----------------------------------------------------------------------
- @DataProvider(name="betweenIso")
- Object[][] data_betweenIso() {
- return new Object[][] {
- {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
- {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
- {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
- {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
- {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
- {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
- {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
- {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
- {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
- {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
-
- {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
- {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
- {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
- {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
- {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
- {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
- {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
- {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
- {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
- {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
- {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
- {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
- {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
- {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
- {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
- {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
- {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
-
- {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
- {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
-
- {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
- {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
- {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
-
- {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
- {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
- {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
-
- {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
- {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
- {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
-
- {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
- {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
- {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
-
- {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
- {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
- {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
- {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
- {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
- {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
- {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
- {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
- {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
-
- {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
- {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
- {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
- {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
- {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
- {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
- {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
-
- {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
- {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
- {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
-
- {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
- {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
- {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
-
- {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
- {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
- {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
-
- {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
- {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
- {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
- };
- }
-
- @Test(dataProvider="betweenIso")
- public void factory_betweenIso_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
- LocalDate start = LocalDate.of(y1, m1, d1);
- LocalDate end = LocalDate.of(y2, m2, d2);
- Period test = Period.betweenIso(start, end);
- assertPeriod(test, ye, me, de, 0, 0, 0, 0);
- //assertEquals(start.plus(test), end);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_betweenIso_LocalDate_nullFirst() {
- Period.betweenIso((LocalDate) null, LocalDate.of(2010, 1, 1));
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_betweenIso_LocalDate_nullSecond() {
- Period.betweenIso(LocalDate.of(2010, 1, 1), (LocalDate) null);
- }
-
- //-------------------------------------------------------------------------
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_betweenIso_LocalTime_nullFirst() {
- Period.betweenIso((LocalTime) null, LocalTime.of(12, 30));
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void factory_betweenIso_LocalTime_nullSecond() {
- Period.betweenIso(LocalTime.of(12, 30), (LocalTime) null);
- }
-
- //-----------------------------------------------------------------------
- // parse()
- //-----------------------------------------------------------------------
- @Test(dataProvider="toStringAndParse")
- public void test_parse(Period test, String expected) {
- assertEquals(test, Period.parse(expected));
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void test_parse_nullText() {
- Period.parse((String) null);
- }
-
- //-----------------------------------------------------------------------
- // isZero()
- //-----------------------------------------------------------------------
- public void test_isZero() {
- assertEquals(Period.of(1, 2, 3, 4, 5, 6, 7).isZero(), false);
- assertEquals(Period.of(1, 2, 3, 0, 0, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).isZero(), false);
- assertEquals(Period.of(1, 0, 0, 0, 0, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 2, 0, 0, 0, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 3, 0, 0, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 4, 0, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 0, 5, 0, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, 6, 0).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, 0, 7).isZero(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, 0, 0).isZero(), true);
- }
-
- //-----------------------------------------------------------------------
- // isPositive()
- //-----------------------------------------------------------------------
- public void test_isPositive() {
- assertEquals(Period.of(1, 2, 3, 4, 5, 6, 7).isPositive(), true);
- assertEquals(Period.of(1, 2, 3, 0, 0, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).isPositive(), true);
- assertEquals(Period.of(1, 0, 0, 0, 0, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 2, 0, 0, 0, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 3, 0, 0, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 0, 4, 0, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 0, 0, 5, 0, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 0, 0, 0, 6, 0).isPositive(), true);
- assertEquals(Period.of(0, 0, 0, 0, 0, 0, 7).isPositive(), true);
- assertEquals(Period.of(-1, -2, -3, -4, -5, -6, -7).isPositive(), false);
- assertEquals(Period.of(-1, -2, 3, 4, -5, -6, -7).isPositive(), false);
- assertEquals(Period.of(-1, 0, 0, 0, 0, 0, 0).isPositive(), false);
- assertEquals(Period.of(0, -2, 0, 0, 0, 0, 0).isPositive(), false);
- assertEquals(Period.of(0, 0, -3, 0, 0, 0, 0).isPositive(), false);
- assertEquals(Period.of(0, 0, 0, -4, 0, 0, 0).isPositive(), false);
- assertEquals(Period.of(0, 0, 0, 0, -5, 0, 0).isPositive(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, -6, 0).isPositive(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, 0, -7).isPositive(), false);
- assertEquals(Period.of(0, 0, 0, 0, 0, 0, 0).isPositive(), false);
- }
-
- //-----------------------------------------------------------------------
- // withYears()
- //-----------------------------------------------------------------------
- public void test_withYears() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.withYears(10), 10, 2, 3, 4, 5, 6, 7);
- }
-
- public void test_withYears_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.withYears(1), test);
- }
-
- public void test_withYears_toZero() {
- Period test = Period.of(1, YEARS);
- assertSame(test.withYears(0), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // withMonths()
- //-----------------------------------------------------------------------
- public void test_withMonths() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.withMonths(10), 1, 10, 3, 4, 5, 6, 7);
- }
-
- public void test_withMonths_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.withMonths(2), test);
- }
-
- public void test_withMonths_toZero() {
- Period test = Period.of(1, MONTHS);
- assertSame(test.withMonths(0), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // withDays()
- //-----------------------------------------------------------------------
- public void test_withDays() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.withDays(10), 1, 2, 10, 4, 5, 6, 7);
- }
-
- public void test_withDays_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.withDays(3), test);
- }
-
- public void test_withDays_toZero() {
- Period test = Period.of(1, DAYS);
- assertSame(test.withDays(0), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // withTimeNanos()
- //-----------------------------------------------------------------------
- public void test_withTimeNanos() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.withTimeNanos(10), 1, 2, 3, 0, 0, 0, 10);
- }
-
- public void test_withTimeNanos_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.withTimeNanos(((4 * 60 + 5) * 60 + 6) * 1_000_000_000L + 7), test);
- }
-
- public void test_withTimeNanos_toZero() {
- Period test = Period.of(1, NANOS);
- assertSame(test.withTimeNanos(0), Period.ZERO);
- }
-
-
- //-----------------------------------------------------------------------
- // plusYears()
- //-----------------------------------------------------------------------
- public void test_plusYears() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, YEARS), 11, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(Period.of(10, YEARS)), 11, 2, 3, 4, 5, 6, 7);
- }
-
- public void test_plusYears_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, YEARS), test);
- assertPeriod(test.plus(Period.of(0, YEARS)), 1, 2, 3, 4, 5, 6, 7);
- }
-
- public void test_plusYears_toZero() {
- Period test = Period.of(-1, YEARS);
- assertSame(test.plus(1, YEARS), Period.ZERO);
- assertSame(test.plus(Period.of(1, YEARS)), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusYears_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, YEARS);
- test.plus(1, YEARS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusYears_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, YEARS);
- test.plus(-1, YEARS);
- }
-
- //-----------------------------------------------------------------------
- // plusMonths()
- //-----------------------------------------------------------------------
- public void test_plusMonths() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, MONTHS), 1, 12, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(Period.of(10, MONTHS)), 1, 12, 3, 4, 5, 6, 7);
- }
-
- public void test_plusMonths_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, MONTHS), test);
- assertEquals(test.plus(Period.of(0, MONTHS)), test);
- }
-
- public void test_plusMonths_toZero() {
- Period test = Period.of(-1, MONTHS);
- assertSame(test.plus(1, MONTHS), Period.ZERO);
- assertSame(test.plus(Period.of(1, MONTHS)), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusMonths_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, MONTHS);
- test.plus(1, MONTHS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusMonths_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, MONTHS);
- test.plus(-1, MONTHS);
- }
-
- //-----------------------------------------------------------------------
- // plusDays()
- //-----------------------------------------------------------------------
- public void test_plusDays() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, DAYS), 1, 2, 13, 4, 5, 6, 7);
- }
-
- public void test_plusDays_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, DAYS), test);
- }
-
- public void test_plusDays_toZero() {
- Period test = Period.of(-1, DAYS);
- assertSame(test.plus(1, DAYS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusDays_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, DAYS);
- test.plus(1, DAYS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusDays_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, DAYS);
- test.plus(-1, DAYS);
- }
-
- //-----------------------------------------------------------------------
- // plusHours()
- //-----------------------------------------------------------------------
- public void test_plusHours() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, HOURS), 1, 2, 3, 14, 5, 6, 7);
- }
-
- public void test_plusHours_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, HOURS), test);
- }
-
- public void test_plusHours_toZero() {
- Period test = Period.of(-1, HOURS);
- assertSame(test.plus(1, HOURS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusHours_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, HOURS);
- test.plus(1, HOURS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusHours_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, HOURS);
- test.plus(-1, HOURS);
- }
-
- //-----------------------------------------------------------------------
- // plusMinutes()
- //-----------------------------------------------------------------------
- public void test_plusMinutes() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, MINUTES), 1, 2, 3, 4, 15, 6, 7);
- }
-
- public void test_plusMinutes_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, MINUTES), test);
- }
-
- public void test_plusMinutes_toZero() {
- Period test = Period.of(-1, MINUTES);
- assertSame(test.plus(1, MINUTES), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // plusSeconds()
- //-----------------------------------------------------------------------
- public void test_plusSeconds() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, SECONDS), 1, 2, 3, 4, 5, 16, 7);
- }
-
- public void test_plusSeconds_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, SECONDS), test);
- }
-
- public void test_plusSeconds_toZero() {
- Period test = Period.of(-1, SECONDS);
- assertSame(test.plus(1, SECONDS), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // plusNanos()
- //-----------------------------------------------------------------------
- public void test_plusNanos() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.plus(10, NANOS), 1, 2, 3, 4, 5, 6, 17);
- }
-
- public void test_plusNanos_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.plus(0, NANOS), test);
- }
-
- public void test_plusNanos_toZero() {
- Period test = Period.of(-1, NANOS);
- assertSame(test.plus(1, NANOS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusNanos_overflowTooBig() {
- Period test = Period.of(Long.MAX_VALUE, NANOS);
- test.plus(1, NANOS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_plusNanos_overflowTooSmall() {
- Period test = Period.of(Long.MIN_VALUE, NANOS);
- test.plus(-1, NANOS);
- }
-
- //-----------------------------------------------------------------------
- // minusYears()
- //-----------------------------------------------------------------------
- public void test_minus_Years() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, YEARS), -9, 2, 3, 4, 5, 6, 7);
- }
-
- public void test_minus_Years_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, YEARS), test);
- }
-
- public void test_minus_Years_toZero() {
- Period test = Period.of(1, YEARS);
- assertSame(test.minus(1, YEARS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Years_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, YEARS);
- test.minus(-1, YEARS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Years_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, YEARS);
- test.minus(1, YEARS);
- }
-
- //-----------------------------------------------------------------------
- // minusYears()
- //-----------------------------------------------------------------------
- public void test_minusYears() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusYears(10), -9, 2, 3, 4, 5, 6, 7);
- }
-
- public void test_minusYears_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusYears(0), test);
- }
-
- public void test_minusYears_toZero() {
- Period test = Period.of(1, YEARS);
- assertEquals(test.minusYears(1), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusYears_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, YEARS);
- test.minusYears(-1);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusYears_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, YEARS);
- test.minusYears(1);
- }
-
- //-----------------------------------------------------------------------
- // minusMonths()
- //-----------------------------------------------------------------------
- public void test_minus_Months() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, MONTHS), 1, -8, 3, 4, 5, 6, 7);
- }
-
- public void test_minus_Months_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, MONTHS), test);
- }
-
- public void test_minus_Months_toZero() {
- Period test = Period.of(1, MONTHS);
- assertSame(test.minus(1, MONTHS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Months_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, MONTHS);
- test.minus(-1, MONTHS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Months_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, MONTHS);
- test.minus(1, MONTHS);
- }
-
- //-----------------------------------------------------------------------
- // minusMonths()
- //-----------------------------------------------------------------------
- public void test_minusMonths() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusMonths(10), 1, -8, 3, 4, 5, 6, 7);
- }
-
- public void test_minusMonths_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusMonths(0), test);
- }
-
- public void test_minusMonths_toZero() {
- Period test = Period.of(1, MONTHS);
- assertEquals(test.minusMonths(1), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusMonths_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, MONTHS);
- test.minusMonths(-1);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusMonths_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, MONTHS);
- test.minusMonths(1);
- }
-
- //-----------------------------------------------------------------------
- // minusDays()
- //-----------------------------------------------------------------------
- public void test_minus_Days() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, DAYS), 1, 2, -7, 4, 5, 6, 7);
- }
-
- public void test_minus_Days_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, DAYS), test);
- }
-
- public void test_minus_Days_toZero() {
- Period test = Period.of(1, DAYS);
- assertSame(test.minus(1, DAYS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Days_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, DAYS);
- test.minus(-1, DAYS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Days_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, DAYS);
- test.minus(1, DAYS);
- }
-
- //-----------------------------------------------------------------------
- // minusDays()
- //-----------------------------------------------------------------------
- public void test_minusDays() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusDays(10), 1, 2, -7, 4, 5, 6, 7);
- }
-
- public void test_minusDays_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusDays(0), test);
- }
-
- public void test_minusDays_toZero() {
- Period test = Period.of(1, DAYS);
- assertEquals(test.minusDays(1), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusDays_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, DAYS);
- test.minusDays(-1);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusDays_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, DAYS);
- test.minusDays(1);
- }
-
- //-----------------------------------------------------------------------
- // minusHours()
- //-----------------------------------------------------------------------
- public void test_minus_Hours() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, HOURS), 1, 2, 3, -5, -54, -53, -999999993);
- assertEquals(test.minus(10, HOURS).plus(10, HOURS), test);
- }
-
- public void test_minus_Hours_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, HOURS), test);
- }
-
- public void test_minus_Hours_toZero() {
- Period test = Period.of(1, HOURS);
- assertSame(test.minus(1, HOURS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Hours_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, HOURS);
- test.minus(-1, HOURS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Hours_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, HOURS);
- test.minus(1, HOURS);
- }
-
- //-----------------------------------------------------------------------
- // minusHours()
- //-----------------------------------------------------------------------
- public void test_minusHours() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusHours(10), 1, 2, 3, -5, -54, -53, -999999993);
- assertEquals(test.minusHours(10).plusHours(10), test);
- }
-
- public void test_minusHours_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusHours(0), test);
- }
-
- public void test_minusHours_toZero() {
- Period test = Period.of(1, HOURS);
- assertEquals(test.minusHours(1), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusHours_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE, HOURS);
- test.minusHours(-1);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusHours_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE, HOURS);
- test.minusHours(1);
- }
-
- //-----------------------------------------------------------------------
- // minusMinutes()
- //-----------------------------------------------------------------------
- public void test_minus_Minutes() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, MINUTES), 1, 2, 3, 3, 55, 6, 7);
- assertEquals(test.minus(10, MINUTES).plus(10, MINUTES), test);
- }
-
- public void test_minus_Minutes_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, MINUTES), test);
- }
-
- public void test_minus_Minutes_toZero() {
- Period test = Period.of(1, MINUTES);
- assertSame(test.minus(1, MINUTES), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // minusMinutes()
- //-----------------------------------------------------------------------
- public void test_minusMinutes() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusMinutes(10), 1, 2, 3, 3, 55, 6, 7);
- assertEquals(test.minusMinutes(10).plusMinutes(10), test);
- }
-
- public void test_minusMinutes_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusMinutes(0), test);
- }
-
- public void test_minusMinutes_toZero() {
- Period test = Period.of(1, MINUTES);
- assertEquals(test.minusMinutes(1), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // minusSeconds()
- //-----------------------------------------------------------------------
- public void test_minus_Seconds() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, SECONDS), 1, 2, 3, 4, 4, 56, 7);
- assertEquals(test.minus(10, SECONDS).plus(10, SECONDS), test);
- }
-
- public void test_minus_Seconds_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, SECONDS), test);
- }
-
- public void test_minus_Seconds_toZero() {
- Period test = Period.of(1, SECONDS);
- assertSame(test.minus(1, SECONDS), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // minusSeconds()
- //-----------------------------------------------------------------------
- public void test_minusSeconds() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusSeconds(10), 1, 2, 3, 4, 4, 56, 7);
- assertEquals(test.minusSeconds(10).plusSeconds(10), test);
- }
-
- public void test_minusSeconds_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusSeconds(0), test);
- }
-
- public void test_minusSeconds_toZero() {
- Period test = Period.of(1, SECONDS);
- assertEquals(test.minusSeconds(1), Period.ZERO);
- }
-
- //-----------------------------------------------------------------------
- // minusNanos()
- //-----------------------------------------------------------------------
- public void test_minus_Nanos() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minus(10, NANOS), 1, 2, 3, 4, 5, 5, 999999997);
- }
-
- public void test_minus_Nanos_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.minus(0, NANOS), test);
- }
-
- public void test_minus_Nanos_toZero() {
- Period test = Period.of(1, NANOS);
- assertSame(test.minus(1, NANOS), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Nanos_overflowTooBig() {
- Period test = Period.of(Long.MAX_VALUE, NANOS);
- test.minus(-1, NANOS);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minus_Nanos_overflowTooSmall() {
- Period test = Period.of(Long.MIN_VALUE, NANOS);
- test.minus(1, NANOS);
- }
-
- //-----------------------------------------------------------------------
- // minusNanos()
- //-----------------------------------------------------------------------
- public void test_minusNanos() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.minusNanos(10), 1, 2, 3, 4, 5, 5, 999999997);
- }
-
- public void test_minusNanos_noChange() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertEquals(test.minusNanos(0), test);
- }
-
- public void test_minusNanos_toZero() {
- Period test = Period.of(1, NANOS);
- assertEquals(test.minusNanos(1), Period.ZERO);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusNanos_overflowTooBig() {
- Period test = Period.of(Long.MAX_VALUE, NANOS);
- test.minusNanos(-1);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_minusNanos_overflowTooSmall() {
- Period test = Period.of(Long.MIN_VALUE, NANOS);
- test.minusNanos(1);
- }
-
- //-----------------------------------------------------------------------
- // multipliedBy()
- //-----------------------------------------------------------------------
- public void test_multipliedBy() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.multipliedBy(2), 2, 4, 6, 8, 10, 12, 14);
- assertPeriod(test.multipliedBy(-3), -3, -6, -9, -12, -15, -18, -21);
- }
-
- public void test_multipliedBy_zeroBase() {
- assertSame(Period.ZERO.multipliedBy(2), Period.ZERO);
- }
-
- public void test_multipliedBy_zero() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.multipliedBy(0), Period.ZERO);
- }
-
- public void test_multipliedBy_one() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertSame(test.multipliedBy(1), test);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_multipliedBy_overflowTooBig() {
- Period test = Period.of(Integer.MAX_VALUE / 2 + 1, YEARS);
- test.multipliedBy(2);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_multipliedBy_overflowTooSmall() {
- Period test = Period.of(Integer.MIN_VALUE / 2 - 1, YEARS);
- test.multipliedBy(2);
- }
-
- //-----------------------------------------------------------------------
- // negated()
- //-----------------------------------------------------------------------
- public void test_negated() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
- assertPeriod(test.negated(), -1, -2, -3, -4, -5, -6, -7);
- }
-
- public void test_negated_zero() {
- assertSame(Period.ZERO.negated(), Period.ZERO);
- }
-
- public void test_negated_max() {
- assertPeriod(Period.of(Integer.MAX_VALUE, YEARS).negated(), -Integer.MAX_VALUE, 0, 0, 0, 0, 0, 0);
- }
-
- @Test(expectedExceptions=ArithmeticException.class)
- public void test_negated_overflow() {
- Period.of(Integer.MIN_VALUE, YEARS).negated();
- }
-
- //-----------------------------------------------------------------------
- // addTo()
- //-----------------------------------------------------------------------
- @DataProvider(name="addTo")
- Object[][] data_addTo() {
- return new Object[][] {
- {pymd(0, 0, 0), date(2012, 6, 30), date(2012, 6, 30)},
-
- {pymd(1, 0, 0), date(2012, 6, 10), date(2013, 6, 10)},
- {pymd(0, 1, 0), date(2012, 6, 10), date(2012, 7, 10)},
- {pymd(0, 0, 1), date(2012, 6, 10), date(2012, 6, 11)},
-
- {pymd(-1, 0, 0), date(2012, 6, 10), date(2011, 6, 10)},
- {pymd(0, -1, 0), date(2012, 6, 10), date(2012, 5, 10)},
- {pymd(0, 0, -1), date(2012, 6, 10), date(2012, 6, 9)},
-
- {pymd(1, 2, 3), date(2012, 6, 27), date(2013, 8, 30)},
- {pymd(1, 2, 3), date(2012, 6, 28), date(2013, 8, 31)},
- {pymd(1, 2, 3), date(2012, 6, 29), date(2013, 9, 1)},
- {pymd(1, 2, 3), date(2012, 6, 30), date(2013, 9, 2)},
- {pymd(1, 2, 3), date(2012, 7, 1), date(2013, 9, 4)},
-
- {pymd(1, 0, 0), date(2011, 2, 28), date(2012, 2, 28)},
- {pymd(4, 0, 0), date(2011, 2, 28), date(2015, 2, 28)},
- {pymd(1, 0, 0), date(2012, 2, 29), date(2013, 2, 28)},
- {pymd(4, 0, 0), date(2012, 2, 29), date(2016, 2, 29)},
-
- {pymd(1, 1, 0), date(2011, 1, 29), date(2012, 2, 29)},
- {pymd(1, 2, 0), date(2012, 2, 29), date(2013, 4, 29)},
- };
- }
-
- @Test(dataProvider="addTo")
- public void test_addTo(Period period, LocalDate baseDate, LocalDate expected) {
- assertEquals(period.addTo(baseDate), expected);
- }
-
- @Test(dataProvider="addTo")
- public void test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected) {
- assertEquals(baseDate.plus(period), expected);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void test_addTo_nullZero() {
- Period.ZERO.addTo(null);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void test_addTo_nullNonZero() {
- Period.of(2, DAYS).addTo(null);
- }
-
- //-----------------------------------------------------------------------
- // subtractFrom()
- //-----------------------------------------------------------------------
- @DataProvider(name="subtractFrom")
- Object[][] data_subtractFrom() {
- return new Object[][] {
- {pymd(0, 0, 0), date(2012, 6, 30), date(2012, 6, 30)},
-
- {pymd(1, 0, 0), date(2012, 6, 10), date(2011, 6, 10)},
- {pymd(0, 1, 0), date(2012, 6, 10), date(2012, 5, 10)},
- {pymd(0, 0, 1), date(2012, 6, 10), date(2012, 6, 9)},
-
- {pymd(-1, 0, 0), date(2012, 6, 10), date(2013, 6, 10)},
- {pymd(0, -1, 0), date(2012, 6, 10), date(2012, 7, 10)},
- {pymd(0, 0, -1), date(2012, 6, 10), date(2012, 6, 11)},
-
- {pymd(1, 2, 3), date(2012, 8, 30), date(2011, 6, 27)},
- {pymd(1, 2, 3), date(2012, 8, 31), date(2011, 6, 27)},
- {pymd(1, 2, 3), date(2012, 9, 1), date(2011, 6, 28)},
- {pymd(1, 2, 3), date(2012, 9, 2), date(2011, 6, 29)},
- {pymd(1, 2, 3), date(2012, 9, 3), date(2011, 6, 30)},
- {pymd(1, 2, 3), date(2012, 9, 4), date(2011, 7, 1)},
-
- {pymd(1, 0, 0), date(2011, 2, 28), date(2010, 2, 28)},
- {pymd(4, 0, 0), date(2011, 2, 28), date(2007, 2, 28)},
- {pymd(1, 0, 0), date(2012, 2, 29), date(2011, 2, 28)},
- {pymd(4, 0, 0), date(2012, 2, 29), date(2008, 2, 29)},
-
- {pymd(1, 1, 0), date(2013, 3, 29), date(2012, 2, 29)},
- {pymd(1, 2, 0), date(2012, 2, 29), date(2010, 12, 29)},
- };
- }
-
- @Test(dataProvider="subtractFrom")
- public void test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected) {
- assertEquals(period.subtractFrom(baseDate), expected);
- }
-
- @Test(dataProvider="subtractFrom")
- public void test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected) {
- assertEquals(baseDate.minus(period), expected);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void test_subtractFrom_nullZero() {
- Period.ZERO.subtractFrom(null);
- }
-
- @Test(expectedExceptions=NullPointerException.class)
- public void test_subtractFrom_nullNonZero() {
- Period.of(2, DAYS).subtractFrom(null);
- }
-
- //-----------------------------------------------------------------------
- // toDuration()
- //-----------------------------------------------------------------------
- public void test_toDuration() {
- assertEquals(Period.ZERO.toDuration(), Duration.of(0, SECONDS));
- assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).toDuration(), Duration.ofSeconds((4 * 60 + 5) * 60L + 6, 7));
- }
-
- public void test_toDuration_calculation() {
- assertEquals(Period.of(0, 0, 0, 2, 0, 0, 0).toDuration(), Duration.ofSeconds(2 * 3600));
- assertEquals(Period.of(0, 0, 0, 0, 2, 0, 0).toDuration(), Duration.of(120, SECONDS));
- assertEquals(Period.of(0, 0, 0, 0, 0, 2, 0).toDuration(), Duration.of(2, SECONDS));
-
- assertEquals(Period.of(0, 0, 0, 0, 0, 3, 1000000000L - 1).toDuration(), Duration.ofSeconds(3, 999999999));
- assertEquals(Period.of(0, 0, 0, 0, 0, 3, 1000000000L).toDuration(), Duration.ofSeconds(4, 0));
- }
-
- public void test_toDuration_negatives() {
- assertEquals(Period.of(0, 0, 0, 0, 0, 2, 1).toDuration(), Duration.ofSeconds(2, 1));
- assertEquals(Period.of(0, 0, 0, 0, 0, 2, -1).toDuration(), Duration.ofSeconds(1, 999999999));
- assertEquals(Period.of(0, 0, 0, 0, 0, -2, 1).toDuration(), Duration.ofSeconds(-2, 1));
- assertEquals(Period.of(0, 0, 0, 0, 0, -2, -1).toDuration(), Duration.ofSeconds(-3, 999999999));
- }
-
- @Test(expectedExceptions=DateTimeException.class)
- public void test_toDuration_years() {
- Period.of(1, 0, 0, 4, 5, 6, 7).toDuration();
- }
-
- @Test(expectedExceptions=DateTimeException.class)
- public void test_toDuration_months() {
- Period.of(0, 1, 0, 4, 5, 6, 7).toDuration();
- }
-
- @Test(expectedExceptions=DateTimeException.class)
- public void test_toDuration_days() {
- Duration test = Period.of(0, 0, 1, 4, 5, 6, 7).toDuration();
- assertEquals(test, Duration.ofSeconds(101106, 7L));
- }
-
- //-----------------------------------------------------------------------
- // equals() / hashCode()
- //-----------------------------------------------------------------------
- public void test_equals() {
- assertEquals(Period.of(1, 0, 0, 0, 0, 0, 0).equals(Period.of(1, YEARS)), true);
- assertEquals(Period.of(0, 1, 0, 0, 0, 0, 0).equals(Period.of(1, MONTHS)), true);
- assertEquals(Period.of(0, 0, 1, 0, 0, 0, 0).equals(Period.of(1, DAYS)), true);
- assertEquals(Period.of(0, 0, 0, 1, 0, 0, 0).equals(Period.of(1, HOURS)), true);
- assertEquals(Period.of(0, 0, 0, 0, 1, 0, 0).equals(Period.of(1, MINUTES)), true);
- assertEquals(Period.of(0, 0, 0, 0, 0, 1, 0).equals(Period.of(1, SECONDS)), true);
- assertEquals(Period.of(1, 2, 3, 0, 0, 0, 0).equals(Period.ofDate(1, 2, 3)), true);
- assertEquals(Period.of(0, 0, 0, 1, 2, 3, 0).equals(Period.ofTime(1, 2, 3, 0)), true);
- assertEquals(Period.of(1, 2, 3, 4, 5, 6, 0).equals(Period.of(1, 2, 3, 4, 5, 6, 0)), true);
-
- assertEquals(Period.of(1, YEARS).equals(Period.of(1, YEARS)), true);
- assertEquals(Period.of(1, YEARS).equals(Period.of(2, YEARS)), false);
-
- assertEquals(Period.of(1, MONTHS).equals(Period.of(1, MONTHS)), true);
- assertEquals(Period.of(1, MONTHS).equals(Period.of(2, MONTHS)), false);
-
- assertEquals(Period.of(1, DAYS).equals(Period.of(1, DAYS)), true);
- assertEquals(Period.of(1, DAYS).equals(Period.of(2, DAYS)), false);
-
- assertEquals(Period.of(1, HOURS).equals(Period.of(1, HOURS)), true);
- assertEquals(Period.of(1, HOURS).equals(Period.of(2, HOURS)), false);
-
- assertEquals(Period.of(1, MINUTES).equals(Period.of(1, MINUTES)), true);
- assertEquals(Period.of(1, MINUTES).equals(Period.of(2, MINUTES)), false);
-
- assertEquals(Period.of(1, SECONDS).equals(Period.of(1, SECONDS)), true);
- assertEquals(Period.of(1, SECONDS).equals(Period.of(2, SECONDS)), false);
-
- assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 2, 3)), true);
- assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(0, 2, 3)), false);
- assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 0, 3)), false);
- assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 2, 0)), false);
-
- assertEquals(Period.ofTime(1, 2, 3, 0).equals(Period.ofTime(1, 2, 3, 0)), true);
- assertEquals(Period.ofTime(1, 2, 3, 0).equals(Period.ofTime(0, 2, 3, 0)), false);
- assertEquals(Period.ofTime(1, 2, 3, 0).equals(Period.ofTime(1, 0, 3, 0)), false);
- assertEquals(Period.ofTime(1, 2, 3, 0).equals(Period.ofTime(1, 2, 0, 0)), false);
- }
-
- public void test_equals_self() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 0);
- assertEquals(test.equals(test), true);
- }
-
- public void test_equals_null() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 0);
- assertEquals(test.equals(null), false);
- }
-
- public void test_equals_otherClass() {
- Period test = Period.of(1, 2, 3, 4, 5, 6, 0);
- assertEquals(test.equals(""), false);
- }
-
+ // hashCode()
//-----------------------------------------------------------------------
public void test_hashCode() {
- Period test5 = Period.of(5, DAYS);
- Period test6 = Period.of(6, DAYS);
- Period test5M = Period.of(5, MONTHS);
- Period test5Y = Period.of(5, YEARS);
+ Period test5 = Period.ofDays(5);
+ Period test6 = Period.ofDays(6);
+ Period test5M = Period.ofMonths(5);
+ Period test5Y = Period.ofYears(5);
assertEquals(test5.hashCode() == test5.hashCode(), true);
assertEquals(test5.hashCode() == test6.hashCode(), false);
assertEquals(test5.hashCode() == test5M.hashCode(), false);
assertEquals(test5.hashCode() == test5Y.hashCode(), false);
}
- //-----------------------------------------------------------------------
- // toString()
- //-----------------------------------------------------------------------
- @DataProvider(name="toStringAndParse")
- Object[][] data_toString() {
- return new Object[][] {
- {Period.ZERO, "PT0S"},
- {Period.of(0, DAYS), "PT0S"},
- {Period.of(1, YEARS), "P1Y"},
- {Period.of(1, MONTHS), "P1M"},
- {Period.of(1, DAYS), "P1D"},
- {Period.of(1, HOURS), "PT1H"},
- {Period.of(1, MINUTES), "PT1M"},
- {Period.of(1, SECONDS), "PT1S"},
- {Period.of(12, SECONDS), "PT12S"},
- {Period.of(123, SECONDS), "PT2M3S"},
- {Period.of(1234, SECONDS), "PT20M34S"},
- {Period.of(-1, SECONDS), "PT-1S"},
- {Period.of(-12, SECONDS), "PT-12S"},
- {Period.of(-123, SECONDS), "PT-2M-3S"},
- {Period.of(-1234, SECONDS), "PT-20M-34S"},
- {Period.of(1, 2, 3, 4, 5, 6, 0), "P1Y2M3DT4H5M6S"},
- {Period.of(1, 2, 3, 4, 5, 6, 700000000), "P1Y2M3DT4H5M6.7S"},
- {Period.of(0, 0, 0, 0, 0, 0, 100000000), "PT0.1S"},
- {Period.of(0, 0, 0, 0, 0, 0, -100000000), "PT-0.1S"},
- {Period.of(0, 0, 0, 0, 0, 1, -900000000), "PT0.1S"},
- {Period.of(0, 0, 0, 0, 0, -1, 900000000), "PT-0.1S"},
- {Period.of(0, 0, 0, 0, 0, 1, 100000000), "PT1.1S"},
- {Period.of(0, 0, 0, 0, 0, 1, -100000000), "PT0.9S"},
- {Period.of(0, 0, 0, 0, 0, -1, 100000000), "PT-0.9S"},
- {Period.of(0, 0, 0, 0, 0, -1, -100000000), "PT-1.1S"},
- {Period.of(0, 0, 0, 0, 0, 0, 10000000), "PT0.01S"},
- {Period.of(0, 0, 0, 0, 0, 0, -10000000), "PT-0.01S"},
- {Period.of(0, 0, 0, 0, 0, 0, 1000000), "PT0.001S"},
- {Period.of(0, 0, 0, 0, 0, 0, -1000000), "PT-0.001S"},
- {Period.of(0, 0, 0, 0, 0, 0, 1000), "PT0.000001S"},
- {Period.of(0, 0, 0, 0, 0, 0, -1000), "PT-0.000001S"},
- {Period.of(0, 0, 0, 0, 0, 0, 1), "PT0.000000001S"},
- {Period.of(0, 0, 0, 0, 0, 0, -1), "PT-0.000000001S"},
- };
- }
-
- @Test(groups="tck", dataProvider="toStringAndParse")
- public void test_toString(Period input, String expected) {
- assertEquals(input.toString(), expected);
- }
-
- //-----------------------------------------------------------------------
- // toTimeOnly() and toDateOnly()
- //-----------------------------------------------------------------------
- @DataProvider(name="toTimeOnlyAndToDateOnly")
- Object[][] data_toTimeOnlyAndToDateOnly() {
- return new Object[][] {
- {Period.ZERO, Period.ZERO, Period.ZERO},
- {Period.of(1, YEARS), Period.ofDate(1, 0, 0), Period.ZERO},
- {Period.of(2, MONTHS), Period.ofDate(0, 2, 0), Period.ZERO},
- {Period.of(3, DAYS), Period.ofDate(0, 0, 3), Period.ZERO},
- {Period.of(4, HOURS), Period.ZERO, Period.ofTime(4, 0, 0, 0)},
- {Period.of(5, MINUTES), Period.ZERO, Period.ofTime(0, 5, 0, 0)},
- {Period.of(6, SECONDS), Period.ZERO, Period.ofTime(0, 0, 6, 0)},
- {Period.of(7, NANOS), Period.ZERO, Period.ofTime(0, 0, 0, 7)},
- {Period.ofDate(1, 2, 3), Period.of(1, 2, 3, 0, 0, 0, 0), Period.ZERO},
- {Period.ofTime(4, 5, 6, 0), Period.ZERO, Period.of(0, 0, 0, 4, 5, 6, 0)},
- {Period.ofTime(4, 5, 6, 7), Period.ZERO, Period.of(0, 0, 0, 4, 5, 6, 7)},
- {Period.of(1, 2, 3, 4, 5, 6, 0), Period.ofDate(1, 2, 3), Period.ofTime(4, 5, 6, 0)},
- {Period.of(1, 2, 3, 4, 5, 6, 700000000), Period.ofDate(1, 2, 3), Period.ofTime(4, 5, 6, 700000000)},
- };
- }
-
- @Test(groups="tck", dataProvider="toTimeOnlyAndToDateOnly")
- public void test_toTimeOnlyAndToDateOnly(Period input, Period toDateOnlyResult, Period toTimeOnlyResult) {
- assertEquals(input.toDateOnly(), toDateOnlyResult);
- assertEquals(input.toTimeOnly(), toTimeOnlyResult);
- }
-
- //-----------------------------------------------------------------------
- private void assertPeriod(Period test, int y, int mo, int d, int h, int mn, int s, long n) {
- assertEquals(test.getYears(), y, "years");
- assertEquals(test.getMonths(), mo, "months");
- assertEquals(test.getDays(), d, "days");
- assertEquals(test.getHours(), h, "hours");
- assertEquals(test.getMinutes(), mn, "mins");
- assertEquals(test.getSeconds(), s, "secs");
- assertEquals(test.getNanos(), n, "nanos");
- assertEquals(test.getTimeNanos(), (((h * 60L + mn) * 60 + s) * 1_000_000_000L + n), "total nanos");
- }
-
- private static Period pymd(int y, int m, int d) {
- return Period.ofDate(y, m, d);
- }
-
- private static LocalDate date(int y, int m, int d) {
- return LocalDate.of(y, m, d);
- }
-
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment