1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.time;
18
19 import org.apache.logging.log4j.core.util.Clock;
20 import org.apache.logging.log4j.util.PerformanceSensitive;
21
22 import java.io.Serializable;
23
24
25
26
27
28
29
30
31
32
33
34 @PerformanceSensitive("allocation")
35 public class MutableInstant implements Instant, Serializable {
36
37 private static final int MILLIS_PER_SECOND = 1000;
38 private static final int NANOS_PER_MILLI = 1000_000;
39 private static final int NANOS_PER_SECOND = MILLIS_PER_SECOND * NANOS_PER_MILLI;
40
41 private long epochSecond;
42 private int nanoOfSecond;
43
44 @Override
45 public long getEpochSecond() {
46 return epochSecond;
47 }
48
49 @Override
50 public int getNanoOfSecond() {
51 return nanoOfSecond;
52 }
53
54 @Override
55 public long getEpochMillisecond() {
56 final int millis = nanoOfSecond / NANOS_PER_MILLI;
57 final long epochMillisecond = epochSecond * MILLIS_PER_SECOND + millis;
58 return epochMillisecond;
59 }
60
61 @Override
62 public int getNanoOfMillisecond() {
63 final int millis = nanoOfSecond / NANOS_PER_MILLI;
64 final int nanoOfMillisecond = nanoOfSecond - (millis * NANOS_PER_MILLI);
65 return nanoOfMillisecond;
66 }
67
68 public void initFrom(final Instant other) {
69 this.epochSecond = other.getEpochSecond();
70 this.nanoOfSecond = other.getNanoOfSecond();
71 }
72
73
74
75
76
77
78 public void initFromEpochMilli(final long epochMilli, final int nanoOfMillisecond) {
79 validateNanoOfMillisecond(nanoOfMillisecond);
80 this.epochSecond = epochMilli / MILLIS_PER_SECOND;
81 this.nanoOfSecond = (int) (epochMilli - (epochSecond * MILLIS_PER_SECOND)) * NANOS_PER_MILLI + nanoOfMillisecond;
82 }
83
84 private void validateNanoOfMillisecond(final int nanoOfMillisecond) {
85 if (nanoOfMillisecond < 0 || nanoOfMillisecond >= NANOS_PER_MILLI) {
86 throw new IllegalArgumentException("Invalid nanoOfMillisecond " + nanoOfMillisecond);
87 }
88 }
89
90 public void initFrom(final Clock clock) {
91 if (clock instanceof PreciseClock) {
92 ((PreciseClock) clock).init(this);
93 } else {
94 initFromEpochMilli(clock.currentTimeMillis(), 0);
95 }
96 }
97
98
99
100
101
102
103 public void initFromEpochSecond(final long epochSecond, final int nano) {
104 validateNanoOfSecond(nano);
105 this.epochSecond = epochSecond;
106 this.nanoOfSecond = nano;
107 }
108
109 private void validateNanoOfSecond(final int nano) {
110 if (nano < 0 || nano >= NANOS_PER_SECOND) {
111 throw new IllegalArgumentException("Invalid nanoOfSecond " + nano);
112 }
113 }
114
115
116
117
118
119
120
121
122
123 public static void instantToMillisAndNanos(final long epochSecond, final int nano, final long[] result) {
124 final int millis = nano / NANOS_PER_MILLI;
125 result[0] = epochSecond * MILLIS_PER_SECOND + millis;
126 result[1] = nano - (millis * NANOS_PER_MILLI);
127 }
128
129 @Override
130 public boolean equals(final Object object) {
131 if (object == this) {
132 return true;
133 }
134 if (!(object instanceof MutableInstant)) {
135 return false;
136 }
137 final MutableInstant other = (MutableInstant) object;
138 return epochSecond == other.epochSecond && nanoOfSecond == other.nanoOfSecond;
139 }
140
141 @Override
142 public int hashCode() {
143 int result = 17;
144 result = 31 * result + (int) (epochSecond ^ (epochSecond >>> 32));
145 result = 31 * result + nanoOfSecond;
146 return result;
147 }
148
149 @Override
150 public String toString() {
151 final StringBuilder sb = new StringBuilder(64);
152 formatTo(sb);
153 return sb.toString();
154 }
155
156 @Override
157 public void formatTo(final StringBuilder buffer) {
158 buffer.append("MutableInstant[epochSecond=").append(epochSecond).append(", nano=").append(nanoOfSecond).append("]");
159 }
160 }