1 /*
2 * Copyright (C) 2020-2023 Dipl.-Inform. Kai Hofmann. All rights reserved!
3 */
4 package de.powerstat.validation.values;
5
6
7 import java.util.Objects;
8
9 import de.powerstat.validation.interfaces.IValueObject;
10
11
12 /**
13 * Seconds.
14 *
15 * Not DSGVO relevant.
16 *
17 * TODO inMinutes()
18 * TODO min, max
19 */
20 public final class Seconds implements Comparable<Seconds>, IValueObject
21 {
22 /* *
23 * Cache for singletons.
24 */
25 // private static final Map<Long, Seconds> CACHE = new WeakHashMap<>();
26
27 /**
28 * Seconds.
29 */
30 private final long seconds;
31
32
33 /**
34 * Constructor.
35 *
36 * @param seconds Seconds 0-..
37 * @throws IndexOutOfBoundsException When the seconds is less than 0
38 */
39 private Seconds(final long seconds)
40 {
41 super();
42 if (seconds < 0)
43 {
44 throw new IndexOutOfBoundsException("Negative seconds are not allowed"); //$NON-NLS-1$
45 }
46 this.seconds = seconds;
47 }
48
49
50 /**
51 * Seconds factory.
52 *
53 * @param seconds Seconds 0-..
54 * @return Seconds object
55 */
56 public static Seconds of(final long seconds)
57 {
58 /*
59 synchronized (Seconds.class)
60 {
61 Seconds obj = Seconds.CACHE.get(seconds);
62 if (obj != null)
63 {
64 return obj;
65 }
66 obj = new Seconds(seconds);
67 Seconds.CACHE.put(Long.valueOf(seconds), obj);
68 return obj;
69 }
70 */
71 return new Seconds(seconds);
72 }
73
74
75 /**
76 * Seconds factory.
77 *
78 * @param value Seconds 0-.. string
79 * @return Seconds object
80 */
81 public static Seconds of(final String value)
82 {
83 return of(Long.parseLong(value));
84 }
85
86
87 /**
88 * Returns the value of this Seconds as a long.
89 *
90 * @return The numeric value represented by this object after conversion to type long.
91 */
92 public long longValue()
93 {
94 return this.seconds;
95 }
96
97
98 /**
99 * Returns the value of this Seconds as a String.
100 *
101 * @return The numeric value represented by this object after conversion to type String.
102 */
103 @Override
104 public String stringValue()
105 {
106 return String.valueOf(this.seconds);
107 }
108
109
110 /**
111 * Calculate hash code.
112 *
113 * @return Hash
114 * @see java.lang.Object#hashCode()
115 */
116 @Override
117 public int hashCode()
118 {
119 return Long.hashCode(this.seconds);
120 }
121
122
123 /**
124 * Is equal with another object.
125 *
126 * @param obj Object
127 * @return true when equal, false otherwise
128 * @see java.lang.Object#equals(java.lang.Object)
129 */
130 @Override
131 public boolean equals(final Object obj)
132 {
133 if (this == obj)
134 {
135 return true;
136 }
137 if (!(obj instanceof Seconds))
138 {
139 return false;
140 }
141 final Seconds other = (Seconds)obj;
142 return this.seconds == other.seconds;
143 }
144
145
146 /**
147 * Returns the string representation of this Seconds.
148 *
149 * The exact details of this representation are unspecified and subject to change, but the following may be regarded as typical:
150 *
151 * "Seconds[seconds=1]"
152 *
153 * @return String representation of this Seconds
154 * @see java.lang.Object#toString()
155 */
156 @Override
157 public String toString()
158 {
159 final var builder = new StringBuilder(17);
160 builder.append("Seconds[seconds=").append(this.seconds).append(']'); //$NON-NLS-1$
161 return builder.toString();
162 }
163
164
165 /**
166 * Compare with another object.
167 *
168 * @param obj Object to compare with
169 * @return 0: equal; 1: greater; -1: smaller
170 * @see java.lang.Comparable#compareTo(java.lang.Object)
171 */
172 @Override
173 public int compareTo(final Seconds obj)
174 {
175 Objects.requireNonNull(obj, "obj"); //$NON-NLS-1$
176 return Long.compare(this.seconds, obj.seconds);
177 }
178
179
180 /**
181 * Add other seconds to this seconds.
182 *
183 * @param other Other seconds to add to this seconds
184 * @return New seconds after adding other seconds to this seconds
185 * @throws ArithmeticException In case of an overflow
186 */
187 public Seconds add(final Seconds other)
188 {
189 return Seconds.of(Math.addExact(this.seconds, other.seconds));
190 }
191
192
193 /**
194 * Subtract other seconds from this seconds.
195 *
196 * @param other Other seconds to subtract from this one
197 * @return Absolute new seconds after subtracting other seconds from this seconds
198 */
199 public Seconds subtract(final Seconds other)
200 {
201 if (other.seconds > this.seconds)
202 {
203 return Seconds.of(other.seconds - this.seconds);
204 }
205 return Seconds.of(this.seconds - other.seconds);
206 }
207
208
209 /**
210 * Multiply seconds with a multiplier.
211 *
212 * @param multiplier Multiplier to multiply with
213 * @return New seconds that is a multiplication of this seconds with the multiplier
214 * @throws ArithmeticException In case of an overflow
215 */
216 public Seconds multiply(final long multiplier)
217 {
218 return Seconds.of(Math.multiplyExact(this.seconds, multiplier));
219 }
220
221
222 /**
223 * Divide seconds by a divisor.
224 *
225 * @param divisor Divisor to divide by
226 * @return The largest (closest to positive infinity) long value that is less than or equal to the algebraic quotient.
227 * @throws ArithmeticException In case the divisor is 0.
228 */
229 public Seconds divide(final long divisor)
230 {
231 return Seconds.of(Math.floorDiv(this.seconds, divisor));
232 }
233
234
235 /**
236 * Floor modulo seconds by a divisor.
237 *
238 * @param divisor Divisor to divide by
239 * @return The floor modulus Seconds - (floorDiv(Seconds, divisor) * divisor)
240 * @throws ArithmeticException In case the divisor is 0.
241 */
242 public Seconds modulo(final long divisor)
243 {
244 return Seconds.of(Math.floorMod(this.seconds, divisor));
245 }
246
247 }