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