1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea and Martin Buchholz with assistance from
30  * members of JCP JSR-166 Expert Group and released to the public
31  * domain, as explained at
32  * http://creativecommons.org/publicdomain/zero/1.0/
33  */
34 
35 import static java.util.concurrent.TimeUnit.DAYS;
36 import static java.util.concurrent.TimeUnit.HOURS;
37 import static java.util.concurrent.TimeUnit.MICROSECONDS;
38 import static java.util.concurrent.TimeUnit.MILLISECONDS;
39 import static java.util.concurrent.TimeUnit.MINUTES;
40 import static java.util.concurrent.TimeUnit.NANOSECONDS;
41 import static java.util.concurrent.TimeUnit.SECONDS;
42 
43 import java.time.Duration;
44 import java.time.temporal.ChronoUnit;
45 import java.util.Arrays;
46 import java.util.concurrent.ThreadLocalRandom;
47 import java.util.concurrent.TimeUnit;
48 import java.util.stream.LongStream;
49 
50 import junit.framework.Test;
51 import junit.framework.TestSuite;
52 
53 public class TimeUnit8Test extends JSR166TestCase {
main(String[] args)54     public static void main(String[] args) {
55         main(suite(), args);
56     }
57 
suite()58     public static Test suite() {
59         return new TestSuite(TimeUnit8Test.class);
60     }
61 
62     /**
63      * tests for toChronoUnit.
64      */
testToChronoUnit()65     public void testToChronoUnit() throws Exception {
66         assertSame(ChronoUnit.NANOS,   NANOSECONDS.toChronoUnit());
67         assertSame(ChronoUnit.MICROS,  MICROSECONDS.toChronoUnit());
68         assertSame(ChronoUnit.MILLIS,  MILLISECONDS.toChronoUnit());
69         assertSame(ChronoUnit.SECONDS, SECONDS.toChronoUnit());
70         assertSame(ChronoUnit.MINUTES, MINUTES.toChronoUnit());
71         assertSame(ChronoUnit.HOURS,   HOURS.toChronoUnit());
72         assertSame(ChronoUnit.DAYS,    DAYS.toChronoUnit());
73 
74         // Every TimeUnit has a defined ChronoUnit equivalent
75         for (TimeUnit x : TimeUnit.values())
76             assertSame(x, TimeUnit.of(x.toChronoUnit()));
77     }
78 
79     /**
80      * tests for TimeUnit.of(ChronoUnit).
81      */
testTimeUnitOf()82     public void testTimeUnitOf() throws Exception {
83         assertSame(NANOSECONDS,  TimeUnit.of(ChronoUnit.NANOS));
84         assertSame(MICROSECONDS, TimeUnit.of(ChronoUnit.MICROS));
85         assertSame(MILLISECONDS, TimeUnit.of(ChronoUnit.MILLIS));
86         assertSame(SECONDS,      TimeUnit.of(ChronoUnit.SECONDS));
87         assertSame(MINUTES,      TimeUnit.of(ChronoUnit.MINUTES));
88         assertSame(HOURS,        TimeUnit.of(ChronoUnit.HOURS));
89         assertSame(DAYS,         TimeUnit.of(ChronoUnit.DAYS));
90 
91         assertThrows(NullPointerException.class,
92                      () -> TimeUnit.of((ChronoUnit)null));
93 
94         // ChronoUnits either round trip to their TimeUnit
95         // equivalents, or throw IllegalArgumentException.
96         for (ChronoUnit cu : ChronoUnit.values()) {
97             final TimeUnit tu;
98             try {
99                 tu = TimeUnit.of(cu);
100             } catch (IllegalArgumentException acceptable) {
101                 continue;
102             }
103             assertSame(cu, tu.toChronoUnit());
104         }
105     }
106 
107     /**
108      * convert(Duration) roundtrips with Duration.ofXXXX and Duration.of(long, ChronoUnit)
109      */
testConvertDuration_roundtripDurationOf()110     public void testConvertDuration_roundtripDurationOf() {
111         long n = ThreadLocalRandom.current().nextLong();
112 
113         assertEquals(n, NANOSECONDS.convert(Duration.ofNanos(n)));
114         assertEquals(n, NANOSECONDS.convert(Duration.of(n, ChronoUnit.NANOS)));
115         assertEquals(n, MILLISECONDS.convert(Duration.ofMillis(n)));
116         assertEquals(n, MILLISECONDS.convert(Duration.of(n, ChronoUnit.MILLIS)));
117         assertEquals(n, SECONDS.convert(Duration.ofSeconds(n)));
118         assertEquals(n, SECONDS.convert(Duration.of(n, ChronoUnit.SECONDS)));
119         n /= 60;
120         assertEquals(n, MINUTES.convert(Duration.ofMinutes(n)));
121         assertEquals(n, MINUTES.convert(Duration.of(n, ChronoUnit.MINUTES)));
122         n /= 60;
123         assertEquals(n, HOURS.convert(Duration.ofHours(n)));
124         assertEquals(n, HOURS.convert(Duration.of(n, ChronoUnit.HOURS)));
125         n /= 24;
126         assertEquals(n, DAYS.convert(Duration.ofDays(n)));
127         assertEquals(n, DAYS.convert(Duration.of(n, ChronoUnit.DAYS)));
128     }
129 
130     /**
131      * convert(Duration.ofNanos(n)) agrees with convert(n, NANOSECONDS)
132      */
testConvertDuration_roundtripDurationOfNanos()133     public void testConvertDuration_roundtripDurationOfNanos() {
134         // Test values near unit transitions and near overflow.
135         LongStream.concat(
136                 Arrays.stream(TimeUnit.values()).mapToLong(u -> u.toNanos(1)),
137                 LongStream.of(Long.MAX_VALUE, Long.MIN_VALUE))
138             .flatMap(n -> LongStream.of(n, n + 1, n - 1))
139             .flatMap(n -> LongStream.of(n, n + 1_000_000_000, n - 1_000_000_000))
140             .flatMap(n -> LongStream.of(n, -n))
141             // .peek(System.err::println)
142             .forEach(n -> Arrays.stream(TimeUnit.values()).forEach(
143                 u -> assertEquals(u.convert(n, NANOSECONDS),
144                                   u.convert(Duration.ofNanos(n)))));
145     }
146 
147     /**
148      * convert(Duration) doesn't misbehave near Long.MAX_VALUE and Long.MIN_VALUE.
149      */
testConvertDuration_nearOverflow()150     public void testConvertDuration_nearOverflow() {
151         ChronoUnit NANOS = ChronoUnit.NANOS;
152         Duration maxDuration = Duration.ofSeconds(Long.MAX_VALUE, 999_999_999);
153         Duration minDuration = Duration.ofSeconds(Long.MIN_VALUE, 0);
154 
155         for (TimeUnit u : TimeUnit.values()) {
156             ChronoUnit cu = u.toChronoUnit();
157             long r;
158             if (u.toNanos(1) > SECONDS.toNanos(1)) {
159                 r = u.toNanos(1) / SECONDS.toNanos(1);
160 
161                 assertThrows(ArithmeticException.class,
162                              () -> Duration.of(Long.MAX_VALUE, cu),
163                              () -> Duration.of(Long.MIN_VALUE, cu));
164             } else {
165                 r = 1;
166 
167                 Duration max = Duration.of(Long.MAX_VALUE, cu);
168                 Duration min = Duration.of(Long.MIN_VALUE, cu);
169                 assertEquals(Long.MAX_VALUE, u.convert(max));
170                 assertEquals(Long.MAX_VALUE - 1, u.convert(max.minus(1, NANOS)));
171                 assertEquals(Long.MAX_VALUE - 1, u.convert(max.minus(1, cu)));
172                 assertEquals(Long.MIN_VALUE, u.convert(min));
173                 assertEquals(Long.MIN_VALUE + 1, u.convert(min.plus(1, NANOS)));
174                 assertEquals(Long.MIN_VALUE + 1, u.convert(min.plus(1, cu)));
175                 assertEquals(Long.MAX_VALUE, u.convert(max.plus(1, NANOS)));
176                 if (u != SECONDS) {
177                     assertEquals(Long.MAX_VALUE, u.convert(max.plus(1, cu)));
178                     assertEquals(Long.MIN_VALUE, u.convert(min.minus(1, NANOS)));
179                     assertEquals(Long.MIN_VALUE, u.convert(min.minus(1, cu)));
180                 }
181             }
182 
183             assertEquals(Long.MAX_VALUE / r, u.convert(maxDuration));
184             assertEquals(Long.MIN_VALUE / r, u.convert(minDuration));
185         }
186     }
187 
188 }
189