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 }