1c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer/*
2c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
5c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This code is free software; you can redistribute it and/or modify it
6c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * under the terms of the GNU General Public License version 2 only, as
7c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * published by the Free Software Foundation.  Oracle designates this
8c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * particular file as subject to the "Classpath" exception as provided
9c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * by Oracle in the LICENSE file that accompanied this code.
10c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
11c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This code is distributed in the hope that it will be useful, but WITHOUT
12c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * version 2 for more details (a copy is included in the LICENSE file that
15c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * accompanied this code).
16c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
17c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * You should have received a copy of the GNU General Public License version
18c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * 2 along with this work; if not, write to the Free Software Foundation,
19c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
21c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * or visit www.oracle.com if you need additional information or have any
23c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * questions.
24c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer */
25c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
26c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer/*
27c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This file is available under and governed by the GNU General Public
28c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * License version 2 only, as published by the Free Software Foundation.
29c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * However, the following notice accompanied the original version of this
30c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * file:
31c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
32c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
33c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
34c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * All rights reserved.
35c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
36c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Redistribution and use in source and binary forms, with or without
37c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * modification, are permitted provided that the following conditions are met:
38c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
39c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *  * Redistributions of source code must retain the above copyright notice,
40c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    this list of conditions and the following disclaimer.
41c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
42c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *  * Redistributions in binary form must reproduce the above copyright notice,
43c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    this list of conditions and the following disclaimer in the documentation
44c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    and/or other materials provided with the distribution.
45c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
46c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *  * Neither the name of JSR-310 nor the names of its contributors
47c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    may be used to endorse or promote products derived from this software
48c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    without specific prior written permission.
49c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
50c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer */
62c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerpackage java.time;
63c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
64c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.LocalTime.NANOS_PER_MINUTE;
65c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.LocalTime.NANOS_PER_SECOND;
66c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
67c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.Serializable;
68c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.Objects;
69c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.TimeZone;
70c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
71c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer/**
72c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * A clock providing access to the current instant, date and time using a time-zone.
73c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
74c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Instances of this class are used to find the current instant, which can be
75c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * interpreted using the stored time-zone to find the current date and time.
76c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * As such, a clock can be used instead of {@link System#currentTimeMillis()}
77c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * and {@link TimeZone#getDefault()}.
78c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
79c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Use of a {@code Clock} is optional. All key date-time classes also have a
80c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * {@code now()} factory method that uses the system clock in the default time zone.
81c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The primary purpose of this abstraction is to allow alternate clocks to be
82c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * plugged in as and when required. Applications use an object to obtain the
83c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * current time rather than a static method. This can simplify testing.
84c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
85c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Best practice for applications is to pass a {@code Clock} into any method
86c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * that requires the current instant. A dependency injection framework is one
87c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * way to achieve this:
88c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <pre>
89c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *  public class MyBean {
90c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    private Clock clock;  // dependency inject
91c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    ...
92c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    public void process(LocalDate eventDate) {
93c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *      if (eventDate.isBefore(LocalDate.now(clock)) {
94c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *        ...
95c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *      }
96c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *    }
97c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *  }
98c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * </pre>
99c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This approach allows an alternate clock, such as {@link #fixed(Instant, ZoneId) fixed}
100c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * or {@link #offset(Clock, Duration) offset} to be used during testing.
101c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
102c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The {@code system} factory methods provide clocks based on the best available
103c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * system clock This may use {@link System#currentTimeMillis()}, or a higher
104c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * resolution clock if one is available.
105c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
106c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * @implSpec
107c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This abstract class must be implemented with care to ensure other classes operate correctly.
108c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * All implementations that can be instantiated must be final, immutable and thread-safe.
109c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
110c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The principal methods are defined to allow the throwing of an exception.
111c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * In normal use, no exceptions will be thrown, however one possible implementation would be to
112c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * obtain the time from a central time server across the network. Obviously, in this case the
113c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * lookup could fail, and so the method is permitted to throw an exception.
114c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
115c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The returned instants from {@code Clock} work on a time-scale that ignores leap seconds,
116c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * as described in {@link Instant}. If the implementation wraps a source that provides leap
117c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * second information, then a mechanism should be used to "smooth" the leap second.
118c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The Java Time-Scale mandates the use of UTC-SLS, however clock implementations may choose
119c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * how accurate they are with the time-scale so long as they document how they work.
120c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Implementations are therefore not required to actually perform the UTC-SLS slew or to
121c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * otherwise be aware of leap seconds.
122c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
123c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Implementations should implement {@code Serializable} wherever possible and must
124c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * document whether or not they do support serialization.
125c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
126c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * @implNote
127c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The clock implementation provided here is based on {@link System#currentTimeMillis()}.
128c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * That method provides little to no guarantee about the accuracy of the clock.
129c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Applications requiring a more accurate clock must implement this abstract class
130c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * themselves using a different external clock, such as an NTP server.
131c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
132c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * @since 1.8
133c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer */
134c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerpublic abstract class Clock {
135c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
136c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
137c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns the current instant using the best available
138c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * system clock, converting to date and time using the UTC time-zone.
139c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
140c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock, rather than {@link #systemDefaultZone()}, should be used when
141c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * you need the current instant without the date or time.
142c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
143c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock is based on the best available system clock.
144c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This may use {@link System#currentTimeMillis()}, or a higher resolution
145c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * clock if one is available.
146c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
147c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Conversion from instant to date or time uses the {@linkplain ZoneOffset#UTC UTC time-zone}.
148c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
149c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
150c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is equivalent to {@code system(ZoneOffset.UTC)}.
151c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
152c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that uses the best available system clock in the UTC zone, not null
153c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
154c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock systemUTC() {
155c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new SystemClock(ZoneOffset.UTC);
156c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
157c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
158c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
159c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns the current instant using the best available
160c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * system clock, converting to date and time using the default time-zone.
161c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
162c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock is based on the best available system clock.
163c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This may use {@link System#currentTimeMillis()}, or a higher resolution
164c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * clock if one is available.
165c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
166c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Using this method hard codes a dependency to the default time-zone into your application.
167c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is recommended to avoid this and use a specific time-zone whenever possible.
168c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The {@link #systemUTC() UTC clock} should be used when you need the current instant
169c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * without the date or time.
170c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
171c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
172c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is equivalent to {@code system(ZoneId.systemDefault())}.
173c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
174c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that uses the best available system clock in the default zone, not null
175c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @see ZoneId#systemDefault()
176c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
177c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock systemDefaultZone() {
178c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new SystemClock(ZoneId.systemDefault());
179c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
180c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
181c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
182c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns the current instant using best available
183c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * system clock.
184c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
185c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock is based on the best available system clock.
186c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This may use {@link System#currentTimeMillis()}, or a higher resolution
187c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * clock if one is available.
188c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
189c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Conversion from instant to date or time uses the specified time-zone.
190c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
191c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
192c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
193c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param zone  the time-zone to use to convert the instant to date-time, not null
194c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that uses the best available system clock in the specified zone, not null
195c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
196c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock system(ZoneId zone) {
197c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(zone, "zone");
198c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new SystemClock(zone);
199c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
200c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
201c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-------------------------------------------------------------------------
202c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
203c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns the current instant ticking in whole seconds
204c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * using best available system clock.
205c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
206c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock will always have the nano-of-second field set to zero.
207c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This ensures that the visible time ticks in whole seconds.
208c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The underlying clock is the best available system clock, equivalent to
209c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * using {@link #system(ZoneId)}.
210c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
211c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementations may use a caching strategy for performance reasons.
212c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * As such, it is possible that the start of the second observed via this
213c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * clock will be later than that observed directly via the underlying clock.
214c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
215c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
216c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is equivalent to {@code tick(system(zone), Duration.ofSeconds(1))}.
217c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
218c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param zone  the time-zone to use to convert the instant to date-time, not null
219c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that ticks in whole seconds using the specified zone, not null
220c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
221c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock tickSeconds(ZoneId zone) {
222c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new TickClock(system(zone), NANOS_PER_SECOND);
223c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
224c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
225c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
226c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns the current instant ticking in whole minutes
227c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * using best available system clock.
228c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
229c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock will always have the nano-of-second and second-of-minute fields set to zero.
230c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This ensures that the visible time ticks in whole minutes.
231c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The underlying clock is the best available system clock, equivalent to
232c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * using {@link #system(ZoneId)}.
233c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
234c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementations may use a caching strategy for performance reasons.
235c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * As such, it is possible that the start of the minute observed via this
236c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * clock will be later than that observed directly via the underlying clock.
237c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
238c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
239c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is equivalent to {@code tick(system(zone), Duration.ofMinutes(1))}.
240c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
241c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param zone  the time-zone to use to convert the instant to date-time, not null
242c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that ticks in whole minutes using the specified zone, not null
243c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
244c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock tickMinutes(ZoneId zone) {
245c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new TickClock(system(zone), NANOS_PER_MINUTE);
246c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
247c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
248c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
249c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns instants from the specified clock truncated
250c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * to the nearest occurrence of the specified duration.
251c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
252c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock will only tick as per the specified duration. Thus, if the duration
253c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * is half a second, the clock will return instants truncated to the half second.
254c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
255c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The tick duration must be positive. If it has a part smaller than a whole
256c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * millisecond, then the whole duration must divide into one second without
257c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * leaving a remainder. All normal tick durations will match these criteria,
258c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * including any multiple of hours, minutes, seconds and milliseconds, and
259c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * sensible nanosecond durations, such as 20ns, 250,000ns and 500,000ns.
260c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
261c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A duration of zero or one nanosecond would have no truncation effect.
262c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Passing one of these will return the underlying clock.
263c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
264c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementations may use a caching strategy for performance reasons.
265c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * As such, it is possible that the start of the requested duration observed
266c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * via this clock will be later than that observed directly via the underlying clock.
267c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
268c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}
269c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * providing that the base clock is.
270c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
271c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param baseClock  the base clock to base the ticking clock on, not null
272c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param tickDuration  the duration of each visible tick, not negative, not null
273c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that ticks in whole units of the duration, not null
274c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws IllegalArgumentException if the duration is negative, or has a
275c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  part smaller than a whole millisecond such that the whole duration is not
276c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  divisible into one second
277c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the duration is too large to be represented as nanos
278c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
279c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock tick(Clock baseClock, Duration tickDuration) {
280c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(baseClock, "baseClock");
281c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(tickDuration, "tickDuration");
282c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (tickDuration.isNegative()) {
283c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new IllegalArgumentException("Tick duration must not be negative");
284c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
285c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long tickNanos = tickDuration.toNanos();
286c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (tickNanos % 1000_000 == 0) {
287c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            // ok, no fraction of millisecond
288c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } else if (1000_000_000 % tickNanos == 0) {
289c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            // ok, divides into one second without remainder
290c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } else {
291c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new IllegalArgumentException("Invalid tick duration");
292c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
293c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (tickNanos <= 1) {
294c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock;
295c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
296c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new TickClock(baseClock, tickNanos);
297c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
298c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
299c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
300c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
301c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that always returns the same instant.
302c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
303c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock simply returns the specified instant.
304c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * As such, it is not a clock in the conventional sense.
305c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The main use case for this is in testing, where the fixed clock ensures
306c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * tests are not dependent on the current clock.
307c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
308c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}.
309c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
310c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param fixedInstant  the instant to use as the clock, not null
311c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param zone  the time-zone to use to convert the instant to date-time, not null
312c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock that always returns the same instant, not null
313c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
314c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock fixed(Instant fixedInstant, ZoneId zone) {
315c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(fixedInstant, "fixedInstant");
316c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(zone, "zone");
317c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new FixedClock(fixedInstant, zone);
318c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
319c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
320c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-------------------------------------------------------------------------
321c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
322c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a clock that returns instants from the specified clock with the
323c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * specified duration added
324c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
325c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This clock wraps another clock, returning instants that are later by the
326c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * specified duration. If the duration is negative, the instants will be
327c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * earlier than the current date and time.
328c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The main use case for this is to simulate running in the future or in the past.
329c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
330c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A duration of zero would have no offsetting effect.
331c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Passing zero will return the underlying clock.
332c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
333c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The returned implementation is immutable, thread-safe and {@code Serializable}
334c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * providing that the base clock is.
335c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
336c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param baseClock  the base clock to add the duration to, not null
337c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param offsetDuration  the duration to add, not null
338c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock based on the base clock with the duration added, not null
339c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
340c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Clock offset(Clock baseClock, Duration offsetDuration) {
341c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(baseClock, "baseClock");
342c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(offsetDuration, "offsetDuration");
343c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (offsetDuration.equals(Duration.ZERO)) {
344c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock;
345c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
346c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new OffsetClock(baseClock, offsetDuration);
347c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
348c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
349c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
350c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
351c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Constructor accessible by subclasses.
352c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
353c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    protected Clock() {
354c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
355c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
356c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
357c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
358c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the time-zone being used to create dates and times.
359c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
360c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A clock will typically obtain the current instant and then convert that
361c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * to a date or time using a time-zone. This method returns the time-zone used.
362c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
363c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the time-zone being used to interpret instants, not null
364c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
365c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public abstract ZoneId getZone();
366c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
367c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
368c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this clock with a different time-zone.
369c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
370c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A clock will typically obtain the current instant and then convert that
371c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * to a date or time using a time-zone. This method returns a clock with
372c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * similar properties but using a different time-zone.
373c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
374c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param zone  the time-zone to change to, not null
375c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a clock based on this clock with the specified time-zone, not null
376c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
377c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public abstract Clock withZone(ZoneId zone);
378c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
379c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-------------------------------------------------------------------------
380c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
381c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the current millisecond instant of the clock.
382c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
383c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns the millisecond-based instant, measured from 1970-01-01T00:00Z (UTC).
384c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This is equivalent to the definition of {@link System#currentTimeMillis()}.
385c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
386c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Most applications should avoid this method and use {@link Instant} to represent
387c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * an instant on the time-line rather than a raw millisecond value.
388c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method is provided to allow the use of the clock in high performance use cases
389c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * where the creation of an object would be unacceptable.
390c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
391c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The default implementation currently calls {@link #instant}.
392c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
393c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the current millisecond instant from this clock, measured from
394c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  the Java epoch of 1970-01-01T00:00Z (UTC), not null
395c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
396c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
397c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long millis() {
398c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return instant().toEpochMilli();
399c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
400c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
401c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
402c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
403c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the current instant of the clock.
404c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
405c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns an instant representing the current instant as defined by the clock.
406c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
407c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the current instant from this clock, not null
408c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
409c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
410c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public abstract Instant instant();
411c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
412c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
413c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
414c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Checks if this clock is equal to another clock.
415c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
416c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Clocks should override this method to compare equals based on
417c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * their state and to meet the contract of {@link Object#equals}.
418c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If not overridden, the behavior is defined by {@link Object#equals}
419c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
420c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param obj  the object to check, null returns false
421c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return true if this is equal to the other clock
422c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
423c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
424c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public boolean equals(Object obj) {
425c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return super.equals(obj);
426c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
427c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
428c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
429c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A hash code for this clock.
430c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
431c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Clocks should override this method based on
432c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * their state and to meet the contract of {@link Object#hashCode}.
433c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If not overridden, the behavior is defined by {@link Object#hashCode}
434c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
435c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a suitable hash code
436c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
437c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
438c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public  int hashCode() {
439c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return super.hashCode();
440c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
441c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
442c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
443c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
444c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementation of a clock that always returns the latest time from
445c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * {@link System#currentTimeMillis()}.
446c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
447c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    static final class SystemClock extends Clock implements Serializable {
448c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private static final long serialVersionUID = 6740630888130243051L;
449c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final ZoneId zone;
450c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
451c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        SystemClock(ZoneId zone) {
452c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.zone = zone;
453c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
454c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
455c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public ZoneId getZone() {
456c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return zone;
457c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
458c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
459c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Clock withZone(ZoneId zone) {
460c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (zone.equals(this.zone)) {  // intentional NPE
461c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return this;
462c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
463c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return new SystemClock(zone);
464c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
465c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
466c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public long millis() {
467c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return System.currentTimeMillis();
468c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
469c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
470c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Instant instant() {
471c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return Instant.ofEpochMilli(millis());
472c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
473c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
474c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public boolean equals(Object obj) {
475c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (obj instanceof SystemClock) {
476c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return zone.equals(((SystemClock) obj).zone);
477c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
478c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return false;
479c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
480c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
481c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public int hashCode() {
482c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return zone.hashCode() + 1;
483c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
484c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
485c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public String toString() {
486c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return "SystemClock[" + zone + "]";
487c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
488c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
489c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
490c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
491c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
492c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementation of a clock that always returns the same instant.
493c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This is typically used for testing.
494c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
495c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    static final class FixedClock extends Clock implements Serializable {
496c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer       private static final long serialVersionUID = 7430389292664866958L;
497c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final Instant instant;
498c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final ZoneId zone;
499c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
500c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        FixedClock(Instant fixedInstant, ZoneId zone) {
501c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.instant = fixedInstant;
502c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.zone = zone;
503c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
504c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
505c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public ZoneId getZone() {
506c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return zone;
507c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
508c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
509c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Clock withZone(ZoneId zone) {
510c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (zone.equals(this.zone)) {  // intentional NPE
511c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return this;
512c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
513c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return new FixedClock(instant, zone);
514c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
515c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
516c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public long millis() {
517c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return instant.toEpochMilli();
518c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
519c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
520c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Instant instant() {
521c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return instant;
522c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
523c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
524c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public boolean equals(Object obj) {
525c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (obj instanceof FixedClock) {
526c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                FixedClock other = (FixedClock) obj;
527c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return instant.equals(other.instant) && zone.equals(other.zone);
528c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
529c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return false;
530c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
531c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
532c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public int hashCode() {
533c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return instant.hashCode() ^ zone.hashCode();
534c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
535c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
536c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public String toString() {
537c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return "FixedClock[" + instant + "," + zone + "]";
538c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
539c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
540c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
541c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
542c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
543c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementation of a clock that adds an offset to an underlying clock.
544c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
545c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    static final class OffsetClock extends Clock implements Serializable {
546c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer       private static final long serialVersionUID = 2007484719125426256L;
547c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final Clock baseClock;
548c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final Duration offset;
549c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
550c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        OffsetClock(Clock baseClock, Duration offset) {
551c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.baseClock = baseClock;
552c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.offset = offset;
553c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
554c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
555c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public ZoneId getZone() {
556c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock.getZone();
557c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
558c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
559c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Clock withZone(ZoneId zone) {
560c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (zone.equals(baseClock.getZone())) {  // intentional NPE
561c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return this;
562c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
563c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return new OffsetClock(baseClock.withZone(zone), offset);
564c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
565c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
566c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public long millis() {
567c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return Math.addExact(baseClock.millis(), offset.toMillis());
568c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
569c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
570c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Instant instant() {
571c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock.instant().plus(offset);
572c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
573c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
574c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public boolean equals(Object obj) {
575c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (obj instanceof OffsetClock) {
576c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                OffsetClock other = (OffsetClock) obj;
577c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return baseClock.equals(other.baseClock) && offset.equals(other.offset);
578c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
579c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return false;
580c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
581c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
582c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public int hashCode() {
583c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock.hashCode() ^ offset.hashCode();
584c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
585c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
586c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public String toString() {
587c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return "OffsetClock[" + baseClock + "," + offset + "]";
588c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
589c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
590c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
591c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
592c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
593c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Implementation of a clock that adds an offset to an underlying clock.
594c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
595c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    static final class TickClock extends Clock implements Serializable {
596c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private static final long serialVersionUID = 6504659149906368850L;
597c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final Clock baseClock;
598c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        private final long tickNanos;
599c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
600c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        TickClock(Clock baseClock, long tickNanos) {
601c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.baseClock = baseClock;
602c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            this.tickNanos = tickNanos;
603c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
604c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
605c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public ZoneId getZone() {
606c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock.getZone();
607c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
608c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
609c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Clock withZone(ZoneId zone) {
610c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (zone.equals(baseClock.getZone())) {  // intentional NPE
611c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return this;
612c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
613c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return new TickClock(baseClock.withZone(zone), tickNanos);
614c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
615c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
616c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public long millis() {
617c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long millis = baseClock.millis();
618c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return millis - Math.floorMod(millis, tickNanos / 1000_000L);
619c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
620c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
621c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public Instant instant() {
622c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if ((tickNanos % 1000_000) == 0) {
623c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                long millis = baseClock.millis();
624c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return Instant.ofEpochMilli(millis - Math.floorMod(millis, tickNanos / 1000_000L));
625c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
626c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            Instant instant = baseClock.instant();
627c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long nanos = instant.getNano();
628c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long adjust = Math.floorMod(nanos, tickNanos);
629c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return instant.minusNanos(adjust);
630c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
631c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
632c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public boolean equals(Object obj) {
633c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (obj instanceof TickClock) {
634c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                TickClock other = (TickClock) obj;
635c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                return baseClock.equals(other.baseClock) && tickNanos == other.tickNanos;
636c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
637c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return false;
638c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
639c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
640c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public int hashCode() {
641c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return baseClock.hashCode() ^ ((int) (tickNanos ^ (tickNanos >>> 32)));
642c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
643c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        @Override
644c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        public String toString() {
645c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return "TickClock[" + baseClock + "," + Duration.ofNanos(tickNanos) + "]";
646c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
647c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
648c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
649c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer}
650