< prev index next >

jdk/src/java.base/share/classes/java/time/Clock.java

Print this page


   1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  44  *    and/or other materials provided with the distribution.
  45  *
  46  *  * Neither the name of JSR-310 nor the names of its contributors
  47  *    may be used to endorse or promote products derived from this software
  48  *    without specific prior written permission.
  49  *
  50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  54  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  55  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  56  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  57  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  58  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61  */
  62 package java.time;
  63 


  64 import static java.time.LocalTime.NANOS_PER_MINUTE;
  65 import static java.time.LocalTime.NANOS_PER_SECOND;
  66 
  67 import java.io.Serializable;
  68 import java.util.Objects;
  69 import java.util.TimeZone;

  70 
  71 /**
  72  * A clock providing access to the current instant, date and time using a time-zone.
  73  * <p>
  74  * Instances of this class are used to find the current instant, which can be
  75  * interpreted using the stored time-zone to find the current date and time.
  76  * As such, a clock can be used instead of {@link System#currentTimeMillis()}
  77  * and {@link TimeZone#getDefault()}.
  78  * <p>
  79  * Use of a {@code Clock} is optional. All key date-time classes also have a
  80  * {@code now()} factory method that uses the system clock in the default time zone.
  81  * The primary purpose of this abstraction is to allow alternate clocks to be
  82  * plugged in as and when required. Applications use an object to obtain the
  83  * current time rather than a static method. This can simplify testing.
  84  * <p>
  85  * Best practice for applications is to pass a {@code Clock} into any method
  86  * that requires the current instant. A dependency injection framework is one
  87  * way to achieve this:
  88  * <pre>
  89  *  public class MyBean {


 429      * A hash code for this clock.
 430      * <p>
 431      * Clocks should override this method based on
 432      * their state and to meet the contract of {@link Object#hashCode}.
 433      * If not overridden, the behavior is defined by {@link Object#hashCode}
 434      *
 435      * @return a suitable hash code
 436      */
 437     @Override
 438     public  int hashCode() {
 439         return super.hashCode();
 440     }
 441 
 442     //-----------------------------------------------------------------------
 443     /**
 444      * Implementation of a clock that always returns the latest time from
 445      * {@link System#currentTimeMillis()}.
 446      */
 447     static final class SystemClock extends Clock implements Serializable {
 448         private static final long serialVersionUID = 6740630888130243051L;


 449         private final ZoneId zone;









 450 
 451         SystemClock(ZoneId zone) {
 452             this.zone = zone;

 453         }
 454         @Override
 455         public ZoneId getZone() {
 456             return zone;
 457         }
 458         @Override
 459         public Clock withZone(ZoneId zone) {
 460             if (zone.equals(this.zone)) {  // intentional NPE
 461                 return this;
 462             }
 463             return new SystemClock(zone);
 464         }
 465         @Override
 466         public long millis() {






 467             return System.currentTimeMillis();
 468         }
 469         @Override
 470         public Instant instant() {
 471             return Instant.ofEpochMilli(millis());

































 472         }
 473         @Override
 474         public boolean equals(Object obj) {
 475             if (obj instanceof SystemClock) {
 476                 return zone.equals(((SystemClock) obj).zone);
 477             }
 478             return false;
 479         }
 480         @Override
 481         public int hashCode() {
 482             return zone.hashCode() + 1;
 483         }
 484         @Override
 485         public String toString() {
 486             return "SystemClock[" + zone + "]";
 487         }






 488     }
 489 
 490     //-----------------------------------------------------------------------
 491     /**
 492      * Implementation of a clock that always returns the same instant.
 493      * This is typically used for testing.
 494      */
 495     static final class FixedClock extends Clock implements Serializable {
 496        private static final long serialVersionUID = 7430389292664866958L;
 497         private final Instant instant;
 498         private final ZoneId zone;
 499 
 500         FixedClock(Instant fixedInstant, ZoneId zone) {
 501             this.instant = fixedInstant;
 502             this.zone = zone;
 503         }
 504         @Override
 505         public ZoneId getZone() {
 506             return zone;
 507         }


   1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  44  *    and/or other materials provided with the distribution.
  45  *
  46  *  * Neither the name of JSR-310 nor the names of its contributors
  47  *    may be used to endorse or promote products derived from this software
  48  *    without specific prior written permission.
  49  *
  50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  54  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  55  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  56  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  57  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  58  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61  */
  62 package java.time;
  63 
  64 import java.io.IOException;
  65 import java.io.ObjectInputStream;
  66 import static java.time.LocalTime.NANOS_PER_MINUTE;
  67 import static java.time.LocalTime.NANOS_PER_SECOND;
  68 
  69 import java.io.Serializable;
  70 import java.util.Objects;
  71 import java.util.TimeZone;
  72 import sun.misc.VM;
  73 
  74 /**
  75  * A clock providing access to the current instant, date and time using a time-zone.
  76  * <p>
  77  * Instances of this class are used to find the current instant, which can be
  78  * interpreted using the stored time-zone to find the current date and time.
  79  * As such, a clock can be used instead of {@link System#currentTimeMillis()}
  80  * and {@link TimeZone#getDefault()}.
  81  * <p>
  82  * Use of a {@code Clock} is optional. All key date-time classes also have a
  83  * {@code now()} factory method that uses the system clock in the default time zone.
  84  * The primary purpose of this abstraction is to allow alternate clocks to be
  85  * plugged in as and when required. Applications use an object to obtain the
  86  * current time rather than a static method. This can simplify testing.
  87  * <p>
  88  * Best practice for applications is to pass a {@code Clock} into any method
  89  * that requires the current instant. A dependency injection framework is one
  90  * way to achieve this:
  91  * <pre>
  92  *  public class MyBean {


 432      * A hash code for this clock.
 433      * <p>
 434      * Clocks should override this method based on
 435      * their state and to meet the contract of {@link Object#hashCode}.
 436      * If not overridden, the behavior is defined by {@link Object#hashCode}
 437      *
 438      * @return a suitable hash code
 439      */
 440     @Override
 441     public  int hashCode() {
 442         return super.hashCode();
 443     }
 444 
 445     //-----------------------------------------------------------------------
 446     /**
 447      * Implementation of a clock that always returns the latest time from
 448      * {@link System#currentTimeMillis()}.
 449      */
 450     static final class SystemClock extends Clock implements Serializable {
 451         private static final long serialVersionUID = 6740630888130243051L;
 452         private static final long OFFSET_SEED =
 453                 System.currentTimeMillis()/1000 - 1024; // initial offest
 454         private final ZoneId zone;
 455         // We don't actually need a volatile here.
 456         // We don't care if offset is set or read concurrently by multiple
 457         // threads - we just need a value which is 'recent enough' - in other
 458         // words something that has been updated at least once in the last
 459         // 2^32 secs (~136 years). And even if we by chance see an invalid
 460         // offset, the worst that can happen is that we will get a -1 value
 461         // from getNanoTimeAdjustment, forcing us to update the offset
 462         // once again.
 463         private transient long offset;
 464 
 465         SystemClock(ZoneId zone) {
 466             this.zone = zone;
 467             this.offset = OFFSET_SEED;
 468         }
 469         @Override
 470         public ZoneId getZone() {
 471             return zone;
 472         }
 473         @Override
 474         public Clock withZone(ZoneId zone) {
 475             if (zone.equals(this.zone)) {  // intentional NPE
 476                 return this;
 477             }
 478             return new SystemClock(zone);
 479         }
 480         @Override
 481         public long millis() {
 482             // System.currentTimeMillis() and VM.getNanoTimeAdjustment(offset)
 483             // use the same time source - System.currentTimeMillis() simply
 484             // limits the resolution to milliseconds.
 485             // So we take the faster path and call System.currentTimeMillis()
 486             // directly - in order to avoid the performance penalty of
 487             // VM.getNanoTimeAdjustment(offset) which is less efficient.
 488             return System.currentTimeMillis();
 489         }
 490         @Override
 491         public Instant instant() {
 492             // Take a local copy of offset. offset can be updated concurrently
 493             // by other threads (even if we haven't made it volatile) so we will
 494             // work with a local copy.
 495             long localOffset = offset;
 496             long adjustment = VM.getNanoTimeAdjustment(localOffset);
 497 
 498             if (adjustment == -1) {
 499                 // -1 is a sentinel value returned by VM.getNanoTimeAdjustment
 500                 // when the offset it is given is too far off the current UTC
 501                 // time. In principle, this should not happen unless the
 502                 // JVM has run for more than ~136 years (not likely) or
 503                 // someone is fiddling with the system time, or the offset is
 504                 // by chance at 1ns in the future (very unlikely).
 505                 // We can easily recover from all these conditions by bringing
 506                 // back the offset in range and retry.
 507 
 508                 // bring back the offset in range. We use -1024 to make
 509                 // it more unlikely to hit the 1ns in the future condition.
 510                 localOffset = System.currentTimeMillis()/1000 - 1024;
 511 
 512                 // retry
 513                 adjustment = VM.getNanoTimeAdjustment(localOffset);
 514 
 515                 if (adjustment == -1) {
 516                     // Should not happen: we just recomputed a new offset.
 517                     // It should have fixed the issue.
 518                     throw new InternalError("Offset " + localOffset + " is not in range");
 519                 } else {
 520                     // OK - recovery succeeded. Update the offset for the
 521                     // next call...
 522                     offset = localOffset;
 523                 }
 524             }
 525             return Instant.ofEpochSecond(localOffset, adjustment);
 526         }
 527         @Override
 528         public boolean equals(Object obj) {
 529             if (obj instanceof SystemClock) {
 530                 return zone.equals(((SystemClock) obj).zone);
 531             }
 532             return false;
 533         }
 534         @Override
 535         public int hashCode() {
 536             return zone.hashCode() + 1;
 537         }
 538         @Override
 539         public String toString() {
 540             return "SystemClock[" + zone + "]";
 541         }
 542         private void readObject(ObjectInputStream is)
 543                 throws IOException, ClassNotFoundException {
 544             // ensure that offset is initialized
 545             is.defaultReadObject();
 546             offset = OFFSET_SEED;
 547         }
 548     }
 549 
 550     //-----------------------------------------------------------------------
 551     /**
 552      * Implementation of a clock that always returns the same instant.
 553      * This is typically used for testing.
 554      */
 555     static final class FixedClock extends Clock implements Serializable {
 556        private static final long serialVersionUID = 7430389292664866958L;
 557         private final Instant instant;
 558         private final ZoneId zone;
 559 
 560         FixedClock(Instant fixedInstant, ZoneId zone) {
 561             this.instant = fixedInstant;
 562             this.zone = zone;
 563         }
 564         @Override
 565         public ZoneId getZone() {
 566             return zone;
 567         }


< prev index next >