8143413: add toEpochSecond methods for efficient access

Reviewed-by: rriggs, scolebourne
This commit is contained in:
Nadeesh TV 2015-12-23 13:19:58 -05:00
parent 1a8918d371
commit 6a9a5a80ea
6 changed files with 149 additions and 1 deletions

View file

@ -147,6 +147,10 @@ public final class LocalDate
* This could be used by an application as a "far future" date.
*/
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
/**
* The epoch year {@code LocalDate}, '1970-01-01'.
*/
public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
/**
* Serialization version.
@ -1864,6 +1868,29 @@ public final class LocalDate
return total - DAYS_0000_TO_1970;
}
/**
* Converts this {@code LocalDate} to the number of seconds since the epoch
* of 1970-01-01T00:00:00Z.
* <p>
* This combines this local date with the specified time and
* offset to calculate the epoch-second value, which is the
* number of elapsed seconds from 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier
* are negative.
*
* @param time the local time, not null
* @param offset the zone offset, not null
* @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
* @since 9
*/
public long toEpochSecond(LocalTime time, ZoneOffset offset) {
Objects.requireNonNull(time, "time");
Objects.requireNonNull(offset, "offset");
long secs = toEpochDay() * SECONDS_PER_DAY + time.toSecondOfDay();
secs -= offset.getTotalSeconds();
return secs;
}
//-----------------------------------------------------------------------
/**
* Compares this date to another date.

View file

@ -1490,6 +1490,30 @@ public final class LocalTime
return total;
}
/**
* Converts this {@code LocalTime} to the number of seconds since the epoch
* of 1970-01-01T00:00:00Z.
* <p>
* This combines this local time with the specified date and
* offset to calculate the epoch-second value, which is the
* number of elapsed seconds from 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier
* are negative.
*
* @param date the local date, not null
* @param offset the zone offset, not null
* @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
* @since 9
*/
public long toEpochSecond(LocalDate date, ZoneOffset offset) {
Objects.requireNonNull(date, "date");
Objects.requireNonNull(offset, "offset");
long epochDay = date.toEpochDay();
long secs = epochDay * 86400 + toSecondOfDay();
secs -= offset.getTotalSeconds();
return secs;
}
//-----------------------------------------------------------------------
/**
* Compares this time to another time.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1232,6 +1232,28 @@ public final class OffsetTime
return nod - offsetNanos;
}
/**
* Converts this {@code OffsetTime} to the number of seconds since the epoch
* of 1970-01-01T00:00:00Z.
* <p>
* This combines this offset time with the specified date to calculate the
* epoch-second value, which is the number of elapsed seconds from
* 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier
* are negative.
*
* @param date the localdate, not null
* @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
* @since 9
*/
public long toEpochSecond(LocalDate date) {
Objects.requireNonNull(date, "date");
long epochDay = date.toEpochDay();
long secs = epochDay * 86400 + time.toSecondOfDay();
secs -= offset.getTotalSeconds();
return secs;
}
//-----------------------------------------------------------------------
/**
* Compares this {@code OffsetTime} to another time.

View file

@ -2156,6 +2156,31 @@ public class TCKLocalDate extends AbstractDateTimeTest {
assertEquals(LocalDate.of(-1, 12, 31).toEpochDay(), -678942 - 40587);
}
//-----------------------------------------------------------------------
// toEpochSecond
//-----------------------------------------------------------------------
@DataProvider(name="epochSecond")
Object[][] provider_toEpochSecond() {
return new Object[][] {
{LocalDate.of(1858, 11, 17).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE), -3506720400L},
{LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62135557200L},
{LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_PTWO), 812172600L},
{LocalDate.of(1970, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_MTWO), 7200L},
{LocalDate.of(-1, 12, 31).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62167266000L},
{LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE),
Instant.ofEpochSecond(-62135600400L).getEpochSecond()},
{LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.NOON, OFFSET_PTWO),
Instant.ofEpochSecond(812196000L).getEpochSecond()},
{LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_MTWO),
LocalDateTime.of(1995, 9, 27, 5, 30).toEpochSecond(OFFSET_MTWO)},
};
}
@Test(dataProvider="epochSecond")
public void test_toEpochSecond(long actual, long expected) {
assertEquals(actual, expected);
}
//-----------------------------------------------------------------------
// compareTo()
//-----------------------------------------------------------------------

View file

@ -2433,6 +2433,32 @@ public class TCKLocalTime extends AbstractDateTimeTest {
}
}
//-----------------------------------------------------------------------
// toEpochSecond()
//--------------------------------------------------------------------------
@DataProvider(name="epochSecond")
Object[][] provider__toEpochSecond() {
return new Object[][] {
{LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO), -7200L},
{LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1965, 12, 31), OFFSET_PTWO), -126282600L},
{LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1995, 5, 3), OFFSET_MTWO), 799507800L},
{LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
Instant.ofEpochSecond(-7200).getEpochSecond()},
{LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1969, 12, 31), OFFSET_MTWO),
Instant.ofEpochSecond(-37800L).getEpochSecond()},
{LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
LocalDateTime.of(1970, 1, 1, 11, 30).toEpochSecond(OFFSET_PTWO)},
};
}
@Test(dataProvider="epochSecond")
public void test_toEpochSecond(long actual, long expected) {
assertEquals(actual, expected);
}
//-----------------------------------------------------------------------
// toSecondOfDay_fromNanoOfDay_symmetry()
//-----------------------------------------------------------------------
@Test
public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
LocalTime t = LocalTime.of(0, 0);

View file

@ -134,6 +134,7 @@ public class TCKOffsetTime extends AbstractDateTimeTest {
private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
private static final LocalDate DATE = LocalDate.of(2008, 12, 3);
private OffsetTime TEST_11_30_59_500_PONE;
@ -1148,6 +1149,29 @@ public class TCKOffsetTime extends AbstractDateTimeTest {
OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).format(null);
}
//-----------------------------------------------------------------------
// toEpochSecond()
//-----------------------------------------------------------------------
@DataProvider(name="epochSecond")
Object[][] provider_toEpochSecond() {
return new Object[][] {
{OffsetTime.of(0, 0, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1970, 1, 1)), -7200L},
{OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1995, 9, 27)), 812208600L},
{OffsetTime.of(0, 0, 0, 0, OFFSET_PONE).toEpochSecond(LocalDate.of(1970, 1, 1)),
Instant.ofEpochSecond(-3600).getEpochSecond()},
{OffsetTime.of(11, 30, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1965, 12, 31)),
Instant.ofEpochSecond(-126282600L).getEpochSecond()},
{OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1970, 1, 1)),
OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(11, 30), OFFSET_MTWO)
.toEpochSecond()},
};
}
@Test(dataProvider="epochSecond")
public void test_toEpochSecond(long actual, long expected) {
assertEquals(actual, expected);
}
//-----------------------------------------------------------------------
// compareTo()
//-----------------------------------------------------------------------