1c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer/*
2c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * Copyright (c) 2012, 2015, 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_SECOND;
65c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.LocalTime.SECONDS_PER_DAY;
66c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.LocalTime.SECONDS_PER_HOUR;
67c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.LocalTime.SECONDS_PER_MINUTE;
68c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.temporal.ChronoField.NANO_OF_SECOND;
69c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.temporal.ChronoUnit.DAYS;
70c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.temporal.ChronoUnit.NANOS;
71c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport static java.time.temporal.ChronoUnit.SECONDS;
72c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
73c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.DataInput;
74c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.DataOutput;
75c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.IOException;
76c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.InvalidObjectException;
77c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.ObjectInputStream;
78c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.io.Serializable;
79c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.math.BigDecimal;
80c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.math.BigInteger;
81c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.math.RoundingMode;
82c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.format.DateTimeParseException;
83c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.ChronoField;
84c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.ChronoUnit;
85c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.Temporal;
86c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.TemporalAmount;
87c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.TemporalUnit;
88c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.time.temporal.UnsupportedTemporalTypeException;
89c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.Arrays;
90c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.Collections;
91c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.List;
92c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.Objects;
93c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.regex.Matcher;
94c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerimport java.util.regex.Pattern;
95c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
96fa84287e36805c14f8177d449207b9701faacd10Przemyslaw Szczepaniak// Android-changed: removed ValueBased paragraph.
97c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer/**
98c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * A time-based amount of time, such as '34.5 seconds'.
99c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
100c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This class models a quantity or amount of time in terms of seconds and nanoseconds.
101c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * It can be accessed using other duration-based units, such as minutes and hours.
102c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * In addition, the {@link ChronoUnit#DAYS DAYS} unit can be used and is treated as
103c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * exactly equal to 24 hours, thus ignoring daylight savings effects.
104c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * See {@link Period} for the date-based equivalent to this class.
105c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
106c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * A physical duration could be of infinite length.
107c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * For practicality, the duration is stored with constraints similar to {@link Instant}.
108c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The duration uses nanosecond resolution with a maximum value of the seconds that can
109c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * be held in a {@code long}. This is greater than the current estimated age of the universe.
110c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
111c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The range of a duration requires the storage of a number larger than a {@code long}.
112c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * To achieve this, the class stores a {@code long} representing seconds and an {@code int}
113c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * representing nanosecond-of-second, which will always be between 0 and 999,999,999.
114c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The model is of a directed duration, meaning that the duration may be negative.
115c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * <p>
116c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * The duration is measured in "seconds", but these are not necessarily identical to
117c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * the scientific "SI second" definition based on atomic clocks.
118c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This difference only impacts durations measured near a leap-second and should not affect
119c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * most applications.
120c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * See {@link Instant} for a discussion as to the meaning of the second and time-scales.
121c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
122c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * @implSpec
123c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * This class is immutable and thread-safe.
124c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer *
125c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer * @since 1.8
126c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer */
127c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauerpublic final class Duration
128c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        implements TemporalAmount, Comparable<Duration>, Serializable {
129c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
130c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
131c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Constant for a duration of zero.
132c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
133c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static final Duration ZERO = new Duration(0, 0);
134c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
135c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Serialization version.
136c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
137c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static final long serialVersionUID = 3078945930695997490L;
138c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
139c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Constant for nanos per second.
140c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
141c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static final BigInteger BI_NANOS_PER_SECOND = BigInteger.valueOf(NANOS_PER_SECOND);
142c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
143c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The pattern for parsing.
144c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
145c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static final Pattern PATTERN =
146c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
147c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    "(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
148c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    Pattern.CASE_INSENSITIVE);
149c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
150c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
151c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of seconds in the duration.
152c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
153c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private final long seconds;
154c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
155c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of nanoseconds in the duration, expressed as a fraction of the
156c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * number of seconds. This is always positive, and never exceeds 999,999,999.
157c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
158c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private final int nanos;
159c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
160c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
161c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
162c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of standard 24 hour days.
163c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
164c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The seconds are calculated based on the standard definition of a day,
165c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * where each day is 86400 seconds which implies a 24 hour day.
166c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanosecond in second field is set to zero.
167c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
168c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param days  the number of days, positive or negative
169c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
170c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the input days exceeds the capacity of {@code Duration}
171c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
172c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofDays(long days) {
173c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(Math.multiplyExact(days, SECONDS_PER_DAY), 0);
174c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
175c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
176c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
177c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of standard hours.
178c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
179c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The seconds are calculated based on the standard definition of an hour,
180c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * where each hour is 3600 seconds.
181c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanosecond in second field is set to zero.
182c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
183c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param hours  the number of hours, positive or negative
184c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
185c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the input hours exceeds the capacity of {@code Duration}
186c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
187c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofHours(long hours) {
188c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(Math.multiplyExact(hours, SECONDS_PER_HOUR), 0);
189c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
190c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
191c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
192c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of standard minutes.
193c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
194c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The seconds are calculated based on the standard definition of a minute,
195c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * where each minute is 60 seconds.
196c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanosecond in second field is set to zero.
197c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
198c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param minutes  the number of minutes, positive or negative
199c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
200c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the input minutes exceeds the capacity of {@code Duration}
201c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
202c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofMinutes(long minutes) {
203c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(Math.multiplyExact(minutes, SECONDS_PER_MINUTE), 0);
204c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
205c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
206c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
207c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
208c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of seconds.
209c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
210c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanosecond in second field is set to zero.
211c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
212c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the number of seconds, positive or negative
213c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
214c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
215c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofSeconds(long seconds) {
216c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(seconds, 0);
217c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
218c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
219c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
220c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of seconds and an
221c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * adjustment in nanoseconds.
222c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
223c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method allows an arbitrary number of nanoseconds to be passed in.
224c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The factory will alter the values of the second and nanosecond in order
225c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * to ensure that the stored nanosecond is in the range 0 to 999,999,999.
226c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * For example, the following will result in the exactly the same duration:
227c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
228c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  Duration.ofSeconds(3, 1);
229c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  Duration.ofSeconds(4, -999_999_999);
230c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  Duration.ofSeconds(2, 1000_000_001);
231c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
232c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
233c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the number of seconds, positive or negative
234c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanoAdjustment  the nanosecond adjustment to the number of seconds, positive or negative
235c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
236c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the adjustment causes the seconds to exceed the capacity of {@code Duration}
237c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
238c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofSeconds(long seconds, long nanoAdjustment) {
239c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long secs = Math.addExact(seconds, Math.floorDiv(nanoAdjustment, NANOS_PER_SECOND));
240c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int nos = (int) Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
241c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(secs, nos);
242c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
243c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
244c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
245c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
246c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of milliseconds.
247c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
248c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The seconds and nanoseconds are extracted from the specified milliseconds.
249c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
250c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param millis  the number of milliseconds, positive or negative
251c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
252c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
253c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofMillis(long millis) {
254c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long secs = millis / 1000;
255c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int mos = (int) (millis % 1000);
256c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (mos < 0) {
257c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            mos += 1000;
258c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            secs--;
259c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
260c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(secs, mos * 1000_000);
261c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
262c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
263c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
264c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
265c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing a number of nanoseconds.
266c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
267c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The seconds and nanoseconds are extracted from the specified nanoseconds.
268c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
269c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanos  the number of nanoseconds, positive or negative
270c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
271c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
272c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration ofNanos(long nanos) {
273c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long secs = nanos / NANOS_PER_SECOND;
274c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int nos = (int) (nanos % NANOS_PER_SECOND);
275c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (nos < 0) {
276c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            nos += NANOS_PER_SECOND;
277c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            secs--;
278c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
279c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(secs, nos);
280c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
281c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
282c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
283c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
284c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing an amount in the specified unit.
285c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
286c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The parameters represent the two parts of a phrase like '6 Hours'. For example:
287c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
288c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  Duration.of(3, SECONDS);
289c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  Duration.of(465, HOURS);
290c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
291c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only a subset of units are accepted by this method.
292c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The unit must either have an {@linkplain TemporalUnit#isDurationEstimated() exact duration} or
293c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * be {@link ChronoUnit#DAYS} which is treated as 24 hours. Other units throw an exception.
294c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
295c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param amount  the amount of the duration, measured in terms of the unit, positive or negative
296c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param unit  the unit that the duration is measured in, must have an exact duration, not null
297c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
298c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the period unit has an estimated duration
299c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if a numeric overflow occurs
300c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
301c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration of(long amount, TemporalUnit unit) {
302c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return ZERO.plus(amount, unit);
303c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
304c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
305c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
306c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
307c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains an instance of {@code Duration} from a temporal amount.
308c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
309c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This obtains a duration based on the specified amount.
310c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A {@code TemporalAmount} represents an  amount of time, which may be
311c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * date-based or time-based, which this factory extracts to a duration.
312c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
313c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The conversion loops around the set of units from the amount and uses
314c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the {@linkplain TemporalUnit#getDuration() duration} of the unit to
315c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * calculate the total {@code Duration}.
316c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only a subset of units are accepted by this method. The unit must either
317c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * have an {@linkplain TemporalUnit#isDurationEstimated() exact duration}
318c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * or be {@link ChronoUnit#DAYS} which is treated as 24 hours.
319c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If any other units are found then an exception is thrown.
320c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
321c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param amount  the temporal amount to convert, not null
322c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the equivalent duration, not null
323c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if unable to convert to a {@code Duration}
324c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
325c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
326c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration from(TemporalAmount amount) {
327c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(amount, "amount");
328c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Duration duration = ZERO;
329c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        for (TemporalUnit unit : amount.getUnits()) {
330c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            duration = duration.plus(amount.get(unit), unit);
331c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
332c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return duration;
333c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
334c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
335c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
336c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
337c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMn.nS}.
338c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
339c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This will parse a textual representation of a duration, including the
340c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * string produced by {@code toString()}. The formats accepted are based
341c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * on the ISO-8601 duration format {@code PnDTnHnMn.nS} with days
342c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * considered to be exactly 24 hours.
343c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
344c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The string starts with an optional sign, denoted by the ASCII negative
345c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * or positive symbol. If negative, the whole period is negated.
346c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The ASCII letter "P" is next in upper or lower case.
347c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * There are then four sections, each consisting of a number and a suffix.
348c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The sections have suffixes in ASCII of "D", "H", "M" and "S" for
349c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * days, hours, minutes and seconds, accepted in upper or lower case.
350c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The suffixes must occur in order. The ASCII letter "T" must occur before
351c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the first occurrence, if any, of an hour, minute or second section.
352c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * At least one of the four sections must be present, and if "T" is present
353c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * there must be at least one section after the "T".
354c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number part of each section must consist of one or more ASCII digits.
355c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number may be prefixed by the ASCII negative or positive symbol.
356c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of days, hours and minutes must parse to an {@code long}.
357c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of seconds must parse to an {@code long} with optional fraction.
358c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The decimal point may be either a dot or a comma.
359c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The fractional part may have from zero to 9 digits.
360c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
361c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The leading plus/minus sign, and negative values for other units are
362c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * not part of the ISO-8601 standard.
363c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
364c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Examples:
365c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
366c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "PT20.345S" -- parses as "20.345 seconds"
367c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
368c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
369c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
370c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
371c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
372c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
373c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
374c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
375c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
376c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param text  the text to parse, not null
377c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the parsed duration, not null
378c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeParseException if the text cannot be parsed to a duration
379c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
380c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration parse(CharSequence text) {
381c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(text, "text");
382c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Matcher matcher = PATTERN.matcher(text);
383c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (matcher.matches()) {
384c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            // check for letter T but no time sections
385c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if ("T".equals(matcher.group(3)) == false) {
386c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                boolean negate = "-".equals(matcher.group(1));
387c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                String dayMatch = matcher.group(2);
388c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                String hourMatch = matcher.group(4);
389c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                String minuteMatch = matcher.group(5);
390c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                String secondMatch = matcher.group(6);
391c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                String fractionMatch = matcher.group(7);
392c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                if (dayMatch != null || hourMatch != null || minuteMatch != null || secondMatch != null) {
393c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    long daysAsSecs = parseNumber(text, dayMatch, SECONDS_PER_DAY, "days");
394c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    long hoursAsSecs = parseNumber(text, hourMatch, SECONDS_PER_HOUR, "hours");
395c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    long minsAsSecs = parseNumber(text, minuteMatch, SECONDS_PER_MINUTE, "minutes");
396c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    long seconds = parseNumber(text, secondMatch, 1, "seconds");
397c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    int nanos = parseFraction(text,  fractionMatch, seconds < 0 ? -1 : 1);
398c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    try {
399c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                        return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
400c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    } catch (ArithmeticException ex) {
401c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                        throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: overflow", text, 0).initCause(ex);
402c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    }
403c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                }
404c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
405c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
406c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        throw new DateTimeParseException("Text cannot be parsed to a Duration", text, 0);
407c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
408c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
409c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static long parseNumber(CharSequence text, String parsed, int multiplier, String errorText) {
410c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        // regex limits to [-+]?[0-9]+
411c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (parsed == null) {
412c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return 0;
413c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
414c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        try {
415c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long val = Long.parseLong(parsed);
416c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return Math.multiplyExact(val, multiplier);
417c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } catch (NumberFormatException | ArithmeticException ex) {
418c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: " + errorText, text, 0).initCause(ex);
419c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
420c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
421c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
422c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static int parseFraction(CharSequence text, String parsed, int negate) {
423c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        // regex limits to [0-9]{0,9}
424c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (parsed == null || parsed.length() == 0) {
425c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return 0;
426c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
427c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        try {
428c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            parsed = (parsed + "000000000").substring(0, 9);
429c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return Integer.parseInt(parsed) * negate;
430c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } catch (NumberFormatException | ArithmeticException ex) {
431c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: fraction", text, 0).initCause(ex);
432c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
433c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
434c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
435c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static Duration create(boolean negate, long daysAsSecs, long hoursAsSecs, long minsAsSecs, long secs, int nanos) {
436c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long seconds = Math.addExact(daysAsSecs, Math.addExact(hoursAsSecs, Math.addExact(minsAsSecs, secs)));
437c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (negate) {
438c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return ofSeconds(seconds, nanos).negated();
439c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
440c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return ofSeconds(seconds, nanos);
441c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
442c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
443c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
444c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
445c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains a {@code Duration} representing the duration between two temporal objects.
446c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
447c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This calculates the duration between two temporal objects. If the objects
448c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * are of different types, then the duration is calculated based on the type
449c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * of the first object. For example, if the first argument is a {@code LocalTime}
450c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * then the second argument is converted to a {@code LocalTime}.
451c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
452c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit.
453c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the
454c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported.
455c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
456c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The result of this method can be a negative period if the end is before the start.
457c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * To guarantee to obtain a positive duration call {@link #abs()} on the result.
458c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
459c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param startInclusive  the start instant, inclusive, not null
460c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param endExclusive  the end instant, exclusive, not null
461c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
462c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the seconds between the temporals cannot be obtained
463c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the calculation exceeds the capacity of {@code Duration}
464c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
465c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public static Duration between(Temporal startInclusive, Temporal endExclusive) {
466c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        try {
467c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return ofNanos(startInclusive.until(endExclusive, NANOS));
468c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } catch (DateTimeException | ArithmeticException ex) {
469c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long secs = startInclusive.until(endExclusive, SECONDS);
470c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            long nanos;
471c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            try {
472c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
473c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                if (secs > 0 && nanos < 0) {
474c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    secs++;
475c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                } else if (secs < 0 && nanos > 0) {
476c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                    secs--;
477c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                }
478c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            } catch (DateTimeException ex2) {
479c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                nanos = 0;
480c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
481c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return ofSeconds(secs, nanos);
482c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
483c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
484c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
485c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
486c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
487c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Obtains an instance of {@code Duration} using seconds and nanoseconds.
488c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
489c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the length of the duration in seconds, positive or negative
490c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanoAdjustment  the nanosecond adjustment within the second, from 0 to 999,999,999
491c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
492c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static Duration create(long seconds, int nanoAdjustment) {
493c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if ((seconds | nanoAdjustment) == 0) {
494c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return ZERO;
495c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
496c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new Duration(seconds, nanoAdjustment);
497c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
498c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
499c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
500c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Constructs an instance of {@code Duration} using seconds and nanoseconds.
501c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
502c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the length of the duration in seconds, positive or negative
503c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanos  the nanoseconds within the second, from 0 to 999,999,999
504c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
505c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private Duration(long seconds, int nanos) {
506c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        super();
507c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        this.seconds = seconds;
508c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        this.nanos = nanos;
509c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
510c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
511c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
512c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
513c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the value of the requested unit.
514c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
515c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns a value for each of the two supported units,
516c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * {@link ChronoUnit#SECONDS SECONDS} and {@link ChronoUnit#NANOS NANOS}.
517c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * All other units throw an exception.
518c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
519c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param unit the {@code TemporalUnit} for which to return the value
520c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the long value of the unit
521c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the unit is not supported
522c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws UnsupportedTemporalTypeException if the unit is not supported
523c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
524c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
525c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long get(TemporalUnit unit) {
526c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (unit == SECONDS) {
527c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return seconds;
528c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } else if (unit == NANOS) {
529c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return nanos;
530c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } else {
531c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
532c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
533c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
534c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
535c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
536c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the set of units supported by this duration.
537c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
538c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The supported units are {@link ChronoUnit#SECONDS SECONDS},
539c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * and {@link ChronoUnit#NANOS NANOS}.
540c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * They are returned in the order seconds, nanos.
541c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
542c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This set can be used in conjunction with {@link #get(TemporalUnit)}
543c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * to access the entire state of the duration.
544c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
545c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a list containing the seconds and nanos units, not null
546c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
547c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
548c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public List<TemporalUnit> getUnits() {
549c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return DurationUnits.UNITS;
550c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
551c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
552c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
553c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Private class to delay initialization of this list until needed.
554c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The circular dependency between Duration and ChronoUnit prevents
555c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the simple initialization in Duration.
556c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
557c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static class DurationUnits {
558c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        static final List<TemporalUnit> UNITS =
559c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                Collections.unmodifiableList(Arrays.<TemporalUnit>asList(SECONDS, NANOS));
560c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
561c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
562c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
563c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
564c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Checks if this duration is zero length.
565c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
566c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A {@code Duration} represents a directed distance between two points on
567c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the time-line and can therefore be positive, zero or negative.
568c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method checks whether the length is zero.
569c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
570c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return true if this duration has a total length equal to zero
571c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
572c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public boolean isZero() {
573c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (seconds | nanos) == 0;
574c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
575c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
576c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
577c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Checks if this duration is negative, excluding zero.
578c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
579c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A {@code Duration} represents a directed distance between two points on
580c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the time-line and can therefore be positive, zero or negative.
581c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method checks whether the length is less than zero.
582c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
583c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return true if this duration has a total length less than zero
584c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
585c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public boolean isNegative() {
586c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return seconds < 0;
587c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
588c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
589c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
590c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
591c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the number of seconds in this duration.
592c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
593c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The length of the duration is stored using two fields - seconds and nanoseconds.
594c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
595c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the length in seconds.
596c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The total duration is defined by calling this method and {@link #getNano()}.
597c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
598c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A {@code Duration} represents a directed distance between two points on the time-line.
599c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A negative duration is expressed by the negative sign of the seconds part.
600c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
601c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
602c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the whole seconds part of the length of the duration, positive or negative
603c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
604c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long getSeconds() {
605c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return seconds;
606c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
607c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
608c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
609c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the number of nanoseconds within the second in this duration.
610c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
611c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The length of the duration is stored using two fields - seconds and nanoseconds.
612c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
613c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the length in seconds.
614c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The total duration is defined by calling this method and {@link #getSeconds()}.
615c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
616c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A {@code Duration} represents a directed distance between two points on the time-line.
617c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A negative duration is expressed by the negative sign of the seconds part.
618c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
619c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
620c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
621c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
622c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public int getNano() {
623c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return nanos;
624c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
625c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
626c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
627c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
628c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified amount of seconds.
629c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
630c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns a duration with the specified seconds, retaining the
631c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * nano-of-second part of this duration.
632c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
633c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
634c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
635c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the seconds to represent, may be negative
636c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this period with the requested seconds, not null
637c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
638c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration withSeconds(long seconds) {
639c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(seconds, nanos);
640c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
641c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
642c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
643c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified nano-of-second.
644c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
645c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns a duration with the specified nano-of-second, retaining the
646c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * seconds part of this duration.
647c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
648c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
649c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
650c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
651c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this period with the requested nano-of-second, not null
652c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if the nano-of-second is invalid
653c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
654c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration withNanos(int nanoOfSecond) {
655c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        NANO_OF_SECOND.checkValidIntValue(nanoOfSecond);
656c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(seconds, nanoOfSecond);
657c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
658c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
659c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
660c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
661c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration added.
662c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
663c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
664c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
665c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param duration  the duration to add, positive or negative, not null
666c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified duration added, not null
667c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
668c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
669c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plus(Duration duration) {
670c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(duration.getSeconds(), duration.getNano());
671c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     }
672c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
673c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
674c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration added.
675c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
676c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The duration amount is measured in terms of the specified unit.
677c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only a subset of units are accepted by this method.
678c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The unit must either have an {@linkplain TemporalUnit#isDurationEstimated() exact duration} or
679c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * be {@link ChronoUnit#DAYS} which is treated as 24 hours. Other units throw an exception.
680c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
681c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
682c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
683c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param amountToAdd  the amount to add, measured in terms of the unit, positive or negative
684c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param unit  the unit that the amount is measured in, must have an exact duration, not null
685c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified duration added, not null
686c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws UnsupportedTemporalTypeException if the unit is not supported
687c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
688c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
689c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plus(long amountToAdd, TemporalUnit unit) {
690c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Objects.requireNonNull(unit, "unit");
691c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (unit == DAYS) {
692c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return plus(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY), 0);
693c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
694c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (unit.isDurationEstimated()) {
695c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new UnsupportedTemporalTypeException("Unit must not have an estimated duration");
696c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
697c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (amountToAdd == 0) {
698c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return this;
699c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
700c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (unit instanceof ChronoUnit) {
701c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            switch ((ChronoUnit) unit) {
702c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                case NANOS: return plusNanos(amountToAdd);
703c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                case MICROS: return plusSeconds((amountToAdd / (1000_000L * 1000)) * 1000).plusNanos((amountToAdd % (1000_000L * 1000)) * 1000);
704c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                case MILLIS: return plusMillis(amountToAdd);
705c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                case SECONDS: return plusSeconds(amountToAdd);
706c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
707c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return plusSeconds(Math.multiplyExact(unit.getDuration().seconds, amountToAdd));
708c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
709c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        Duration duration = unit.getDuration().multipliedBy(amountToAdd);
710c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plusSeconds(duration.getSeconds()).plusNanos(duration.getNano());
711c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
712c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
713c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
714c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
715c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in standard 24 hour days added.
716c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
717c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of days is multiplied by 86400 to obtain the number of seconds to add.
718c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This is based on the standard definition of a day as 24 hours.
719c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
720c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
721c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
722c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param daysToAdd  the days to add, positive or negative
723c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified days added, not null
724c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
725c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
726c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusDays(long daysToAdd) {
727c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(Math.multiplyExact(daysToAdd, SECONDS_PER_DAY), 0);
728c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
729c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
730c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
731c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in hours added.
732c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
733c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
734c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
735c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param hoursToAdd  the hours to add, positive or negative
736c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified hours added, not null
737c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
738c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
739c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusHours(long hoursToAdd) {
740c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(Math.multiplyExact(hoursToAdd, SECONDS_PER_HOUR), 0);
741c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
742c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
743c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
744c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in minutes added.
745c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
746c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
747c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
748c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param minutesToAdd  the minutes to add, positive or negative
749c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified minutes added, not null
750c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
751c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
752c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusMinutes(long minutesToAdd) {
753c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(Math.multiplyExact(minutesToAdd, SECONDS_PER_MINUTE), 0);
754c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
755c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
756c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
757c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in seconds added.
758c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
759c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
760c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
761c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param secondsToAdd  the seconds to add, positive or negative
762c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified seconds added, not null
763c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
764c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
765c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusSeconds(long secondsToAdd) {
766c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(secondsToAdd, 0);
767c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
768c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
769c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
770c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in milliseconds added.
771c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
772c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
773c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
774c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param millisToAdd  the milliseconds to add, positive or negative
775c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified milliseconds added, not null
776c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
777c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
778c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusMillis(long millisToAdd) {
779c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(millisToAdd / 1000, (millisToAdd % 1000) * 1000_000);
780c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
781c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
782c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
783c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in nanoseconds added.
784c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
785c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
786c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
787c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanosToAdd  the nanoseconds to add, positive or negative
788c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified nanoseconds added, not null
789c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
790c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
791c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration plusNanos(long nanosToAdd) {
792c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(0, nanosToAdd);
793c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
794c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
795c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
796c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration added.
797c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
798c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
799c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
800c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param secondsToAdd  the seconds to add, positive or negative
801c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanosToAdd  the nanos to add, positive or negative
802c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified seconds added, not null
803c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
804c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
805c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private Duration plus(long secondsToAdd, long nanosToAdd) {
806c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if ((secondsToAdd | nanosToAdd) == 0) {
807c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return this;
808c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
809c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long epochSec = Math.addExact(seconds, secondsToAdd);
810c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        epochSec = Math.addExact(epochSec, nanosToAdd / NANOS_PER_SECOND);
811c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        nanosToAdd = nanosToAdd % NANOS_PER_SECOND;
812c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long nanoAdjustment = nanos + nanosToAdd;  // safe int+NANOS_PER_SECOND
813c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return ofSeconds(epochSec, nanoAdjustment);
814c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
815c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
816c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
817c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
818c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration subtracted.
819c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
820c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
821c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
822c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param duration  the duration to subtract, positive or negative, not null
823c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified duration subtracted, not null
824c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
825c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
826c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minus(Duration duration) {
827c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long secsToSubtract = duration.getSeconds();
828c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int nanosToSubtract = duration.getNano();
829c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (secsToSubtract == Long.MIN_VALUE) {
830c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return plus(Long.MAX_VALUE, -nanosToSubtract).plus(1, 0);
831c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
832c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return plus(-secsToSubtract, -nanosToSubtract);
833c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     }
834c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
835c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
836c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration subtracted.
837c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
838c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The duration amount is measured in terms of the specified unit.
839c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only a subset of units are accepted by this method.
840c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The unit must either have an {@linkplain TemporalUnit#isDurationEstimated() exact duration} or
841c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * be {@link ChronoUnit#DAYS} which is treated as 24 hours. Other units throw an exception.
842c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
843c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
844c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
845c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param amountToSubtract  the amount to subtract, measured in terms of the unit, positive or negative
846c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param unit  the unit that the amount is measured in, must have an exact duration, not null
847c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified duration subtracted, not null
848c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
849c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
850c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minus(long amountToSubtract, TemporalUnit unit) {
851c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
852c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
853c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
854c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
855c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
856c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in standard 24 hour days subtracted.
857c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
858c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of days is multiplied by 86400 to obtain the number of seconds to subtract.
859c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This is based on the standard definition of a day as 24 hours.
860c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
861c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
862c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
863c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param daysToSubtract  the days to subtract, positive or negative
864c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified days subtracted, not null
865c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
866c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
867c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusDays(long daysToSubtract) {
868c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
869c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
870c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
871c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
872c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in hours subtracted.
873c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
874c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of hours is multiplied by 3600 to obtain the number of seconds to subtract.
875c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
876c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
877c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
878c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param hoursToSubtract  the hours to subtract, positive or negative
879c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified hours subtracted, not null
880c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
881c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
882c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusHours(long hoursToSubtract) {
883c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (hoursToSubtract == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hoursToSubtract));
884c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
885c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
886c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
887c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in minutes subtracted.
888c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
889c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The number of hours is multiplied by 60 to obtain the number of seconds to subtract.
890c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
891c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
892c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
893c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param minutesToSubtract  the minutes to subtract, positive or negative
894c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified minutes subtracted, not null
895c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
896c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
897c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusMinutes(long minutesToSubtract) {
898c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (minutesToSubtract == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutesToSubtract));
899c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
900c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
901c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
902c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in seconds subtracted.
903c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
904c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
905c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
906c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param secondsToSubtract  the seconds to subtract, positive or negative
907c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified seconds subtracted, not null
908c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
909c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
910c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusSeconds(long secondsToSubtract) {
911c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (secondsToSubtract == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-secondsToSubtract));
912c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
913c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
914c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
915c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in milliseconds subtracted.
916c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
917c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
918c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
919c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param millisToSubtract  the milliseconds to subtract, positive or negative
920c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified milliseconds subtracted, not null
921c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
922c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
923c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusMillis(long millisToSubtract) {
924c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (millisToSubtract == Long.MIN_VALUE ? plusMillis(Long.MAX_VALUE).plusMillis(1) : plusMillis(-millisToSubtract));
925c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
926c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
927c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
928c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the specified duration in nanoseconds subtracted.
929c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
930c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
931c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
932c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param nanosToSubtract  the nanoseconds to subtract, positive or negative
933c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the specified nanoseconds subtracted, not null
934c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
935c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
936c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration minusNanos(long nanosToSubtract) {
937c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return (nanosToSubtract == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanosToSubtract));
938c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
939c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
940c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
941c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
942c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration multiplied by the scalar.
943c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
944c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
945c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
946c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param multiplicand  the value to multiply the duration by, positive or negative
947c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration multiplied by the specified scalar, not null
948c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
949c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
950c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration multipliedBy(long multiplicand) {
951c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (multiplicand == 0) {
952c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return ZERO;
953c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
954c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (multiplicand == 1) {
955c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return this;
956c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
957c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand)));
958c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     }
959c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
960c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
961c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration divided by the specified value.
962c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
963c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
964c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
965c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param divisor  the value to divide the duration by, positive or negative, not zero
966c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration divided by the specified divisor, not null
967c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if the divisor is zero or if numeric overflow occurs
968c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
969c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration dividedBy(long divisor) {
970c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (divisor == 0) {
971c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new ArithmeticException("Cannot divide by zero");
972c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
973c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (divisor == 1) {
974c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return this;
975c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
976c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return create(toSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
977c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     }
978c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
979c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
980c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Converts this duration to the total length in seconds and
981c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * fractional nanoseconds expressed as a {@code BigDecimal}.
982c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
983c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the total length of the duration in seconds, with a scale of 9, not null
984c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
985c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private BigDecimal toSeconds() {
986c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
987c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
988c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
989c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
990c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Creates an instance of {@code Duration} from a number of seconds.
991c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
992c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param seconds  the number of seconds, up to scale 9, positive or negative
993c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration}, not null
994c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
995c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
996c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private static Duration create(BigDecimal seconds) {
997c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        BigInteger nanos = seconds.movePointRight(9).toBigIntegerExact();
998c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        BigInteger[] divRem = nanos.divideAndRemainder(BI_NANOS_PER_SECOND);
999c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (divRem[0].bitLength() > 63) {
1000c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            throw new ArithmeticException("Exceeds capacity of Duration: " + nanos);
1001c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1002c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return ofSeconds(divRem[0].longValue(), divRem[1].intValue());
1003c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1004c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1005c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1006c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1007c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with the length negated.
1008c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1009c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method swaps the sign of the total length of this duration.
1010c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * For example, {@code PT1.3S} will be returned as {@code PT-1.3S}.
1011c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1012c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1013c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1014c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with the amount negated, not null
1015c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1016c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1017c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration negated() {
1018c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return multipliedBy(-1);
1019c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1020c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1021c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1022c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Returns a copy of this duration with a positive length.
1023c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1024c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This method returns a positive duration by effectively removing the sign from any negative total length.
1025c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * For example, {@code PT-1.3S} will be returned as {@code PT1.3S}.
1026c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1027c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1028c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1029c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a {@code Duration} based on this duration with an absolute length, not null
1030c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1031c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1032c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Duration abs() {
1033c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return isNegative() ? negated() : this;
1034c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1035c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1036c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-------------------------------------------------------------------------
1037c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1038c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Adds this duration to the specified temporal object.
1039c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1040c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns a temporal object of the same observable type as the input
1041c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * with this duration added.
1042c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1043c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * In most cases, it is clearer to reverse the calling pattern by using
1044c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * {@link Temporal#plus(TemporalAmount)}.
1045c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
1046c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   // these two lines are equivalent, but the second approach is recommended
1047c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   dateTime = thisDuration.addTo(dateTime);
1048c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   dateTime = dateTime.plus(thisDuration);
1049c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
1050c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1051c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The calculation will add the seconds, then nanos.
1052c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only non-zero amounts will be added.
1053c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1054c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1055c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1056c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param temporal  the temporal object to adjust, not null
1057c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return an object of the same type with the adjustment made, not null
1058c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if unable to add
1059c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1060c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1061c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1062c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Temporal addTo(Temporal temporal) {
1063c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (seconds != 0) {
1064c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            temporal = temporal.plus(seconds, SECONDS);
1065c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1066c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (nanos != 0) {
1067c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            temporal = temporal.plus(nanos, NANOS);
1068c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1069c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return temporal;
1070c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1071c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1072c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1073c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Subtracts this duration from the specified temporal object.
1074c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1075c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns a temporal object of the same observable type as the input
1076c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * with this duration subtracted.
1077c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1078c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * In most cases, it is clearer to reverse the calling pattern by using
1079c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * {@link Temporal#minus(TemporalAmount)}.
1080c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
1081c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   // these two lines are equivalent, but the second approach is recommended
1082c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   dateTime = thisDuration.subtractFrom(dateTime);
1083c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *   dateTime = dateTime.minus(thisDuration);
1084c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
1085c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1086c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The calculation will subtract the seconds, then nanos.
1087c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Only non-zero amounts will be added.
1088c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1089c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1090c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1091c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param temporal  the temporal object to adjust, not null
1092c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return an object of the same type with the adjustment made, not null
1093c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws DateTimeException if unable to subtract
1094c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1095c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1096c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1097c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public Temporal subtractFrom(Temporal temporal) {
1098c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (seconds != 0) {
1099c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            temporal = temporal.minus(seconds, SECONDS);
1100c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1101c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (nanos != 0) {
1102c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            temporal = temporal.minus(nanos, NANOS);
1103c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1104c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return temporal;
1105c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1106c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1107c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1108c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1109c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the number of days in this duration.
1110c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1111c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns the total number of days in the duration by dividing the
1112c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * number of seconds by 86400.
1113c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This is based on the standard definition of a day as 24 hours.
1114c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1115c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1116c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1117c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the number of days in the duration, may be negative
1118c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1119c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long toDays() {
1120c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return seconds / SECONDS_PER_DAY;
1121c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1122c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1123c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1124c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the number of hours in this duration.
1125c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1126c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns the total number of hours in the duration by dividing the
1127c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * number of seconds by 3600.
1128c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1129c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1130c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1131c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the number of hours in the duration, may be negative
1132c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1133c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long toHours() {
1134c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return seconds / SECONDS_PER_HOUR;
1135c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1136c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1137c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1138c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Gets the number of minutes in this duration.
1139c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1140c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This returns the total number of minutes in the duration by dividing the
1141c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * number of seconds by 60.
1142c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1143c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * This instance is immutable and unaffected by this method call.
1144c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1145c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the number of minutes in the duration, may be negative
1146c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1147c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long toMinutes() {
1148c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return seconds / SECONDS_PER_MINUTE;
1149c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1150c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1151c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1152c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Converts this duration to the total length in milliseconds.
1153c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1154c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If this duration is too large to fit in a {@code long} milliseconds, then an
1155c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * exception is thrown.
1156c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1157c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If this duration has greater than millisecond precision, then the conversion
1158c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * will drop any excess precision information as though the amount in nanoseconds
1159c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * was subject to integer division by one million.
1160c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1161c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the total length of the duration in milliseconds
1162c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1163c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1164c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long toMillis() {
1165c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long millis = Math.multiplyExact(seconds, 1000);
1166c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        millis = Math.addExact(millis, nanos / 1000_000);
1167c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return millis;
1168c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1169c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1170c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1171c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Converts this duration to the total length in nanoseconds expressed as a {@code long}.
1172c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1173c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If this duration is too large to fit in a {@code long} nanoseconds, then an
1174c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * exception is thrown.
1175c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1176c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the total length of the duration in nanoseconds
1177c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws ArithmeticException if numeric overflow occurs
1178c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1179c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public long toNanos() {
1180c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long totalNanos = Math.multiplyExact(seconds, NANOS_PER_SECOND);
1181c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        totalNanos = Math.addExact(totalNanos, nanos);
1182c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return totalNanos;
1183c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1184c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1185c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1186c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1187c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Compares this duration to the specified {@code Duration}.
1188c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1189c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The comparison is based on the total length of the durations.
1190c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * It is "consistent with equals", as defined by {@link Comparable}.
1191c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1192c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param otherDuration  the other duration to compare to, not null
1193c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the comparator value, negative if less, positive if greater
1194c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1195c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1196c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public int compareTo(Duration otherDuration) {
1197c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int cmp = Long.compare(seconds, otherDuration.seconds);
1198c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (cmp != 0) {
1199c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return cmp;
1200c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1201c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return nanos - otherDuration.nanos;
1202c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1203c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1204c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1205c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1206c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Checks if this duration is equal to the specified {@code Duration}.
1207c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1208c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The comparison is based on the total length of the durations.
1209c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1210c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param otherDuration  the other duration, null returns false
1211c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return true if the other duration is equal to this one
1212c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1213c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1214c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public boolean equals(Object otherDuration) {
1215c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (this == otherDuration) {
1216c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return true;
1217c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1218c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (otherDuration instanceof Duration) {
1219c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            Duration other = (Duration) otherDuration;
1220c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return this.seconds == other.seconds &&
1221c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                   this.nanos == other.nanos;
1222c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1223c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return false;
1224c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1225c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1226c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1227c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A hash code for this duration.
1228c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1229c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return a suitable hash code
1230c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1231c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1232c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public int hashCode() {
1233c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return ((int) (seconds ^ (seconds >>> 32))) + (51 * nanos);
1234c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1235c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1236c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1237c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1238c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * A string representation of this duration using ISO-8601 seconds
1239c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * based representation, such as {@code PT8H6M12.345S}.
1240c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1241c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The format of the returned string will be {@code PTnHnMnS}, where n is
1242c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * the relevant hours, minutes or seconds part of the duration.
1243c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Any fractional seconds are placed after a decimal point i the seconds section.
1244c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * If a section has a zero value, it is omitted.
1245c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * The hours, minutes and seconds will all have the same sign.
1246c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <p>
1247c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Examples:
1248c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
1249c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "20.345 seconds"                 -- "PT20.345S
1250c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "15 minutes" (15 * 60 seconds)   -- "PT15M"
1251c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "10 hours" (10 * 3600 seconds)   -- "PT10H"
1252c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *    "2 days" (2 * 86400 seconds)     -- "PT48H"
1253c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
1254c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Note that multiples of 24 hours are not output as days to avoid confusion
1255c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * with {@code Period}.
1256c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1257c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return an ISO-8601 representation of this duration, not null
1258c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1259c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    @Override
1260c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    public String toString() {
1261c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (this == ZERO) {
1262c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return "PT0S";
1263c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1264c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long hours = seconds / SECONDS_PER_HOUR;
1265c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int minutes = (int) ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
1266c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int secs = (int) (seconds % SECONDS_PER_MINUTE);
1267c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        StringBuilder buf = new StringBuilder(24);
1268c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        buf.append("PT");
1269c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (hours != 0) {
1270c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            buf.append(hours).append('H');
1271c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1272c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (minutes != 0) {
1273c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            buf.append(minutes).append('M');
1274c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1275c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (secs == 0 && nanos == 0 && buf.length() > 2) {
1276c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            return buf.toString();
1277c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1278c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (secs < 0 && nanos > 0) {
1279c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (secs == -1) {
1280c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                buf.append("-0");
1281c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            } else {
1282c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                buf.append(secs + 1);
1283c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
1284c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        } else {
1285c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            buf.append(secs);
1286c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1287c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        if (nanos > 0) {
1288c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            int pos = buf.length();
1289c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            if (secs < 0) {
1290c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                buf.append(2 * NANOS_PER_SECOND - nanos);
1291c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            } else {
1292c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                buf.append(nanos + NANOS_PER_SECOND);
1293c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
1294c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            while (buf.charAt(buf.length() - 1) == '0') {
1295c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer                buf.setLength(buf.length() - 1);
1296c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            }
1297c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer            buf.setCharAt(pos, '.');
1298c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        }
1299c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        buf.append('S');
1300c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return buf.toString();
1301c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1302c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1303c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    //-----------------------------------------------------------------------
1304c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1305c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Writes the object using a
1306c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
1307c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @serialData
1308c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * <pre>
1309c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  out.writeByte(1);  // identifies a Duration
1310c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  out.writeLong(seconds);
1311c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *  out.writeInt(nanos);
1312c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * </pre>
1313c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1314c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @return the instance of {@code Ser}, not null
1315c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1316c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private Object writeReplace() {
1317c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return new Ser(Ser.DURATION_TYPE, this);
1318c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1319c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1320c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    /**
1321c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * Defend against malicious streams.
1322c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     *
1323c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @param s the stream to read
1324c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     * @throws InvalidObjectException always
1325c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer     */
1326c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    private void readObject(ObjectInputStream s) throws InvalidObjectException {
1327c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        throw new InvalidObjectException("Deserialization via serialization delegate");
1328c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1329c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1330c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    void writeExternal(DataOutput out) throws IOException {
1331c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        out.writeLong(seconds);
1332c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        out.writeInt(nanos);
1333c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1334c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1335c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    static Duration readExternal(DataInput in) throws IOException {
1336c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        long seconds = in.readLong();
1337c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        int nanos = in.readInt();
1338c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer        return Duration.ofSeconds(seconds, nanos);
1339c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer    }
1340c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer
1341c9dd3385ea6f927052783f42fb1282fb093e636eJoachim Sauer}
1342