changeset 13398:d0a642db657b

8143413: add toEpochSecond methods for efficient access Reviewed-by: rriggs, scolebourne
author ntv
date Wed, 23 Dec 2015 13:19:58 -0500
parents ec08bf9b7cb2
children f9a4a8cbbf49
files src/java.base/share/classes/java/time/LocalDate.java src/java.base/share/classes/java/time/LocalTime.java src/java.base/share/classes/java/time/OffsetTime.java test/java/time/tck/java/time/TCKLocalDate.java test/java/time/tck/java/time/TCKLocalTime.java test/java/time/tck/java/time/TCKOffsetTime.java
diffstat 6 files changed, 149 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/time/LocalDate.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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.
+     * <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.
--- a/src/java.base/share/classes/java/time/LocalTime.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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.
+     * <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.
--- a/src/java.base/share/classes/java/time/OffsetTime.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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.
+     * <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.
--- a/test/java/time/tck/java/time/TCKLocalDate.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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
--- a/test/java/time/tck/java/time/TCKLocalTime.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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);
--- a/test/java/time/tck/java/time/TCKOffsetTime.java	Fri Dec 18 17:42:06 2015 +0100
+++ b/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