--- a/jdk/src/share/classes/java/time/Instant.java Tue Feb 12 16:02:14 2013 +0400
+++ b/jdk/src/share/classes/java/time/Instant.java Tue Feb 12 09:25:43 2013 -0800
@@ -61,6 +61,7 @@
*/
package java.time;
+import static java.time.LocalTime.NANOS_PER_SECOND;
import static java.time.LocalTime.SECONDS_PER_DAY;
import static java.time.LocalTime.SECONDS_PER_HOUR;
import static java.time.LocalTime.SECONDS_PER_MINUTE;
@@ -76,18 +77,17 @@
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
-import java.time.format.DateTimeFormatters;
+import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Queries;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ValueRange;
import java.util.Objects;
@@ -225,10 +225,6 @@
* Serialization version.
*/
private static final long serialVersionUID = -665713676816604388L;
- /**
- * Constant for nanos per second.
- */
- private static final int NANOS_PER_SECOND = 1000_000_000;
/**
* The number of seconds from the epoch of 1970-01-01T00:00:00Z.
@@ -333,8 +329,9 @@
/**
* Obtains an instance of {@code Instant} from a temporal object.
* <p>
- * A {@code TemporalAccessor} represents some form of date and time information.
- * This factory converts the arbitrary temporal object to an instance of {@code Instant}.
+ * This obtains an instant based on the specified temporal.
+ * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+ * which this factory converts to an instance of {@code Instant}.
* <p>
* The conversion extracts the {@link ChronoField#INSTANT_SECONDS INSTANT_SECONDS}
* and {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} fields.
@@ -358,14 +355,14 @@
* {@code 2007-12-03T10:15:30:00}.
* <p>
* The string must represent a valid instant in UTC and is parsed using
- * {@link DateTimeFormatters#isoInstant()}.
+ * {@link DateTimeFormatter#ISO_INSTANT}.
*
* @param text the text to parse, not null
* @return the parsed instant, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
public static Instant parse(final CharSequence text) {
- return DateTimeFormatters.isoInstant().parse(text, Instant::from);
+ return DateTimeFormatter.ISO_INSTANT.parse(text, Instant::from);
}
//-----------------------------------------------------------------------
@@ -418,7 +415,7 @@
* All other {@code ChronoField} instances will return false.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the field is supported is determined by the field.
*
@@ -430,7 +427,7 @@
if (field instanceof ChronoField) {
return field == INSTANT_SECONDS || field == NANO_OF_SECOND || field == MICRO_OF_SECOND || field == MILLI_OF_SECOND;
}
- return field != null && field.doIsSupported(this);
+ return field != null && field.isSupportedBy(this);
}
/**
@@ -447,7 +444,7 @@
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the range can be obtained is determined by the field.
*
@@ -475,7 +472,7 @@
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
@@ -495,7 +492,7 @@
}
throw new DateTimeException("Unsupported field: " + field.getName());
}
- return range(field).checkValidIntValue(field.doGet(this), field);
+ return range(field).checkValidIntValue(field.getFrom(this), field);
}
/**
@@ -511,7 +508,7 @@
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
@@ -531,7 +528,7 @@
}
throw new DateTimeException("Unsupported field: " + field.getName());
}
- return field.doGet(this);
+ return field.getFrom(this);
}
//-----------------------------------------------------------------------
@@ -565,7 +562,7 @@
/**
* Returns an adjusted copy of this instant.
* <p>
- * This returns a new {@code Instant}, based on this one, with the date adjusted.
+ * This returns an {@code Instant}, based on this one, with the instant adjusted.
* The adjustment takes place using the specified adjuster strategy object.
* Read the documentation of the adjuster to understand what adjustment will be made.
* <p>
@@ -588,7 +585,7 @@
/**
* Returns a copy of this instant with the specified field set to a new value.
* <p>
- * This returns a new {@code Instant}, based on this one, with the value
+ * This returns an {@code Instant}, based on this one, with the value
* for the specified field changed.
* If it is not possible to set the value, because the field is not supported or for
* some other reason, an exception is thrown.
@@ -616,7 +613,7 @@
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+ * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
* passing {@code this} as the argument. In this case, the field determines
* whether and how to adjust the instant.
* <p>
@@ -647,24 +644,130 @@
}
throw new DateTimeException("Unsupported field: " + field.getName());
}
- return field.doWith(this, newValue);
+ return field.adjustInto(this, newValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a copy of this {@code Instant} truncated to the specified unit.
+ * <p>
+ * Truncating the instant returns a copy of the original with fields
+ * smaller than the specified unit set to zero.
+ * The fields are calculated on the basis of using a UTC offset as seen
+ * in {@code toString}.
+ * For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
+ * round down to the nearest minute, setting the seconds and nanoseconds to zero.
+ * <p>
+ * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+ * that divides into the length of a standard day without remainder.
+ * This includes all supplied time units on {@link ChronoUnit} and
+ * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param unit the unit to truncate to, not null
+ * @return an {@code Instant} based on this instant with the time truncated, not null
+ * @throws DateTimeException if the unit is invalid for truncation
+ */
+ public Instant truncatedTo(TemporalUnit unit) {
+ if (unit == ChronoUnit.NANOS) {
+ return this;
+ }
+ Duration unitDur = unit.getDuration();
+ if (unitDur.getSeconds() > LocalTime.SECONDS_PER_DAY) {
+ throw new DateTimeException("Unit is too large to be used for truncation");
+ }
+ long dur = unitDur.toNanos();
+ if ((LocalTime.NANOS_PER_DAY % dur) != 0) {
+ throw new DateTimeException("Unit must divide into a standard day without remainder");
+ }
+ long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
+ long result = (nod / dur) * dur;
+ return plusNanos(result - nod);
}
//-----------------------------------------------------------------------
/**
- * {@inheritDoc}
- * @throws DateTimeException {@inheritDoc}
- * @throws ArithmeticException {@inheritDoc}
+ * Returns a copy of this instant with the specified amount added.
+ * <p>
+ * This returns an {@code Instant}, based on this one, with the specified amount added.
+ * The amount is typically {@link Duration} but may be any other type implementing
+ * the {@link TemporalAmount} interface.
+ * <p>
+ * The calculation is delegated to the amount object by calling
+ * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+ * to implement the addition in any way it wishes, however it typically
+ * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+ * of the amount implementation to determine if it can be successfully added.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param amountToAdd the amount to add, not null
+ * @return an {@code Instant} based on this instant with the addition made, not null
+ * @throws DateTimeException if the addition cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
- public Instant plus(TemporalAdder adder) {
- return (Instant) adder.addTo(this);
+ public Instant plus(TemporalAmount amountToAdd) {
+ return (Instant) amountToAdd.addTo(this);
}
/**
- * {@inheritDoc}
- * @throws DateTimeException {@inheritDoc}
- * @throws ArithmeticException {@inheritDoc}
+ * Returns a copy of this instant with the specified amount added.
+ * <p>
+ * This returns an {@code Instant}, based on this one, with the amount
+ * in terms of the unit added. If it is not possible to add the amount, because the
+ * unit is not supported or for some other reason, an exception is thrown.
+ * <p>
+ * If the field is a {@link ChronoUnit} then the addition is implemented here.
+ * The supported fields behave as follows:
+ * <ul>
+ * <li>{@code NANOS} -
+ * Returns a {@code Instant} with the specified number of nanoseconds added.
+ * This is equivalent to {@link #plusNanos(long)}.
+ * <li>{@code MICROS} -
+ * Returns a {@code Instant} with the specified number of microseconds added.
+ * This is equivalent to {@link #plusNanos(long)} with the amount
+ * multiplied by 1,000.
+ * <li>{@code MILLIS} -
+ * Returns a {@code Instant} with the specified number of milliseconds added.
+ * This is equivalent to {@link #plusNanos(long)} with the amount
+ * multiplied by 1,000,000.
+ * <li>{@code SECONDS} -
+ * Returns a {@code Instant} with the specified number of seconds added.
+ * This is equivalent to {@link #plusSeconds(long)}.
+ * <li>{@code MINUTES} -
+ * Returns a {@code Instant} with the specified number of minutes added.
+ * This is equivalent to {@link #plusSeconds(long)} with the amount
+ * multiplied by 60.
+ * <li>{@code HOURS} -
+ * Returns a {@code Instant} with the specified number of hours added.
+ * This is equivalent to {@link #plusSeconds(long)} with the amount
+ * multiplied by 3,600.
+ * <li>{@code HALF_DAYS} -
+ * Returns a {@code Instant} with the specified number of half-days added.
+ * This is equivalent to {@link #plusSeconds(long)} with the amount
+ * multiplied by 43,200 (12 hours).
+ * <li>{@code DAYS} -
+ * Returns a {@code Instant} with the specified number of days added.
+ * This is equivalent to {@link #plusSeconds(long)} with the amount
+ * multiplied by 86,400 (24 hours).
+ * </ul>
+ * <p>
+ * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+ * <p>
+ * If the field is not a {@code ChronoUnit}, then the result of this method
+ * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+ * passing {@code this} as the argument. In this case, the unit determines
+ * whether and how to perform the addition.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param amountToAdd the amount of the unit to add to the result, may be negative
+ * @param unit the unit of the amount to add, not null
+ * @return an {@code Instant} based on this instant with the specified amount added, not null
+ * @throws DateTimeException if the addition cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
public Instant plus(long amountToAdd, TemporalUnit unit) {
@@ -681,7 +784,7 @@
}
throw new DateTimeException("Unsupported unit: " + unit.getName());
}
- return unit.doPlus(this, amountToAdd);
+ return unit.addTo(this, amountToAdd);
}
//-----------------------------------------------------------------------
@@ -751,19 +854,47 @@
//-----------------------------------------------------------------------
/**
- * {@inheritDoc}
- * @throws DateTimeException {@inheritDoc}
- * @throws ArithmeticException {@inheritDoc}
+ * Returns a copy of this instant with the specified amount subtracted.
+ * <p>
+ * This returns an {@code Instant}, based on this one, with the specified amount subtracted.
+ * The amount is typically {@link Duration} but may be any other type implementing
+ * the {@link TemporalAmount} interface.
+ * <p>
+ * The calculation is delegated to the amount object by calling
+ * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+ * to implement the subtraction in any way it wishes, however it typically
+ * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+ * of the amount implementation to determine if it can be successfully subtracted.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param amountToSubtract the amount to subtract, not null
+ * @return an {@code Instant} based on this instant with the subtraction made, not null
+ * @throws DateTimeException if the subtraction cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
- public Instant minus(TemporalSubtractor subtractor) {
- return (Instant) subtractor.subtractFrom(this);
+ public Instant minus(TemporalAmount amountToSubtract) {
+ return (Instant) amountToSubtract.subtractFrom(this);
}
/**
- * {@inheritDoc}
- * @throws DateTimeException {@inheritDoc}
- * @throws ArithmeticException {@inheritDoc}
+ * Returns a copy of this instant with the specified amount subtracted.
+ * <p>
+ * This returns a {@code Instant}, based on this one, with the amount
+ * in terms of the unit subtracted. If it is not possible to subtract the amount,
+ * because the unit is not supported or for some other reason, an exception is thrown.
+ * <p>
+ * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+ * See that method for a full description of how addition, and thus subtraction, works.
+ * <p>
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param amountToSubtract the amount of the unit to subtract from the result, may be negative
+ * @param unit the unit of the amount to subtract, not null
+ * @return an {@code Instant} based on this instant with the specified amount subtracted, not null
+ * @throws DateTimeException if the subtraction cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
public Instant minus(long amountToSubtract, TemporalUnit unit) {
@@ -848,7 +979,7 @@
return (R) NANOS;
}
// inline TemporalAccessor.super.query(query) as an optimization
- if (query == Queries.chrono() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+ if (query == Queries.chronology() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
return null;
}
return query.queryFrom(this);
@@ -945,7 +1076,7 @@
}
throw new DateTimeException("Unsupported unit: " + unit.getName());
}
- return unit.between(this, endInstant).getAmount();
+ return unit.between(this, endInstant);
}
private long nanosUntil(Instant end) {
@@ -959,6 +1090,43 @@
//-----------------------------------------------------------------------
/**
+ * Combines this instant with an offset to create an {@code OffsetDateTime}.
+ * <p>
+ * This returns an {@code OffsetDateTime} formed from this instant at the
+ * specified offset from UTC/Greenwich. An exception will be thrown if the
+ * instant is too large to fit into an offset date-time.
+ * <p>
+ * This method is equivalent to
+ * {@link OffsetDateTime#ofInstant(Instant, ZoneId) OffsetDateTime.ofInstant(this, offset)}.
+ *
+ * @param offset the offset to combine with, not null
+ * @return the offset date-time formed from this instant and the specified offset, not null
+ * @throws DateTimeException if the result exceeds the supported range
+ */
+ public OffsetDateTime atOffset(ZoneOffset offset) {
+ return OffsetDateTime.ofInstant(this, offset);
+ }
+
+ /**
+ * Combines this instant with a time-zone to create a {@code ZonedDateTime}.
+ * <p>
+ * This returns an {@code ZonedDateTime} formed from this instant at the
+ * specified time-zone. An exception will be thrown if the instant is too
+ * large to fit into a zoned date-time.
+ * <p>
+ * This method is equivalent to
+ * {@link ZonedDateTime#ofInstant(Instant, ZoneId) ZonedDateTime.ofInstant(this, zone)}.
+ *
+ * @param zone the zone to combine with, not null
+ * @return the zoned date-time formed from this instant and the specified zone, not null
+ * @throws DateTimeException if the result exceeds the supported range
+ */
+ public ZonedDateTime atZone(ZoneId zone) {
+ return ZonedDateTime.ofInstant(this, zone);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
* Converts this instant to the number of milliseconds from the epoch
* of 1970-01-01T00:00:00Z.
* <p>
@@ -1059,13 +1227,13 @@
/**
* A string representation of this instant using ISO-8601 representation.
* <p>
- * The format used is the same as {@link DateTimeFormatters#isoInstant()}.
+ * The format used is the same as {@link DateTimeFormatter#ISO_INSTANT}.
*
* @return an ISO-8601 representation of this instant, not null
*/
@Override
public String toString() {
- return DateTimeFormatters.isoInstant().print(this);
+ return DateTimeFormatter.ISO_INSTANT.format(this);
}
// -----------------------------------------------------------------------