View Javadoc
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  }