-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReactiveInstant.java
149 lines (147 loc) · 4.86 KB
/
ReactiveInstant.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Part of Reactive time for Hookless: https://hookless.machinezoo.com/time
package com.machinezoo.hookless.time;
import java.math.*;
import java.time.*;
import java.time.temporal.*;
import com.machinezoo.stagean.*;
/**
* Reactive version of {@link Instant}.
*/
@DraftApi("requires review")
@DraftCode("requires review")
@NoTests
@StubDocs
public class ReactiveInstant implements Comparable<ReactiveInstant> {
final ReactiveClock clock;
final Duration shift;
ReactiveInstant(ReactiveClock clock, Duration shift) {
this.clock = clock;
this.shift = shift;
}
public static ReactiveInstant now() {
return ReactiveClock.get().now();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
else if (obj instanceof ReactiveInstant) {
ReactiveInstant other = (ReactiveInstant)obj;
clock.checkSame(other.clock);
return shift.equals(other.shift);
} else if (obj instanceof Instant)
return compareTo((Instant)obj) == 0;
else
return false;
}
@Override
public int hashCode() {
return shift.hashCode();
}
@Override
public int compareTo(ReactiveInstant other) {
clock.checkSame(other.clock);
return shift.compareTo(other.shift);
}
public int compareTo(Instant instant) {
return clock.compareTo(instant.minus(shift));
}
public boolean isAfter(ReactiveInstant other) {
clock.checkSame(other.clock);
return shift.compareTo(other.shift) > 0;
}
public boolean isAfter(Instant instant) {
return clock.isAfter(instant.minus(shift));
}
public boolean isBefore(ReactiveInstant other) {
clock.checkSame(other.clock);
return shift.compareTo(other.shift) < 0;
}
public boolean isBefore(Instant instant) {
return clock.isBefore(instant.minus(shift));
}
public Instant plus(ShrinkingReactiveDuration duration) {
clock.checkSame(duration.clock);
return duration.zero.plus(shift);
}
public ReactiveInstant plus(Duration duration) {
return new ReactiveInstant(clock, shift.plus(duration));
}
public ReactiveInstant plus(long amount, TemporalUnit unit) {
return plus(Duration.of(amount, unit));
}
public ReactiveInstant plusSeconds(long seconds) {
return plus(Duration.ofSeconds(seconds));
}
public ReactiveInstant plusMillis(long millis) {
return plus(Duration.ofMillis(millis));
}
public ReactiveInstant plusNanos(long nanos) {
return plus(Duration.ofNanos(nanos));
}
public Instant minus(GrowingReactiveDuration duration) {
clock.checkSame(duration.clock);
return duration.zero.plus(shift);
}
public ReactiveInstant minus(Duration duration) {
return new ReactiveInstant(clock, shift.minus(duration));
}
public ReactiveInstant minus(long amount, TemporalUnit unit) {
return minus(Duration.of(amount, unit));
}
public ReactiveInstant minusSeconds(long seconds) {
return minus(Duration.ofSeconds(seconds));
}
public ReactiveInstant minusMillis(long millis) {
return minus(Duration.ofMillis(millis));
}
public ReactiveInstant minusNanos(long nanos) {
return minus(Duration.ofNanos(nanos));
}
public Instant truncatedTo(Duration unit) {
if (unit.isNegative() || unit.isZero())
throw new IllegalArgumentException("Can only truncate with positive unit");
if (unit.compareTo(Duration.ofDays(1)) > 0)
throw new IllegalArgumentException("Cannot truncate with unit longer that one day");
long nanoUnit = unit.toNanos();
if (Duration.ofDays(1).toNanos() % nanoUnit != 0)
throw new IllegalArgumentException("Can only truncate with unit that divides day");
Instant instant = clock.instant().plus(shift);
Instant days = instant.truncatedTo(ChronoUnit.DAYS);
long nanoTime = Duration.between(days, instant).toNanos();
Instant truncated = days.plus(Duration.ofNanos(nanoTime / nanoUnit * nanoUnit));
Instant constraint = truncated.minus(shift);
clock.constrainLeftClosed(constraint);
clock.constrainRightOpen(constraint.plus(unit));
return truncated;
}
public Instant truncatedTo(TemporalUnit unit) {
return truncatedTo(unit.getDuration());
}
public long getEpochSecond() {
return truncatedTo(ChronoUnit.SECONDS).getEpochSecond();
}
public long toEpochMilli() {
return truncatedTo(ChronoUnit.MILLIS).toEpochMilli();
}
public long until(Instant end, Duration unit) {
return ReactiveDuration.between(this, end).toUnits(unit);
}
public long until(Instant end, TemporalUnit unit) {
return ReactiveDuration.between(this, end).toUnits(unit);
}
public long until(ReactiveInstant end, Duration unit) {
Duration duration = ReactiveDuration.between(this, end);
BigInteger big = ReactiveDuration.big(duration).divide(ReactiveDuration.big(unit));
if (big.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 || big.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0)
throw new ArithmeticException();
return big.longValue();
}
public long until(ReactiveInstant end, TemporalUnit unit) {
return until(end, unit.getDuration());
}
@Override
public String toString() {
return "now + " + shift.toString();
}
}