/*
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javax.time;
import static java.time.calendrical.ChronoUnit.NANOS;
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.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.calendrical.DateTimeAccessor.Query;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Test Instant.
*/
@Test
public class TestInstant extends AbstractTest {
// -----------------------------------------------------------------------
@Test(groups = { "implementation" })
public void test_interfaces() {
assertTrue(Serializable.class.isAssignableFrom(Duration.class));
assertTrue(Comparable.class.isAssignableFrom(Duration.class));
}
@Test(groups = { "tck" })
public void test_zero() {
assertEquals(Instant.EPOCH.getEpochSecond(), 0L);
assertEquals(Instant.EPOCH.getNano(), 0);
}
// -----------------------------------------------------------------------
// now()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void now() {
Instant expected = Instant.now(Clock.systemUTC());
Instant test = Instant.now();
for (int i = 0; i < 100; i++) {
if (expected.equals(test)) {
return;
}
expected = Instant.now(Clock.systemUTC());
test = Instant.now();
}
assertEquals(test, expected);
}
// -----------------------------------------------------------------------
// now(Clock)
// -----------------------------------------------------------------------
@Test(expectedExceptions = NullPointerException.class, groups = { "tck" })
public void now_Clock_nullClock() {
Instant.now(null);
}
@Test(groups = { "tck" })
public void now_Clock_allSecsInDay_utc() {
for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
Instant expected = Instant.ofEpochSecond(i).plusNanos(123456789L);
Clock clock = Clock.fixed(expected, ZoneOffset.UTC);
Instant test = Instant.now(clock);
assertEquals(test, expected);
}
}
@Test(groups = { "tck" })
public void now_Clock_allSecsInDay_beforeEpoch() {
for (int i = -1; i >= -(24 * 60 * 60); i--) {
Instant expected = Instant.ofEpochSecond(i).plusNanos(123456789L);
Clock clock = Clock.fixed(expected, ZoneOffset.UTC);
Instant test = Instant.now(clock);
assertEquals(test, expected);
}
}
// -----------------------------------------------------------------------
// ofEpochSecond(long)
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void factory_seconds_long() {
for (long i = -2; i <= 2; i++) {
Instant t = Instant.ofEpochSecond(i);
assertEquals(t.getEpochSecond(), i);
assertEquals(t.getNano(), 0);
}
}
// -----------------------------------------------------------------------
// ofEpochSecond(long,long)
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void factory_seconds_long_long() {
for (long i = -2; i <= 2; i++) {
for (int j = 0; j < 10; j++) {
Instant t = Instant.ofEpochSecond(i, j);
assertEquals(t.getEpochSecond(), i);
assertEquals(t.getNano(), j);
}
for (int j = -10; j < 0; j++) {
Instant t = Instant.ofEpochSecond(i, j);
assertEquals(t.getEpochSecond(), i - 1);
assertEquals(t.getNano(), j + 1000000000);
}
for (int j = 999999990; j < 1000000000; j++) {
Instant t = Instant.ofEpochSecond(i, j);
assertEquals(t.getEpochSecond(), i);
assertEquals(t.getNano(), j);
}
}
}
@Test(groups = { "tck" })
public void factory_seconds_long_long_nanosNegativeAdjusted() {
Instant test = Instant.ofEpochSecond(2L, -1);
assertEquals(test.getEpochSecond(), 1);
assertEquals(test.getNano(), 999999999);
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void factory_seconds_long_long_tooBig() {
Instant.ofEpochSecond(Long.MAX_VALUE, 1000000000);
}
// -----------------------------------------------------------------------
// ofEpochMilli(long)
// -----------------------------------------------------------------------
@DataProvider(name = "MillisInstantNoNanos")
Object[][] provider_factory_millis_long() {
return new Object[][] { { 0, 0, 0 }, { 1, 0, 1000000 }, { 2, 0, 2000000 }, { 999, 0, 999000000 }, { 1000, 1, 0 },
{ 1001, 1, 1000000 }, { -1, -1, 999000000 }, { -2, -1, 998000000 }, { -999, -1, 1000000 }, { -1000, -1, 0 },
{ -1001, -2, 999000000 }, };
}
@Test(dataProvider = "MillisInstantNoNanos", groups = { "tck" })
public void factory_millis_long(long millis, long expectedSeconds, int expectedNanoOfSecond) {
Instant t = Instant.ofEpochMilli(millis);
assertEquals(t.getEpochSecond(), expectedSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
// -----------------------------------------------------------------------
// parse(String)
// -----------------------------------------------------------------------
@DataProvider(name = "Parse")
Object[][] provider_factory_parse() {
return new Object[][] { { "1970-01-01T00:00:00Z", 0, 0 }, { "1970-01-01t00:00:00Z", 0, 0 },
{ "1970-01-01T00:00:00z", 0, 0 }, { "1970-01-01T00:00:00.0Z", 0, 0 },
{ "1970-01-01T00:00:00.000000000Z", 0, 0 },
{ "1970-01-01T00:00:00.000000001Z", 0, 1 }, { "1970-01-01T00:00:00.100000000Z", 0, 100000000 },
{ "1970-01-01T00:00:01Z", 1, 0 }, { "1970-01-01T00:01:00Z", 60, 0 }, { "1970-01-01T00:01:01Z", 61, 0 },
{ "1970-01-01T00:01:01.000000001Z", 61, 1 }, { "1970-01-01T01:00:00.000000000Z", 3600, 0 },
{ "1970-01-01T01:01:01.000000001Z", 3661, 1 }, { "1970-01-02T01:01:01.100000000Z", 90061, 100000000 }, };
}
@Test(dataProvider = "Parse")
public void factory_parse(String text, long expectedEpochSeconds, int expectedNanoOfSecond) {
Instant t = Instant.parse(text);
assertEquals(t.getEpochSecond(), expectedEpochSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(dataProvider = "Parse")
public void factory_parseLowercase(String text, long expectedEpochSeconds, int expectedNanoOfSecond) {
Instant t = Instant.parse(text.toLowerCase(Locale.ENGLISH));
assertEquals(t.getEpochSecond(), expectedEpochSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
// TODO: should comma be accepted?
// @Test(dataProvider="Parse")
// public void factory_parse_comma(String text, long expectedEpochSeconds, int expectedNanoOfSecond) {
// text = text.replace('.', ',');
// Instant t = Instant.parse(text);
// assertEquals(t.getEpochSecond(), expectedEpochSeconds);
// assertEquals(t.getNano(), expectedNanoOfSecond);
// }
@DataProvider(name = "ParseFailures")
Object[][] provider_factory_parseFailures() {
return new Object[][] { { "" }, { "Z" }, { "1970-01-01T00:00:00" }, { "1970-01-01T00:00:0Z" },
{ "1970-01-01T00:00:00.0000000000Z" }, };
}
@Test(dataProvider = "ParseFailures", expectedExceptions = DateTimeParseException.class)
public void factory_parseFailures(String text) {
Instant.parse(text);
}
@Test(dataProvider = "ParseFailures", expectedExceptions = DateTimeParseException.class)
public void factory_parseFailures_comma(String text) {
text = text.replace('.', ',');
Instant.parse(text);
}
@Test(expectedExceptions = NullPointerException.class)
public void factory_parse_nullText() {
Instant.parse(null);
}
// -----------------------------------------------------------------------
// serialization
// -----------------------------------------------------------------------
@Test(groups = { "implementation" })
public void test_deserializationSingleton() throws Exception {
Instant orginal = Instant.EPOCH;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(orginal);
out.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream in = new ObjectInputStream(bais);
Instant ser = (Instant) in.readObject();
assertSame(ser, Instant.EPOCH);
}
@Test(groups = { "tck" })
public void test_deserialization() throws Exception {
Instant orginal = Instant.ofEpochSecond(2);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(orginal);
out.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream in = new ObjectInputStream(bais);
Instant ser = (Instant) in.readObject();
assertEquals(Instant.ofEpochSecond(2), ser);
}
// -----------------------------------------------------------------------
// query(Query)
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_query_chrono() {
assertEquals(Instant.EPOCH.query(Query.CHRONO), null);
}
@Test(groups = { "tck" })
public void test_query_zone() {
assertEquals(Instant.EPOCH.query(Query.ZONE_ID), null);
}
@Test(groups = { "tck" })
public void test_query_timePrecision() {
assertEquals(Instant.EPOCH.query(Query.TIME_PRECISION), NANOS);
}
@Test(expectedExceptions = NullPointerException.class, groups = { "tck" })
public void test_query_null() {
Instant.EPOCH.query(null);
}
// -----------------------------------------------------------------------
@DataProvider(name = "Plus")
Object[][] provider_plus() {
return new Object[][] { { Long.MIN_VALUE, 0, Long.MAX_VALUE, 0, -1, 0 },
{ Long.MIN_VALUE, 0, 1, 0, Long.MIN_VALUE + 1, 0 }, { Long.MIN_VALUE, 0, 0, 500, Long.MIN_VALUE, 500 },
{ Long.MIN_VALUE, 0, 0, 1000000000, Long.MIN_VALUE + 1, 0 },
{ Long.MIN_VALUE + 1, 0, -1, 0, Long.MIN_VALUE, 0 },
{ Long.MIN_VALUE + 1, 0, 0, -500, Long.MIN_VALUE, 999999500 },
{ Long.MIN_VALUE + 1, 0, 0, -1000000000, Long.MIN_VALUE, 0 },
{ -4, 666666667, -4, 666666667, -7, 333333334 }, { -4, 666666667, -3, 0, -7, 666666667 },
{ -4, 666666667, -2, 0, -6, 666666667 }, { -4, 666666667, -1, 0, -5, 666666667 },
{ -4, 666666667, -1, 333333334, -4, 1 }, { -4, 666666667, -1, 666666667, -4, 333333334 },
{ -4, 666666667, -1, 999999999, -4, 666666666 }, { -4, 666666667, 0, 0, -4, 666666667 },
{ -4, 666666667, 0, 1, -4, 666666668 }, { -4, 666666667, 0, 333333333, -3, 0 },
{ -4, 666666667, 0, 666666666, -3, 333333333 }, { -4, 666666667, 1, 0, -3, 666666667 },
{ -4, 666666667, 2, 0, -2, 666666667 }, { -4, 666666667, 3, 0, -1, 666666667 },
{ -4, 666666667, 3, 333333333, 0, 0 },
{ -3, 0, -4, 666666667, -7, 666666667 }, { -3, 0, -3, 0, -6, 0 }, { -3, 0, -2, 0, -5, 0 },
{ -3, 0, -1, 0, -4, 0 }, { -3, 0, -1, 333333334, -4, 333333334 }, { -3, 0, -1, 666666667, -4, 666666667 },
{ -3, 0, -1, 999999999, -4, 999999999 }, { -3, 0, 0, 0, -3, 0 }, { -3, 0, 0, 1, -3, 1 },
{ -3, 0, 0, 333333333, -3, 333333333 }, { -3, 0, 0, 666666666, -3, 666666666 }, { -3, 0, 1, 0, -2, 0 },
{ -3, 0, 2, 0, -1, 0 }, { -3, 0, 3, 0, 0, 0 }, { -3, 0, 3, 333333333, 0, 333333333 },
{ -2, 0, -4, 666666667, -6, 666666667 }, { -2, 0, -3, 0, -5, 0 }, { -2, 0, -2, 0, -4, 0 },
{ -2, 0, -1, 0, -3, 0 }, { -2, 0, -1, 333333334, -3, 333333334 }, { -2, 0, -1, 666666667, -3, 666666667 },
{ -2, 0, -1, 999999999, -3, 999999999 }, { -2, 0, 0, 0, -2, 0 }, { -2, 0, 0, 1, -2, 1 },
{ -2, 0, 0, 333333333, -2, 333333333 }, { -2, 0, 0, 666666666, -2, 666666666 }, { -2, 0, 1, 0, -1, 0 },
{ -2, 0, 2, 0, 0, 0 }, { -2, 0, 3, 0, 1, 0 }, { -2, 0, 3, 333333333, 1, 333333333 },
{ -1, 0, -4, 666666667, -5, 666666667 }, { -1, 0, -3, 0, -4, 0 }, { -1, 0, -2, 0, -3, 0 },
{ -1, 0, -1, 0, -2, 0 }, { -1, 0, -1, 333333334, -2, 333333334 }, { -1, 0, -1, 666666667, -2, 666666667 },
{ -1, 0, -1, 999999999, -2, 999999999 }, { -1, 0, 0, 0, -1, 0 }, { -1, 0, 0, 1, -1, 1 },
{ -1, 0, 0, 333333333, -1, 333333333 }, { -1, 0, 0, 666666666, -1, 666666666 }, { -1, 0, 1, 0, 0, 0 },
{ -1, 0, 2, 0, 1, 0 }, { -1, 0, 3, 0, 2, 0 }, { -1, 0, 3, 333333333, 2, 333333333 },
{ -1, 666666667, -4, 666666667, -4, 333333334 }, { -1, 666666667, -3, 0, -4, 666666667 },
{ -1, 666666667, -2, 0, -3, 666666667 }, { -1, 666666667, -1, 0, -2, 666666667 },
{ -1, 666666667, -1, 333333334, -1, 1 }, { -1, 666666667, -1, 666666667, -1, 333333334 },
{ -1, 666666667, -1, 999999999, -1, 666666666 }, { -1, 666666667, 0, 0, -1, 666666667 },
{ -1, 666666667, 0, 1, -1, 666666668 }, { -1, 666666667, 0, 333333333, 0, 0 },
{ -1, 666666667, 0, 666666666, 0, 333333333 }, { -1, 666666667, 1, 0, 0, 666666667 },
{ -1, 666666667, 2, 0, 1, 666666667 }, { -1, 666666667, 3, 0, 2, 666666667 },
{ -1, 666666667, 3, 333333333, 3, 0 },
{ 0, 0, -4, 666666667, -4, 666666667 }, { 0, 0, -3, 0, -3, 0 }, { 0, 0, -2, 0, -2, 0 }, { 0, 0, -1, 0, -1, 0 },
{ 0, 0, -1, 333333334, -1, 333333334 }, { 0, 0, -1, 666666667, -1, 666666667 },
{ 0, 0, -1, 999999999, -1, 999999999 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 0, 1 },
{ 0, 0, 0, 333333333, 0, 333333333 }, { 0, 0, 0, 666666666, 0, 666666666 }, { 0, 0, 1, 0, 1, 0 },
{ 0, 0, 2, 0, 2, 0 }, { 0, 0, 3, 0, 3, 0 }, { 0, 0, 3, 333333333, 3, 333333333 },
{ 0, 333333333, -4, 666666667, -3, 0 }, { 0, 333333333, -3, 0, -3, 333333333 },
{ 0, 333333333, -2, 0, -2, 333333333 }, { 0, 333333333, -1, 0, -1, 333333333 },
{ 0, 333333333, -1, 333333334, -1, 666666667 }, { 0, 333333333, -1, 666666667, 0, 0 },
{ 0, 333333333, -1, 999999999, 0, 333333332 }, { 0, 333333333, 0, 0, 0, 333333333 },
{ 0, 333333333, 0, 1, 0, 333333334 }, { 0, 333333333, 0, 333333333, 0, 666666666 },
{ 0, 333333333, 0, 666666666, 0, 999999999 }, { 0, 333333333, 1, 0, 1, 333333333 },
{ 0, 333333333, 2, 0, 2, 333333333 }, { 0, 333333333, 3, 0, 3, 333333333 },
{ 0, 333333333, 3, 333333333, 3, 666666666 },
{ 1, 0, -4, 666666667, -3, 666666667 }, { 1, 0, -3, 0, -2, 0 }, { 1, 0, -2, 0, -1, 0 }, { 1, 0, -1, 0, 0, 0 },
{ 1, 0, -1, 333333334, 0, 333333334 }, { 1, 0, -1, 666666667, 0, 666666667 },
{ 1, 0, -1, 999999999, 0, 999999999 }, { 1, 0, 0, 0, 1, 0 }, { 1, 0, 0, 1, 1, 1 },
{ 1, 0, 0, 333333333, 1, 333333333 }, { 1, 0, 0, 666666666, 1, 666666666 }, { 1, 0, 1, 0, 2, 0 },
{ 1, 0, 2, 0, 3, 0 }, { 1, 0, 3, 0, 4, 0 }, { 1, 0, 3, 333333333, 4, 333333333 },
{ 2, 0, -4, 666666667, -2, 666666667 }, { 2, 0, -3, 0, -1, 0 }, { 2, 0, -2, 0, 0, 0 }, { 2, 0, -1, 0, 1, 0 },
{ 2, 0, -1, 333333334, 1, 333333334 }, { 2, 0, -1, 666666667, 1, 666666667 },
{ 2, 0, -1, 999999999, 1, 999999999 }, { 2, 0, 0, 0, 2, 0 }, { 2, 0, 0, 1, 2, 1 },
{ 2, 0, 0, 333333333, 2, 333333333 }, { 2, 0, 0, 666666666, 2, 666666666 }, { 2, 0, 1, 0, 3, 0 },
{ 2, 0, 2, 0, 4, 0 }, { 2, 0, 3, 0, 5, 0 }, { 2, 0, 3, 333333333, 5, 333333333 },
{ 3, 0, -4, 666666667, -1, 666666667 }, { 3, 0, -3, 0, 0, 0 }, { 3, 0, -2, 0, 1, 0 }, { 3, 0, -1, 0, 2, 0 },
{ 3, 0, -1, 333333334, 2, 333333334 }, { 3, 0, -1, 666666667, 2, 666666667 },
{ 3, 0, -1, 999999999, 2, 999999999 }, { 3, 0, 0, 0, 3, 0 }, { 3, 0, 0, 1, 3, 1 },
{ 3, 0, 0, 333333333, 3, 333333333 }, { 3, 0, 0, 666666666, 3, 666666666 }, { 3, 0, 1, 0, 4, 0 },
{ 3, 0, 2, 0, 5, 0 }, { 3, 0, 3, 0, 6, 0 }, { 3, 0, 3, 333333333, 6, 333333333 },
{ 3, 333333333, -4, 666666667, 0, 0 }, { 3, 333333333, -3, 0, 0, 333333333 },
{ 3, 333333333, -2, 0, 1, 333333333 }, { 3, 333333333, -1, 0, 2, 333333333 },
{ 3, 333333333, -1, 333333334, 2, 666666667 }, { 3, 333333333, -1, 666666667, 3, 0 },
{ 3, 333333333, -1, 999999999, 3, 333333332 }, { 3, 333333333, 0, 0, 3, 333333333 },
{ 3, 333333333, 0, 1, 3, 333333334 }, { 3, 333333333, 0, 333333333, 3, 666666666 },
{ 3, 333333333, 0, 666666666, 3, 999999999 }, { 3, 333333333, 1, 0, 4, 333333333 },
{ 3, 333333333, 2, 0, 5, 333333333 }, { 3, 333333333, 3, 0, 6, 333333333 },
{ 3, 333333333, 3, 333333333, 6, 666666666 },
{ Long.MAX_VALUE - 1, 0, 1, 0, Long.MAX_VALUE, 0 }, { Long.MAX_VALUE - 1, 0, 0, 500, Long.MAX_VALUE - 1, 500 },
{ Long.MAX_VALUE - 1, 0, 0, 1000000000, Long.MAX_VALUE, 0 },
{ Long.MAX_VALUE, 0, -1, 0, Long.MAX_VALUE - 1, 0 },
{ Long.MAX_VALUE, 0, 0, -500, Long.MAX_VALUE - 1, 999999500 },
{ Long.MAX_VALUE, 0, 0, -1000000000, Long.MAX_VALUE - 1, 0 },
{ Long.MAX_VALUE, 0, Long.MIN_VALUE, 0, -1, 0 }, };
}
@Test(dataProvider = "Plus", groups = { "tck" })
public void plus(long seconds, int nanos, long otherSeconds, int otherNanos, long expectedSeconds,
int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds, nanos).plus(Duration.ofSeconds(otherSeconds, otherNanos));
assertEquals(i.getEpochSecond(), expectedSeconds);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void plusOverflowTooBig() {
Instant i = Instant.ofEpochSecond(Long.MAX_VALUE, 999999999);
i.plus(Duration.ofSeconds(0, 1));
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void plusOverflowTooSmall() {
Instant i = Instant.ofEpochSecond(Long.MIN_VALUE);
i.plus(Duration.ofSeconds(-1, 999999999));
}
// -----------------------------------------------------------------------
@DataProvider(name = "PlusSeconds")
Object[][] provider_plusSeconds_long() {
return new Object[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, -1, -1, 0 },
{ 0, 0, Long.MAX_VALUE, Long.MAX_VALUE, 0 }, { 0, 0, Long.MIN_VALUE, Long.MIN_VALUE, 0 }, { 1, 0, 0, 1, 0 },
{ 1, 0, 1, 2, 0 }, { 1, 0, -1, 0, 0 }, { 1, 0, Long.MAX_VALUE - 1, Long.MAX_VALUE, 0 },
{ 1, 0, Long.MIN_VALUE, Long.MIN_VALUE + 1, 0 }, { 1, 1, 0, 1, 1 }, { 1, 1, 1, 2, 1 }, { 1, 1, -1, 0, 1 },
{ 1, 1, Long.MAX_VALUE - 1, Long.MAX_VALUE, 1 }, { 1, 1, Long.MIN_VALUE, Long.MIN_VALUE + 1, 1 },
{ -1, 1, 0, -1, 1 }, { -1, 1, 1, 0, 1 }, { -1, 1, -1, -2, 1 },
{ -1, 1, Long.MAX_VALUE, Long.MAX_VALUE - 1, 1 }, { -1, 1, Long.MIN_VALUE + 1, Long.MIN_VALUE, 1 },
{ Long.MAX_VALUE, 2, Long.MIN_VALUE, -1, 2 }, { Long.MIN_VALUE, 2, Long.MAX_VALUE, -1, 2 }, };
}
@Test(dataProvider = "PlusSeconds", groups = { "tck" })
public void plusSeconds_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant t = Instant.ofEpochSecond(seconds, nanos);
t = t.plusSeconds(amount);
assertEquals(t.getEpochSecond(), expectedSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusSeconds_long_overflowTooBig() {
Instant t = Instant.ofEpochSecond(1, 0);
t.plusSeconds(Long.MAX_VALUE);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusSeconds_long_overflowTooSmall() {
Instant t = Instant.ofEpochSecond(-1, 0);
t.plusSeconds(Long.MIN_VALUE);
}
// -----------------------------------------------------------------------
@DataProvider(name = "PlusMillis")
Object[][] provider_plusMillis_long() {
return new Object[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1000000 }, { 0, 0, 999, 0, 999000000 },
{ 0, 0, 1000, 1, 0 }, { 0, 0, 1001, 1, 1000000 }, { 0, 0, 1999, 1, 999000000 }, { 0, 0, 2000, 2, 0 },
{ 0, 0, -1, -1, 999000000 }, { 0, 0, -999, -1, 1000000 }, { 0, 0, -1000, -1, 0 },
{ 0, 0, -1001, -2, 999000000 }, { 0, 0, -1999, -2, 1000000 },
{ 0, 1, 0, 0, 1 }, { 0, 1, 1, 0, 1000001 }, { 0, 1, 998, 0, 998000001 }, { 0, 1, 999, 0, 999000001 },
{ 0, 1, 1000, 1, 1 }, { 0, 1, 1998, 1, 998000001 }, { 0, 1, 1999, 1, 999000001 }, { 0, 1, 2000, 2, 1 },
{ 0, 1, -1, -1, 999000001 }, { 0, 1, -2, -1, 998000001 }, { 0, 1, -1000, -1, 1 },
{ 0, 1, -1001, -2, 999000001 },
{ 0, 1000000, 0, 0, 1000000 }, { 0, 1000000, 1, 0, 2000000 }, { 0, 1000000, 998, 0, 999000000 },
{ 0, 1000000, 999, 1, 0 }, { 0, 1000000, 1000, 1, 1000000 }, { 0, 1000000, 1998, 1, 999000000 },
{ 0, 1000000, 1999, 2, 0 }, { 0, 1000000, 2000, 2, 1000000 }, { 0, 1000000, -1, 0, 0 },
{ 0, 1000000, -2, -1, 999000000 }, { 0, 1000000, -999, -1, 2000000 }, { 0, 1000000, -1000, -1, 1000000 },
{ 0, 1000000, -1001, -1, 0 }, { 0, 1000000, -1002, -2, 999000000 },
{ 0, 999999999, 0, 0, 999999999 }, { 0, 999999999, 1, 1, 999999 }, { 0, 999999999, 999, 1, 998999999 },
{ 0, 999999999, 1000, 1, 999999999 }, { 0, 999999999, 1001, 2, 999999 }, { 0, 999999999, -1, 0, 998999999 },
{ 0, 999999999, -1000, -1, 999999999 }, { 0, 999999999, -1001, -1, 998999999 },
{ 0, 0, Long.MAX_VALUE, Long.MAX_VALUE / 1000, (int) (Long.MAX_VALUE % 1000) * 1000000 },
{ 0, 0, Long.MIN_VALUE, Long.MIN_VALUE / 1000 - 1, (int) (Long.MIN_VALUE % 1000) * 1000000 + 1000000000 }, };
}
@Test(dataProvider = "PlusMillis", groups = { "tck" })
public void plusMillis_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant t = Instant.ofEpochSecond(seconds, nanos);
t = t.plusMillis(amount);
assertEquals(t.getEpochSecond(), expectedSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(dataProvider = "PlusMillis", groups = { "tck" })
public void plusMillis_long_oneMore(long seconds, int nanos, long amount, long expectedSeconds,
int expectedNanoOfSecond) {
Instant t = Instant.ofEpochSecond(seconds + 1, nanos);
t = t.plusMillis(amount);
assertEquals(t.getEpochSecond(), expectedSeconds + 1);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(dataProvider = "PlusMillis", groups = { "tck" })
public void plusMillis_long_minusOneLess(long seconds, int nanos, long amount, long expectedSeconds,
int expectedNanoOfSecond) {
Instant t = Instant.ofEpochSecond(seconds - 1, nanos);
t = t.plusMillis(amount);
assertEquals(t.getEpochSecond(), expectedSeconds - 1);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(groups = { "tck" })
public void plusMillis_long_max() {
Instant t = Instant.ofEpochSecond(Long.MAX_VALUE, 998999999);
t = t.plusMillis(1);
assertEquals(t.getEpochSecond(), Long.MAX_VALUE);
assertEquals(t.getNano(), 999999999);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusMillis_long_overflowTooBig() {
Instant t = Instant.ofEpochSecond(Long.MAX_VALUE, 999000000);
t.plusMillis(1);
}
@Test(groups = { "tck" })
public void plusMillis_long_min() {
Instant t = Instant.ofEpochSecond(Long.MIN_VALUE, 1000000);
t = t.plusMillis(-1);
assertEquals(t.getEpochSecond(), Long.MIN_VALUE);
assertEquals(t.getNano(), 0);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusMillis_long_overflowTooSmall() {
Instant t = Instant.ofEpochSecond(Long.MIN_VALUE, 0);
t.plusMillis(-1);
}
// -----------------------------------------------------------------------
@DataProvider(name = "PlusNanos")
Object[][] provider_plusNanos_long() {
return new Object[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1 }, { 0, 0, 999999999, 0, 999999999 },
{ 0, 0, 1000000000, 1, 0 }, { 0, 0, 1000000001, 1, 1 }, { 0, 0, 1999999999, 1, 999999999 },
{ 0, 0, 2000000000, 2, 0 }, { 0, 0, -1, -1, 999999999 }, { 0, 0, -999999999, -1, 1 },
{ 0, 0, -1000000000, -1, 0 }, { 0, 0, -1000000001, -2, 999999999 }, { 0, 0, -1999999999, -2, 1 },
{ 1, 0, 0, 1, 0 }, { 1, 0, 1, 1, 1 }, { 1, 0, 999999999, 1, 999999999 }, { 1, 0, 1000000000, 2, 0 },
{ 1, 0, 1000000001, 2, 1 }, { 1, 0, 1999999999, 2, 999999999 }, { 1, 0, 2000000000, 3, 0 },
{ 1, 0, -1, 0, 999999999 }, { 1, 0, -999999999, 0, 1 }, { 1, 0, -1000000000, 0, 0 },
{ 1, 0, -1000000001, -1, 999999999 }, { 1, 0, -1999999999, -1, 1 },
{ -1, 0, 0, -1, 0 }, { -1, 0, 1, -1, 1 }, { -1, 0, 999999999, -1, 999999999 }, { -1, 0, 1000000000, 0, 0 },
{ -1, 0, 1000000001, 0, 1 }, { -1, 0, 1999999999, 0, 999999999 }, { -1, 0, 2000000000, 1, 0 },
{ -1, 0, -1, -2, 999999999 }, { -1, 0, -999999999, -2, 1 }, { -1, 0, -1000000000, -2, 0 },
{ -1, 0, -1000000001, -3, 999999999 }, { -1, 0, -1999999999, -3, 1 },
{ 1, 1, 0, 1, 1 }, { 1, 1, 1, 1, 2 }, { 1, 1, 999999998, 1, 999999999 }, { 1, 1, 999999999, 2, 0 },
{ 1, 1, 1000000000, 2, 1 }, { 1, 1, 1999999998, 2, 999999999 }, { 1, 1, 1999999999, 3, 0 },
{ 1, 1, 2000000000, 3, 1 }, { 1, 1, -1, 1, 0 }, { 1, 1, -2, 0, 999999999 }, { 1, 1, -1000000000, 0, 1 },
{ 1, 1, -1000000001, 0, 0 }, { 1, 1, -1000000002, -1, 999999999 }, { 1, 1, -2000000000, -1, 1 },
{ 1, 999999999, 0, 1, 999999999 }, { 1, 999999999, 1, 2, 0 }, { 1, 999999999, 999999999, 2, 999999998 },
{ 1, 999999999, 1000000000, 2, 999999999 }, { 1, 999999999, 1000000001, 3, 0 },
{ 1, 999999999, -1, 1, 999999998 }, { 1, 999999999, -1000000000, 0, 999999999 },
{ 1, 999999999, -1000000001, 0, 999999998 }, { 1, 999999999, -1999999999, 0, 0 },
{ 1, 999999999, -2000000000, -1, 999999999 },
{ Long.MAX_VALUE, 0, 999999999, Long.MAX_VALUE, 999999999 },
{ Long.MAX_VALUE - 1, 0, 1999999999, Long.MAX_VALUE, 999999999 }, { Long.MIN_VALUE, 1, -1, Long.MIN_VALUE, 0 },
{ Long.MIN_VALUE + 1, 1, -1000000001, Long.MIN_VALUE, 0 },
{ 0, 0, Long.MAX_VALUE, Long.MAX_VALUE / 1000000000, (int) (Long.MAX_VALUE % 1000000000) },
{ 0, 0, Long.MIN_VALUE, Long.MIN_VALUE / 1000000000 - 1, (int) (Long.MIN_VALUE % 1000000000) + 1000000000 }, };
}
@Test(dataProvider = "PlusNanos", groups = { "tck" })
public void plusNanos_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant t = Instant.ofEpochSecond(seconds, nanos);
t = t.plusNanos(amount);
assertEquals(t.getEpochSecond(), expectedSeconds);
assertEquals(t.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusNanos_long_overflowTooBig() {
Instant t = Instant.ofEpochSecond(Long.MAX_VALUE, 999999999);
t.plusNanos(1);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void plusNanos_long_overflowTooSmall() {
Instant t = Instant.ofEpochSecond(Long.MIN_VALUE, 0);
t.plusNanos(-1);
}
// -----------------------------------------------------------------------
@DataProvider(name = "Minus")
Object[][] provider_minus() {
return new Object[][] { { Long.MIN_VALUE, 0, Long.MIN_VALUE + 1, 0, -1, 0 },
{ Long.MIN_VALUE, 0, -1, 0, Long.MIN_VALUE + 1, 0 }, { Long.MIN_VALUE, 0, 0, -500, Long.MIN_VALUE, 500 },
{ Long.MIN_VALUE, 0, 0, -1000000000, Long.MIN_VALUE + 1, 0 },
{ Long.MIN_VALUE + 1, 0, 1, 0, Long.MIN_VALUE, 0 },
{ Long.MIN_VALUE + 1, 0, 0, 500, Long.MIN_VALUE, 999999500 },
{ Long.MIN_VALUE + 1, 0, 0, 1000000000, Long.MIN_VALUE, 0 },
{ -4, 666666667, -4, 666666667, 0, 0 }, { -4, 666666667, -3, 0, -1, 666666667 },
{ -4, 666666667, -2, 0, -2, 666666667 }, { -4, 666666667, -1, 0, -3, 666666667 },
{ -4, 666666667, -1, 333333334, -3, 333333333 }, { -4, 666666667, -1, 666666667, -3, 0 },
{ -4, 666666667, -1, 999999999, -4, 666666668 }, { -4, 666666667, 0, 0, -4, 666666667 },
{ -4, 666666667, 0, 1, -4, 666666666 }, { -4, 666666667, 0, 333333333, -4, 333333334 },
{ -4, 666666667, 0, 666666666, -4, 1 }, { -4, 666666667, 1, 0, -5, 666666667 },
{ -4, 666666667, 2, 0, -6, 666666667 }, { -4, 666666667, 3, 0, -7, 666666667 },
{ -4, 666666667, 3, 333333333, -7, 333333334 },
{ -3, 0, -4, 666666667, 0, 333333333 }, { -3, 0, -3, 0, 0, 0 }, { -3, 0, -2, 0, -1, 0 },
{ -3, 0, -1, 0, -2, 0 }, { -3, 0, -1, 333333334, -3, 666666666 }, { -3, 0, -1, 666666667, -3, 333333333 },
{ -3, 0, -1, 999999999, -3, 1 }, { -3, 0, 0, 0, -3, 0 }, { -3, 0, 0, 1, -4, 999999999 },
{ -3, 0, 0, 333333333, -4, 666666667 }, { -3, 0, 0, 666666666, -4, 333333334 }, { -3, 0, 1, 0, -4, 0 },
{ -3, 0, 2, 0, -5, 0 }, { -3, 0, 3, 0, -6, 0 }, { -3, 0, 3, 333333333, -7, 666666667 },
{ -2, 0, -4, 666666667, 1, 333333333 }, { -2, 0, -3, 0, 1, 0 }, { -2, 0, -2, 0, 0, 0 },
{ -2, 0, -1, 0, -1, 0 }, { -2, 0, -1, 333333334, -2, 666666666 }, { -2, 0, -1, 666666667, -2, 333333333 },
{ -2, 0, -1, 999999999, -2, 1 }, { -2, 0, 0, 0, -2, 0 }, { -2, 0, 0, 1, -3, 999999999 },
{ -2, 0, 0, 333333333, -3, 666666667 }, { -2, 0, 0, 666666666, -3, 333333334 }, { -2, 0, 1, 0, -3, 0 },
{ -2, 0, 2, 0, -4, 0 }, { -2, 0, 3, 0, -5, 0 }, { -2, 0, 3, 333333333, -6, 666666667 },
{ -1, 0, -4, 666666667, 2, 333333333 }, { -1, 0, -3, 0, 2, 0 }, { -1, 0, -2, 0, 1, 0 }, { -1, 0, -1, 0, 0, 0 },
{ -1, 0, -1, 333333334, -1, 666666666 }, { -1, 0, -1, 666666667, -1, 333333333 },
{ -1, 0, -1, 999999999, -1, 1 }, { -1, 0, 0, 0, -1, 0 }, { -1, 0, 0, 1, -2, 999999999 },
{ -1, 0, 0, 333333333, -2, 666666667 }, { -1, 0, 0, 666666666, -2, 333333334 }, { -1, 0, 1, 0, -2, 0 },
{ -1, 0, 2, 0, -3, 0 }, { -1, 0, 3, 0, -4, 0 }, { -1, 0, 3, 333333333, -5, 666666667 },
{ -1, 666666667, -4, 666666667, 3, 0 }, { -1, 666666667, -3, 0, 2, 666666667 },
{ -1, 666666667, -2, 0, 1, 666666667 }, { -1, 666666667, -1, 0, 0, 666666667 },
{ -1, 666666667, -1, 333333334, 0, 333333333 }, { -1, 666666667, -1, 666666667, 0, 0 },
{ -1, 666666667, -1, 999999999, -1, 666666668 }, { -1, 666666667, 0, 0, -1, 666666667 },
{ -1, 666666667, 0, 1, -1, 666666666 }, { -1, 666666667, 0, 333333333, -1, 333333334 },
{ -1, 666666667, 0, 666666666, -1, 1 }, { -1, 666666667, 1, 0, -2, 666666667 },
{ -1, 666666667, 2, 0, -3, 666666667 }, { -1, 666666667, 3, 0, -4, 666666667 },
{ -1, 666666667, 3, 333333333, -4, 333333334 },
{ 0, 0, -4, 666666667, 3, 333333333 }, { 0, 0, -3, 0, 3, 0 }, { 0, 0, -2, 0, 2, 0 }, { 0, 0, -1, 0, 1, 0 },
{ 0, 0, -1, 333333334, 0, 666666666 }, { 0, 0, -1, 666666667, 0, 333333333 }, { 0, 0, -1, 999999999, 0, 1 },
{ 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, -1, 999999999 }, { 0, 0, 0, 333333333, -1, 666666667 },
{ 0, 0, 0, 666666666, -1, 333333334 }, { 0, 0, 1, 0, -1, 0 }, { 0, 0, 2, 0, -2, 0 }, { 0, 0, 3, 0, -3, 0 },
{ 0, 0, 3, 333333333, -4, 666666667 },
{ 0, 333333333, -4, 666666667, 3, 666666666 }, { 0, 333333333, -3, 0, 3, 333333333 },
{ 0, 333333333, -2, 0, 2, 333333333 }, { 0, 333333333, -1, 0, 1, 333333333 },
{ 0, 333333333, -1, 333333334, 0, 999999999 }, { 0, 333333333, -1, 666666667, 0, 666666666 },
{ 0, 333333333, -1, 999999999, 0, 333333334 }, { 0, 333333333, 0, 0, 0, 333333333 },
{ 0, 333333333, 0, 1, 0, 333333332 }, { 0, 333333333, 0, 333333333, 0, 0 },
{ 0, 333333333, 0, 666666666, -1, 666666667 }, { 0, 333333333, 1, 0, -1, 333333333 },
{ 0, 333333333, 2, 0, -2, 333333333 }, { 0, 333333333, 3, 0, -3, 333333333 },
{ 0, 333333333, 3, 333333333, -3, 0 },
{ 1, 0, -4, 666666667, 4, 333333333 }, { 1, 0, -3, 0, 4, 0 }, { 1, 0, -2, 0, 3, 0 }, { 1, 0, -1, 0, 2, 0 },
{ 1, 0, -1, 333333334, 1, 666666666 }, { 1, 0, -1, 666666667, 1, 333333333 }, { 1, 0, -1, 999999999, 1, 1 },
{ 1, 0, 0, 0, 1, 0 }, { 1, 0, 0, 1, 0, 999999999 }, { 1, 0, 0, 333333333, 0, 666666667 },
{ 1, 0, 0, 666666666, 0, 333333334 }, { 1, 0, 1, 0, 0, 0 }, { 1, 0, 2, 0, -1, 0 }, { 1, 0, 3, 0, -2, 0 },
{ 1, 0, 3, 333333333, -3, 666666667 },
{ 2, 0, -4, 666666667, 5, 333333333 }, { 2, 0, -3, 0, 5, 0 }, { 2, 0, -2, 0, 4, 0 }, { 2, 0, -1, 0, 3, 0 },
{ 2, 0, -1, 333333334, 2, 666666666 }, { 2, 0, -1, 666666667, 2, 333333333 }, { 2, 0, -1, 999999999, 2, 1 },
{ 2, 0, 0, 0, 2, 0 }, { 2, 0, 0, 1, 1, 999999999 }, { 2, 0, 0, 333333333, 1, 666666667 },
{ 2, 0, 0, 666666666, 1, 333333334 }, { 2, 0, 1, 0, 1, 0 }, { 2, 0, 2, 0, 0, 0 }, { 2, 0, 3, 0, -1, 0 },
{ 2, 0, 3, 333333333, -2, 666666667 },
{ 3, 0, -4, 666666667, 6, 333333333 }, { 3, 0, -3, 0, 6, 0 }, { 3, 0, -2, 0, 5, 0 }, { 3, 0, -1, 0, 4, 0 },
{ 3, 0, -1, 333333334, 3, 666666666 }, { 3, 0, -1, 666666667, 3, 333333333 }, { 3, 0, -1, 999999999, 3, 1 },
{ 3, 0, 0, 0, 3, 0 }, { 3, 0, 0, 1, 2, 999999999 }, { 3, 0, 0, 333333333, 2, 666666667 },
{ 3, 0, 0, 666666666, 2, 333333334 }, { 3, 0, 1, 0, 2, 0 }, { 3, 0, 2, 0, 1, 0 }, { 3, 0, 3, 0, 0, 0 },
{ 3, 0, 3, 333333333, -1, 666666667 },
{ 3, 333333333, -4, 666666667, 6, 666666666 }, { 3, 333333333, -3, 0, 6, 333333333 },
{ 3, 333333333, -2, 0, 5, 333333333 }, { 3, 333333333, -1, 0, 4, 333333333 },
{ 3, 333333333, -1, 333333334, 3, 999999999 }, { 3, 333333333, -1, 666666667, 3, 666666666 },
{ 3, 333333333, -1, 999999999, 3, 333333334 }, { 3, 333333333, 0, 0, 3, 333333333 },
{ 3, 333333333, 0, 1, 3, 333333332 }, { 3, 333333333, 0, 333333333, 3, 0 },
{ 3, 333333333, 0, 666666666, 2, 666666667 }, { 3, 333333333, 1, 0, 2, 333333333 },
{ 3, 333333333, 2, 0, 1, 333333333 }, { 3, 333333333, 3, 0, 0, 333333333 },
{ 3, 333333333, 3, 333333333, 0, 0 },
{ Long.MAX_VALUE - 1, 0, -1, 0, Long.MAX_VALUE, 0 },
{ Long.MAX_VALUE - 1, 0, 0, -500, Long.MAX_VALUE - 1, 500 },
{ Long.MAX_VALUE - 1, 0, 0, -1000000000, Long.MAX_VALUE, 0 },
{ Long.MAX_VALUE, 0, 1, 0, Long.MAX_VALUE - 1, 0 },
{ Long.MAX_VALUE, 0, 0, 500, Long.MAX_VALUE - 1, 999999500 },
{ Long.MAX_VALUE, 0, 0, 1000000000, Long.MAX_VALUE - 1, 0 },
{ Long.MAX_VALUE, 0, Long.MAX_VALUE, 0, 0, 0 }, };
}
@Test(dataProvider = "Minus", groups = { "tck" })
public void minus_Duration(long seconds, int nanos, long otherSeconds, int otherNanos, long expectedSeconds,
int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds, nanos).minus(Duration.ofSeconds(otherSeconds, otherNanos));
assertEquals(i.getEpochSecond(), expectedSeconds);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void minus_Duration_overflowTooSmall() {
Instant i = Instant.ofEpochSecond(Long.MIN_VALUE);
i.minus(Duration.ofSeconds(0, 1));
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void minus_Duration_overflowTooBig() {
Instant i = Instant.ofEpochSecond(Long.MAX_VALUE, 999999999);
i.minus(Duration.ofSeconds(-1, 999999999));
}
// -----------------------------------------------------------------------
@DataProvider(name = "MinusSeconds")
Object[][] provider_minusSeconds_long() {
return new Object[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 1, -1, 0 }, { 0, 0, -1, 1, 0 },
{ 0, 0, Long.MAX_VALUE, -Long.MAX_VALUE, 0 }, { 0, 0, Long.MIN_VALUE + 1, Long.MAX_VALUE, 0 },
{ 1, 0, 0, 1, 0 }, { 1, 0, 1, 0, 0 }, { 1, 0, -1, 2, 0 }, { 1, 0, Long.MAX_VALUE - 1, -Long.MAX_VALUE + 2, 0 },
{ 1, 0, Long.MIN_VALUE + 2, Long.MAX_VALUE, 0 }, { 1, 1, 0, 1, 1 }, { 1, 1, 1, 0, 1 }, { 1, 1, -1, 2, 1 },
{ 1, 1, Long.MAX_VALUE, -Long.MAX_VALUE + 1, 1 }, { 1, 1, Long.MIN_VALUE + 2, Long.MAX_VALUE, 1 },
{ -1, 1, 0, -1, 1 }, { -1, 1, 1, -2, 1 }, { -1, 1, -1, 0, 1 }, { -1, 1, Long.MAX_VALUE, Long.MIN_VALUE, 1 },
{ -1, 1, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1, 1 }, { -1, 1, Long.MIN_VALUE, Long.MAX_VALUE, 1 },
{ Long.MAX_VALUE, 2, Long.MAX_VALUE, 0, 2 }, { Long.MAX_VALUE - 1, 2, Long.MAX_VALUE, -1, 2 },
{ Long.MIN_VALUE, 2, Long.MIN_VALUE, 0, 2 }, { Long.MIN_VALUE + 1, 2, Long.MIN_VALUE, 1, 2 }, };
}
@Test(dataProvider = "MinusSeconds", groups = { "tck" })
public void minusSeconds_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds, nanos);
i = i.minusSeconds(amount);
assertEquals(i.getEpochSecond(), expectedSeconds);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusSeconds_long_overflowTooBig() {
Instant i = Instant.ofEpochSecond(1, 0);
i.minusSeconds(Long.MIN_VALUE + 1);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusSeconds_long_overflowTooSmall() {
Instant i = Instant.ofEpochSecond(-2, 0);
i.minusSeconds(Long.MAX_VALUE);
}
// -----------------------------------------------------------------------
@DataProvider(name = "MinusMillis")
Object[][] provider_minusMillis_long() {
return new Object[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 1, -1, 999000000 }, { 0, 0, 999, -1, 1000000 },
{ 0, 0, 1000, -1, 0 }, { 0, 0, 1001, -2, 999000000 }, { 0, 0, 1999, -2, 1000000 }, { 0, 0, 2000, -2, 0 },
{ 0, 0, -1, 0, 1000000 }, { 0, 0, -999, 0, 999000000 }, { 0, 0, -1000, 1, 0 }, { 0, 0, -1001, 1, 1000000 },
{ 0, 0, -1999, 1, 999000000 },
{ 0, 1, 0, 0, 1 }, { 0, 1, 1, -1, 999000001 }, { 0, 1, 998, -1, 2000001 }, { 0, 1, 999, -1, 1000001 },
{ 0, 1, 1000, -1, 1 }, { 0, 1, 1998, -2, 2000001 }, { 0, 1, 1999, -2, 1000001 }, { 0, 1, 2000, -2, 1 },
{ 0, 1, -1, 0, 1000001 }, { 0, 1, -2, 0, 2000001 }, { 0, 1, -1000, 1, 1 }, { 0, 1, -1001, 1, 1000001 },
{ 0, 1000000, 0, 0, 1000000 }, { 0, 1000000, 1, 0, 0 }, { 0, 1000000, 998, -1, 3000000 },
{ 0, 1000000, 999, -1, 2000000 }, { 0, 1000000, 1000, -1, 1000000 }, { 0, 1000000, 1998, -2, 3000000 },
{ 0, 1000000, 1999, -2, 2000000 }, { 0, 1000000, 2000, -2, 1000000 }, { 0, 1000000, -1, 0, 2000000 },
{ 0, 1000000, -2, 0, 3000000 }, { 0, 1000000, -999, 1, 0 }, { 0, 1000000, -1000, 1, 1000000 },
{ 0, 1000000, -1001, 1, 2000000 }, { 0, 1000000, -1002, 1, 3000000 },
{ 0, 999999999, 0, 0, 999999999 }, { 0, 999999999, 1, 0, 998999999 }, { 0, 999999999, 999, 0, 999999 },
{ 0, 999999999, 1000, -1, 999999999 }, { 0, 999999999, 1001, -1, 998999999 }, { 0, 999999999, -1, 1, 999999 },
{ 0, 999999999, -1000, 1, 999999999 }, { 0, 999999999, -1001, 2, 999999 },
{ 0, 0, Long.MAX_VALUE, -(Long.MAX_VALUE / 1000) - 1, (int) -(Long.MAX_VALUE % 1000) * 1000000 + 1000000000 },
{ 0, 0, Long.MIN_VALUE, -(Long.MIN_VALUE / 1000), (int) -(Long.MIN_VALUE % 1000) * 1000000 }, };
}
@Test(dataProvider = "MinusMillis", groups = { "tck" })
public void minusMillis_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds, nanos);
i = i.minusMillis(amount);
assertEquals(i.getEpochSecond(), expectedSeconds);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(dataProvider = "MinusMillis", groups = { "tck" })
public void minusMillis_long_oneMore(long seconds, int nanos, long amount, long expectedSeconds,
int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds + 1, nanos);
i = i.minusMillis(amount);
assertEquals(i.getEpochSecond(), expectedSeconds + 1);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(dataProvider = "MinusMillis", groups = { "tck" })
public void minusMillis_long_minusOneLess(long seconds, int nanos, long amount, long expectedSeconds,
int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds - 1, nanos);
i = i.minusMillis(amount);
assertEquals(i.getEpochSecond(), expectedSeconds - 1);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(groups = { "tck" })
public void minusMillis_long_max() {
Instant i = Instant.ofEpochSecond(Long.MAX_VALUE, 998999999);
i = i.minusMillis(-1);
assertEquals(i.getEpochSecond(), Long.MAX_VALUE);
assertEquals(i.getNano(), 999999999);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusMillis_long_overflowTooBig() {
Instant i = Instant.ofEpochSecond(Long.MAX_VALUE, 999000000);
i.minusMillis(-1);
}
@Test(groups = { "tck" })
public void minusMillis_long_min() {
Instant i = Instant.ofEpochSecond(Long.MIN_VALUE, 1000000);
i = i.minusMillis(1);
assertEquals(i.getEpochSecond(), Long.MIN_VALUE);
assertEquals(i.getNano(), 0);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusMillis_long_overflowTooSmall() {
Instant i = Instant.ofEpochSecond(Long.MIN_VALUE, 0);
i.minusMillis(1);
}
// -----------------------------------------------------------------------
@DataProvider(name = "MinusNanos")
Object[][] provider_minusNanos_long() {
return new Object[][] {
{ 0, 0, 0, 0, 0 },
{ 0, 0, 1, -1, 999999999 },
{ 0, 0, 999999999, -1, 1 },
{ 0, 0, 1000000000, -1, 0 },
{ 0, 0, 1000000001, -2, 999999999 },
{ 0, 0, 1999999999, -2, 1 },
{ 0, 0, 2000000000, -2, 0 },
{ 0, 0, -1, 0, 1 },
{ 0, 0, -999999999, 0, 999999999 },
{ 0, 0, -1000000000, 1, 0 },
{ 0, 0, -1000000001, 1, 1 },
{ 0, 0, -1999999999, 1, 999999999 },
{ 1, 0, 0, 1, 0 },
{ 1, 0, 1, 0, 999999999 },
{ 1, 0, 999999999, 0, 1 },
{ 1, 0, 1000000000, 0, 0 },
{ 1, 0, 1000000001, -1, 999999999 },
{ 1, 0, 1999999999, -1, 1 },
{ 1, 0, 2000000000, -1, 0 },
{ 1, 0, -1, 1, 1 },
{ 1, 0, -999999999, 1, 999999999 },
{ 1, 0, -1000000000, 2, 0 },
{ 1, 0, -1000000001, 2, 1 },
{ 1, 0, -1999999999, 2, 999999999 },
{ -1, 0, 0, -1, 0 },
{ -1, 0, 1, -2, 999999999 },
{ -1, 0, 999999999, -2, 1 },
{ -1, 0, 1000000000, -2, 0 },
{ -1, 0, 1000000001, -3, 999999999 },
{ -1, 0, 1999999999, -3, 1 },
{ -1, 0, 2000000000, -3, 0 },
{ -1, 0, -1, -1, 1 },
{ -1, 0, -999999999, -1, 999999999 },
{ -1, 0, -1000000000, 0, 0 },
{ -1, 0, -1000000001, 0, 1 },
{ -1, 0, -1999999999, 0, 999999999 },
{ 1, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 0 },
{ 1, 1, 999999998, 0, 3 },
{ 1, 1, 999999999, 0, 2 },
{ 1, 1, 1000000000, 0, 1 },
{ 1, 1, 1999999998, -1, 3 },
{ 1, 1, 1999999999, -1, 2 },
{ 1, 1, 2000000000, -1, 1 },
{ 1, 1, -1, 1, 2 },
{ 1, 1, -2, 1, 3 },
{ 1, 1, -1000000000, 2, 1 },
{ 1, 1, -1000000001, 2, 2 },
{ 1, 1, -1000000002, 2, 3 },
{ 1, 1, -2000000000, 3, 1 },
{ 1, 999999999, 0, 1, 999999999 },
{ 1, 999999999, 1, 1, 999999998 },
{ 1, 999999999, 999999999, 1, 0 },
{ 1, 999999999, 1000000000, 0, 999999999 },
{ 1, 999999999, 1000000001, 0, 999999998 },
{ 1, 999999999, -1, 2, 0 },
{ 1, 999999999, -1000000000, 2, 999999999 },
{ 1, 999999999, -1000000001, 3, 0 },
{ 1, 999999999, -1999999999, 3, 999999998 },
{ 1, 999999999, -2000000000, 3, 999999999 },
{ Long.MAX_VALUE, 0, -999999999, Long.MAX_VALUE, 999999999 },
{ Long.MAX_VALUE - 1, 0, -1999999999, Long.MAX_VALUE, 999999999 },
{ Long.MIN_VALUE, 1, 1, Long.MIN_VALUE, 0 },
{ Long.MIN_VALUE + 1, 1, 1000000001, Long.MIN_VALUE, 0 },
{ 0, 0, Long.MAX_VALUE, -(Long.MAX_VALUE / 1000000000) - 1, (int) -(Long.MAX_VALUE % 1000000000) + 1000000000 },
{ 0, 0, Long.MIN_VALUE, -(Long.MIN_VALUE / 1000000000), (int) -(Long.MIN_VALUE % 1000000000) }, };
}
@Test(dataProvider = "MinusNanos", groups = { "tck" })
public void minusNanos_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
Instant i = Instant.ofEpochSecond(seconds, nanos);
i = i.minusNanos(amount);
assertEquals(i.getEpochSecond(), expectedSeconds);
assertEquals(i.getNano(), expectedNanoOfSecond);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusNanos_long_overflowTooBig() {
Instant i = Instant.ofEpochSecond(Long.MAX_VALUE, 999999999);
i.minusNanos(-1);
}
@Test(expectedExceptions = { ArithmeticException.class }, groups = { "tck" })
public void minusNanos_long_overflowTooSmall() {
Instant i = Instant.ofEpochSecond(Long.MIN_VALUE, 0);
i.minusNanos(1);
}
// -----------------------------------------------------------------------
// toEpochMilli()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_toEpochMilli() {
assertEquals(Instant.ofEpochSecond(1L, 1000000).toEpochMilli(), 1001L);
assertEquals(Instant.ofEpochSecond(1L, 2000000).toEpochMilli(), 1002L);
assertEquals(Instant.ofEpochSecond(1L, 567).toEpochMilli(), 1000L);
assertEquals(Instant.ofEpochSecond(Long.MAX_VALUE / 1000).toEpochMilli(), (Long.MAX_VALUE / 1000) * 1000);
assertEquals(Instant.ofEpochSecond(Long.MIN_VALUE / 1000).toEpochMilli(), (Long.MIN_VALUE / 1000) * 1000);
assertEquals(Instant.ofEpochSecond(0L, -1000000).toEpochMilli(), -1L);
assertEquals(Instant.ofEpochSecond(0L, 1000000).toEpochMilli(), 1);
assertEquals(Instant.ofEpochSecond(0L, 999999).toEpochMilli(), 0);
assertEquals(Instant.ofEpochSecond(0L, 1).toEpochMilli(), 0);
assertEquals(Instant.ofEpochSecond(0L, 0).toEpochMilli(), 0);
assertEquals(Instant.ofEpochSecond(0L, -1).toEpochMilli(), -1L);
assertEquals(Instant.ofEpochSecond(0L, -999999).toEpochMilli(), -1L);
assertEquals(Instant.ofEpochSecond(0L, -1000000).toEpochMilli(), -1L);
assertEquals(Instant.ofEpochSecond(0L, -1000001).toEpochMilli(), -2L);
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void test_toEpochMilli_tooBig() {
Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1).toEpochMilli();
}
@Test(expectedExceptions = ArithmeticException.class, groups = { "tck" })
public void test_toEpochMilli_tooSmall() {
Instant.ofEpochSecond(Long.MIN_VALUE / 1000 - 1).toEpochMilli();
}
// -----------------------------------------------------------------------
// compareTo()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_comparisons() {
doTest_comparisons_Instant(Instant.ofEpochSecond(-2L, 0), Instant.ofEpochSecond(-2L, 999999998),
Instant.ofEpochSecond(-2L, 999999999), Instant.ofEpochSecond(-1L, 0), Instant.ofEpochSecond(-1L, 1),
Instant.ofEpochSecond(-1L, 999999998), Instant.ofEpochSecond(-1L, 999999999), Instant.ofEpochSecond(0L, 0),
Instant.ofEpochSecond(0L, 1), Instant.ofEpochSecond(0L, 2), Instant.ofEpochSecond(0L, 999999999),
Instant.ofEpochSecond(1L, 0), Instant.ofEpochSecond(2L, 0));
}
void doTest_comparisons_Instant(Instant... instants) {
for (int i = 0; i < instants.length; i++) {
Instant a = instants[i];
for (int j = 0; j < instants.length; j++) {
Instant b = instants[j];
if (i < j) {
assertEquals(a.compareTo(b) < 0, true, a + " <=> " + b);
assertEquals(a.isBefore(b), true, a + " <=> " + b);
assertEquals(a.isAfter(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.isBefore(b), false, a + " <=> " + b);
assertEquals(a.isAfter(b), true, a + " <=> " + b);
assertEquals(a.equals(b), false, a + " <=> " + b);
} else {
assertEquals(a.compareTo(b), 0, a + " <=> " + b);
assertEquals(a.isBefore(b), false, a + " <=> " + b);
assertEquals(a.isAfter(b), false, a + " <=> " + b);
assertEquals(a.equals(b), true, a + " <=> " + b);
}
}
}
}
@Test(expectedExceptions = NullPointerException.class, groups = { "tck" })
public void test_compareTo_ObjectNull() {
Instant a = Instant.ofEpochSecond(0L, 0);
a.compareTo(null);
}
@Test(expectedExceptions = NullPointerException.class, groups = { "tck" })
public void test_isBefore_ObjectNull() {
Instant a = Instant.ofEpochSecond(0L, 0);
a.isBefore(null);
}
@Test(expectedExceptions = NullPointerException.class, groups = { "tck" })
public void test_isAfter_ObjectNull() {
Instant a = Instant.ofEpochSecond(0L, 0);
a.isAfter(null);
}
@Test(expectedExceptions = ClassCastException.class, groups = { "tck" })
@SuppressWarnings({ "unchecked", "rawtypes" })
public void compareToNonInstant() {
Comparable c = Instant.ofEpochSecond(0L);
c.compareTo(new Object());
}
// -----------------------------------------------------------------------
// equals()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_equals() {
Instant test5a = Instant.ofEpochSecond(5L, 20);
Instant test5b = Instant.ofEpochSecond(5L, 20);
Instant test5n = Instant.ofEpochSecond(5L, 30);
Instant test6 = Instant.ofEpochSecond(6L, 20);
assertEquals(test5a.equals(test5a), true);
assertEquals(test5a.equals(test5b), true);
assertEquals(test5a.equals(test5n), false);
assertEquals(test5a.equals(test6), false);
assertEquals(test5b.equals(test5a), true);
assertEquals(test5b.equals(test5b), true);
assertEquals(test5b.equals(test5n), false);
assertEquals(test5b.equals(test6), false);
assertEquals(test5n.equals(test5a), false);
assertEquals(test5n.equals(test5b), false);
assertEquals(test5n.equals(test5n), true);
assertEquals(test5n.equals(test6), false);
assertEquals(test6.equals(test5a), false);
assertEquals(test6.equals(test5b), false);
assertEquals(test6.equals(test5n), false);
assertEquals(test6.equals(test6), true);
}
@Test(groups = { "tck" })
public void test_equals_null() {
Instant test5 = Instant.ofEpochSecond(5L, 20);
assertEquals(test5.equals(null), false);
}
@Test(groups = { "tck" })
public void test_equals_otherClass() {
Instant test5 = Instant.ofEpochSecond(5L, 20);
assertEquals(test5.equals(""), false);
}
// -----------------------------------------------------------------------
// hashCode()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_hashCode() {
Instant test5a = Instant.ofEpochSecond(5L, 20);
Instant test5b = Instant.ofEpochSecond(5L, 20);
Instant test5n = Instant.ofEpochSecond(5L, 30);
Instant test6 = Instant.ofEpochSecond(6L, 20);
assertEquals(test5a.hashCode() == test5a.hashCode(), true);
assertEquals(test5a.hashCode() == test5b.hashCode(), true);
assertEquals(test5b.hashCode() == test5b.hashCode(), true);
assertEquals(test5a.hashCode() == test5n.hashCode(), false);
assertEquals(test5a.hashCode() == test6.hashCode(), false);
}
// -----------------------------------------------------------------------
// toString()
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_toString() {
Instant t = Instant.ofEpochSecond(0L, 567);
assertEquals(t.toString(), "1970-01-01T00:00:00.000000567Z");
}
// -----------------------------------------------------------------------
@Test(groups = { "tck" })
public void test_serialization_format() throws ClassNotFoundException, IOException {
assertEqualsSerialisedForm(Instant.ofEpochMilli(1347830279338l));
}
@Test(groups = { "tck" })
public void test_serialization() throws ClassNotFoundException, IOException {
assertSerializable(Instant.ofEpochMilli(134l));
}
}