# HG changeset patch # User ntv # Date 1450894798 18000 # Node ID bc3eacb42ab172bfd77b867e1f45e234d0575bb8 # Parent de746e7eb1e3ea9797e6fa592b099508a9fb54ab 8143413: add toEpochSecond methods for efficient access Reviewed-by: rriggs, scolebourne diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/src/java.base/share/classes/java/time/LocalDate.java --- a/jdk/src/java.base/share/classes/java/time/LocalDate.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java Wed Dec 23 13:19:58 2015 -0500 @@ -147,6 +147,10 @@ * 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 @@ return total - DAYS_0000_TO_1970; } + /** + * Converts this {@code LocalDate} to the number of seconds since the epoch + * of 1970-01-01T00:00:00Z. + *

+ * 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. diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/src/java.base/share/classes/java/time/LocalTime.java --- a/jdk/src/java.base/share/classes/java/time/LocalTime.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java Wed Dec 23 13:19:58 2015 -0500 @@ -1490,6 +1490,30 @@ return total; } + /** + * Converts this {@code LocalTime} to the number of seconds since the epoch + * of 1970-01-01T00:00:00Z. + *

+ * 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. diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/src/java.base/share/classes/java/time/OffsetTime.java --- a/jdk/src/java.base/share/classes/java/time/OffsetTime.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/time/OffsetTime.java Wed Dec 23 13:19:58 2015 -0500 @@ -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 @@ return nod - offsetNanos; } + /** + * Converts this {@code OffsetTime} to the number of seconds since the epoch + * of 1970-01-01T00:00:00Z. + *

+ * 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. diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/test/java/time/tck/java/time/TCKLocalDate.java --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java Wed Dec 23 13:19:58 2015 -0500 @@ -2157,6 +2157,31 @@ } //----------------------------------------------------------------------- + // 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() //----------------------------------------------------------------------- @Test diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/test/java/time/tck/java/time/TCKLocalTime.java --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java Wed Dec 23 13:19:58 2015 -0500 @@ -2433,6 +2433,32 @@ } } + //----------------------------------------------------------------------- + // 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); diff -r de746e7eb1e3 -r bc3eacb42ab1 jdk/test/java/time/tck/java/time/TCKOffsetTime.java --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Fri Dec 18 17:42:06 2015 +0100 +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Wed Dec 23 13:19:58 2015 -0500 @@ -134,6 +134,7 @@ 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; @@ -1149,6 +1150,29 @@ } //----------------------------------------------------------------------- + // 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() //----------------------------------------------------------------------- @Test