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