Skip to content

Commit 82f90e4

Browse files
committed
增加常用时间长度转换工具类,用于对时间间隔进行转换。
1 parent 89a539d commit 82f90e4

File tree

7 files changed

+381
-1
lines changed

7 files changed

+381
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
package org.javacore.time;
2+
3+
import com.google.common.base.Preconditions;
4+
import com.google.common.collect.Maps;
5+
6+
import java.io.Serializable;
7+
import java.util.Map;
8+
import java.util.concurrent.TimeUnit;
9+
import java.util.regex.Matcher;
10+
import java.util.regex.Pattern;
11+
12+
/**
13+
* Title: Duration
14+
* Create Date: 2016-08-26 15:43
15+
* Description: Duration unit, consisting of length and time unit.
16+
* Simple time convert.
17+
*
18+
* @author Yufan
19+
*/
20+
public class Duration implements Serializable {
21+
private static final long serialVersionUID = 3898309763927286550L;
22+
23+
/**
24+
* A duration of Long.MAX_VALUE Days
25+
*/
26+
public static final Duration INFINITE = new Duration();
27+
28+
/**
29+
* Common time pattern
30+
*/
31+
private static final Pattern PATTERN = Pattern.compile(
32+
"(∞|inf|infinite)|" + "(([\\d]+)[\\s]*(" + "ns|nanosecond(s)?|" + "us|microsecond(s)?|" + "ms|millisecond(s)?|" + "s|second(s)?|"
33+
+ "m|min|mins|minute(s)?|" + "h|hour(s)?|" + "d|day(s)?" + "))");
34+
private static final Map<String, TimeUnit> SUFFIXES;
35+
36+
public final long length;
37+
public final TimeUnit timeUnit;
38+
public final boolean finite;
39+
40+
static {
41+
SUFFIXES = Maps.newHashMapWithExpectedSize(32);
42+
43+
SUFFIXES.put("ns", TimeUnit.NANOSECONDS);
44+
SUFFIXES.put("nanosecond", TimeUnit.NANOSECONDS);
45+
SUFFIXES.put("nanoseconds", TimeUnit.NANOSECONDS);
46+
47+
SUFFIXES.put("us", TimeUnit.MICROSECONDS);
48+
SUFFIXES.put("microsecond", TimeUnit.MICROSECONDS);
49+
SUFFIXES.put("microseconds", TimeUnit.MICROSECONDS);
50+
51+
SUFFIXES.put("ms", TimeUnit.MILLISECONDS);
52+
SUFFIXES.put("millisecond", TimeUnit.MILLISECONDS);
53+
SUFFIXES.put("milliseconds", TimeUnit.MILLISECONDS);
54+
55+
SUFFIXES.put("s", TimeUnit.SECONDS);
56+
SUFFIXES.put("second", TimeUnit.SECONDS);
57+
SUFFIXES.put("seconds", TimeUnit.SECONDS);
58+
59+
SUFFIXES.put("m", TimeUnit.MINUTES);
60+
SUFFIXES.put("min", TimeUnit.MINUTES);
61+
SUFFIXES.put("mins", TimeUnit.MINUTES);
62+
SUFFIXES.put("minute", TimeUnit.MINUTES);
63+
SUFFIXES.put("minutes", TimeUnit.MINUTES);
64+
65+
SUFFIXES.put("h", TimeUnit.HOURS);
66+
SUFFIXES.put("hour", TimeUnit.HOURS);
67+
SUFFIXES.put("hours", TimeUnit.HOURS);
68+
69+
SUFFIXES.put("d", TimeUnit.DAYS);
70+
SUFFIXES.put("day", TimeUnit.DAYS);
71+
SUFFIXES.put("days", TimeUnit.DAYS);
72+
}
73+
74+
/**
75+
* Infinite constructor.
76+
*/
77+
private Duration() {
78+
finite = false;
79+
this.length = Long.MAX_VALUE;
80+
this.timeUnit = TimeUnit.DAYS;
81+
}
82+
83+
private Duration(long length, TimeUnit timeUnit) {
84+
this.length = length;
85+
this.timeUnit = Preconditions.checkNotNull(timeUnit, "timeUnit");
86+
finite = !(length == Long.MAX_VALUE && TimeUnit.DAYS.equals(timeUnit));
87+
}
88+
89+
/**
90+
* Returns the Duration converted to days.
91+
*/
92+
public long toDays() {
93+
return TimeUnit.DAYS.convert(length, timeUnit);
94+
}
95+
96+
/**
97+
* Returns the Duration converted to hours.
98+
*/
99+
public long toHours() {
100+
return TimeUnit.HOURS.convert(length, timeUnit);
101+
}
102+
103+
/**
104+
* Returns the Duration converted to microseconds.
105+
*/
106+
public long toMicros() {
107+
return TimeUnit.MICROSECONDS.convert(length, timeUnit);
108+
}
109+
110+
/**
111+
* Returns the Duration converted to microseconds.
112+
*/
113+
public long toMicroseconds() {
114+
return TimeUnit.MICROSECONDS.convert(length, timeUnit);
115+
}
116+
117+
/**
118+
* Returns the Duration converted to milliseconds.
119+
*/
120+
public long toMillis() {
121+
return TimeUnit.MILLISECONDS.convert(length, timeUnit);
122+
}
123+
124+
/**
125+
* Returns the Duration converted to milliseconds.
126+
*/
127+
public long toMilliseconds() {
128+
return TimeUnit.MILLISECONDS.convert(length, timeUnit);
129+
}
130+
131+
/**
132+
* Returns the Duration converted to minutes.
133+
*/
134+
public long toMins() {
135+
return TimeUnit.MINUTES.convert(length, timeUnit);
136+
}
137+
138+
/**
139+
* Returns the Duration converted to minutes.
140+
*/
141+
public long toMinutes() {
142+
return TimeUnit.MINUTES.convert(length, timeUnit);
143+
}
144+
145+
/**
146+
* Returns the Duration converted to nanoseconds.
147+
*/
148+
public long toNanos() {
149+
return TimeUnit.NANOSECONDS.convert(length, timeUnit);
150+
}
151+
152+
/**
153+
* Returns the Duration converted to nanoseconds.
154+
*/
155+
public long toNanoseconds() {
156+
return TimeUnit.NANOSECONDS.convert(length, timeUnit);
157+
}
158+
159+
/**
160+
* Returns the Duration converted to seconds.
161+
*/
162+
public long toSeconds() {
163+
return TimeUnit.SECONDS.convert(length, timeUnit);
164+
}
165+
166+
/**
167+
* Returns the Duration converted to seconds.
168+
*/
169+
public long toSecs() {
170+
return TimeUnit.SECONDS.convert(length, timeUnit);
171+
}
172+
173+
/**
174+
* Returns a Duration of {@code count} days.
175+
*/
176+
public static Duration days(long count) {
177+
return new Duration(count, TimeUnit.DAYS);
178+
}
179+
180+
/**
181+
* Returns a Duration of {@code count} hours.
182+
*/
183+
public static Duration hours(long count) {
184+
return new Duration(count, TimeUnit.HOURS);
185+
}
186+
187+
/**
188+
* Returns an infinite duration of Long.MAX_VALUE days.
189+
*/
190+
public static Duration inf() {
191+
return INFINITE;
192+
}
193+
194+
/**
195+
* Returns an infinite duration of Long.MAX_VALUE days.
196+
*/
197+
public static Duration infinite() { // NOSONAR
198+
return INFINITE;
199+
}
200+
201+
/**
202+
* Returns a Duration of {@code count} microseconds.
203+
*/
204+
public static Duration microseconds(long count) {
205+
return new Duration(count, TimeUnit.MICROSECONDS);
206+
}
207+
208+
/**
209+
* Returns a Duration of {@code count} milliseconds.
210+
*/
211+
public static Duration millis(long count) {
212+
return new Duration(count, TimeUnit.MILLISECONDS);
213+
}
214+
215+
/**
216+
* Returns a Duration of {@code count} milliseconds.
217+
*/
218+
public static Duration milliseconds(long count) {
219+
return new Duration(count, TimeUnit.MILLISECONDS);
220+
}
221+
222+
/**
223+
* Returns a Duration of {@code count} minutes.
224+
*/
225+
public static Duration mins(long count) {
226+
return new Duration(count, TimeUnit.MINUTES);
227+
}
228+
229+
/**
230+
* Returns a Duration of {@code count} minutes.
231+
*/
232+
public static Duration minutes(long count) {
233+
return new Duration(count, TimeUnit.MINUTES);
234+
}
235+
236+
/**
237+
* Returns a Duration of {@code count} nanoseconds.
238+
*/
239+
public static Duration nanos(long count) {
240+
return new Duration(count, TimeUnit.NANOSECONDS);
241+
}
242+
243+
/**
244+
* Returns a Duration of {@code count} nanoseconds.
245+
*/
246+
public static Duration nanoseconds(long count) {
247+
return new Duration(count, TimeUnit.NANOSECONDS);
248+
}
249+
250+
/**
251+
* Returns a Duration of {@code count} {@code unit}s.
252+
*/
253+
public static Duration of(long count, TimeUnit unit) {
254+
return new Duration(count, unit);
255+
}
256+
257+
/**
258+
* Returns a Duration from the parsed {@code duration}. Example:
259+
* <br />
260+
* <pre>
261+
* 5 s
262+
* 5 seconds
263+
* 10m
264+
* 10 minutes
265+
* </pre>
266+
*/
267+
public static Duration of(String duration) {
268+
Matcher matcher = PATTERN.matcher(duration);
269+
if (!matcher.matches()) {
270+
throw new IllegalArgumentException("Invalid duration: " + duration);
271+
}
272+
273+
if (matcher.group(1) != null) {
274+
return INFINITE;
275+
} else {
276+
String unit = matcher.group(4);
277+
String value = matcher.group(3);
278+
return new Duration(Long.parseLong(value), SUFFIXES.get(unit));
279+
}
280+
}
281+
282+
/**
283+
* Returns a Duration of {@code count} seconds.
284+
*/
285+
public static Duration seconds(long count) {
286+
return new Duration(count, TimeUnit.SECONDS);
287+
}
288+
289+
/**
290+
* Returns a Duration of {@code count} seconds.
291+
*/
292+
public static Duration secs(long count) {
293+
return new Duration(count, TimeUnit.SECONDS);
294+
}
295+
296+
@Override
297+
public boolean equals(Object obj) {
298+
if (this == obj) {
299+
return true;
300+
} else if ((obj == null) || (getClass() != obj.getClass())) {
301+
return false;
302+
}
303+
final Duration duration = (Duration) obj;
304+
return (length == duration.length) && (timeUnit == duration.timeUnit);
305+
}
306+
307+
@Override
308+
public int hashCode() {
309+
return (31 * (int) (length ^ (length >>> 32))) + timeUnit.hashCode();
310+
}
311+
312+
@Override
313+
public String toString() {
314+
String units = timeUnit.toString().toLowerCase();
315+
if (length == 1)
316+
units = units.substring(0, units.length() - 1);
317+
return Long.toString(length) + ' ' + units;
318+
}
319+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.javacore.time;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
6+
import static org.junit.Assert.fail;
7+
8+
public class DurationTest {
9+
@Test
10+
public void testCombineTimeUtil() throws Exception {
11+
Assert.assertEquals(Duration.days(1).toMilliseconds(), 24 * 3600 * 1000);
12+
Assert.assertEquals(24 * 3600 * 1000 * 3, Duration.days(3).toMilliseconds());
13+
Assert.assertEquals(7 * 24 * 3600 * 1000 / 1000, Duration.days(7).toSeconds());
14+
}
15+
16+
@Test
17+
public void testValidDurationStrings() throws Exception {
18+
Assert.assertEquals(Duration.of("5ns"), Duration.nanoseconds(5));
19+
Assert.assertEquals(Duration.of("5microsecond"), Duration.microseconds(5));
20+
Assert.assertEquals(Duration.of("5milliseconds"), Duration.millis(5));
21+
Assert.assertEquals(Duration.of("5 seconds"), Duration.seconds(5));
22+
Assert.assertEquals(Duration.of("5 minutes"), Duration.mins(5));
23+
Assert.assertEquals(Duration.of("5 hours"), Duration.hours(5));
24+
Assert.assertEquals(Duration.of("5 days"), Duration.days(5));
25+
Assert.assertEquals(Duration.of("inf"), Duration.inf());
26+
Assert.assertEquals(Duration.of("infinite"), Duration.inf());
27+
Assert.assertEquals(Duration.of("∞"), Duration.infinite());
28+
29+
// Interesting value but legal nevertheless
30+
Assert.assertEquals(Duration.of("0s"), Duration.seconds(0));
31+
}
32+
33+
private void testInvalidDurationString(String duration) {
34+
try {
35+
Duration.of(duration);
36+
fail("Duration string '" + duration + "' should not parse correctly.");
37+
} catch (IllegalArgumentException iae) {
38+
// Expected
39+
}
40+
}
41+
42+
@Test
43+
public void testInvalidDurationStrings() {
44+
testInvalidDurationString("foobar");
45+
testInvalidDurationString("ms3");
46+
testInvalidDurationString("34 lightyears");
47+
testInvalidDurationString("34 seconds a day");
48+
testInvalidDurationString("5 days a week");
49+
testInvalidDurationString("");
50+
testInvalidDurationString("2");
51+
testInvalidDurationString("ns");
52+
}
53+
54+
@Test
55+
public void testReplaceOldTimeUtils() {
56+
final int HOUR = 1000 * 60 * 60;
57+
long randomTimestamp = (long) (Math.random() * 400000000L) + 100000;
58+
Assert.assertEquals(randomTimestamp / HOUR, Duration.millis(randomTimestamp).toHours());
59+
Assert.assertEquals(randomTimestamp / 1000, Duration.millis(randomTimestamp).toSeconds());
60+
}
61+
}

src/main/java/org/javacore/time/DurationTest.java renamed to src/test/java/org/javacore/time/PlayDuration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* Created by bysocket on 16/8/23.
1111
*/
12-
public class DurationTest {
12+
public class PlayDuration {
1313
public static void main(String[] args) throws InterruptedException {
1414
Instant start = Instant.now();
1515
TimeUnit.SECONDS.sleep(3);

0 commit comments

Comments
 (0)