Project Report: fawkez

Packagesummary org.jcoderz.commons.types

org.jcoderz.commons.types.Date

LineHitsNoteSource
1  /*
2   * $Id: Date.java 1093 2008-07-24 06:30:14Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.types;
34  
35  
36  import java.io.Serializable;
37  import java.text.DateFormat;
38  import java.text.ParseException;
39  import java.text.SimpleDateFormat;
40  import java.util.TimeZone;
41  
42  import org.jcoderz.commons.util.Constants;
43  import org.jcoderz.commons.util.HashCodeUtil;
44  
45  
46  
47  /**
48   * Immutable holder of a Date running through our system.
49   *
50   * This class also holds some time related constants to be used in the code.
51   *
52   * Years before 1 are not fully supported and might result in wrong string
53   * representations.
54   *
55   * @author Andreas Mandel
56   */
57  public final class Date
58        implements Comparable, Serializable
59  {
60     /** Date Formater to use for DATE_TIME_FORMAT_WITH_MILLIS format. */
61100    public static final ThreadLocal DATE_TIME_FORMAT_WITH_MILLIS_FORMATER
62           = new ThreadLocal()
63100          {
64              /**
65               * Thread local date formater.
66               * @see java.lang.ThreadLocal#initialValue()
67               */
68              protected Object initialValue ()
69              {
70100                final DateFormat formater
71                    = new SimpleDateFormat(DATE_TIME_FORMAT_WITH_MILLIS,
72                       Constants.SYSTEM_LOCALE);
73100                formater.setTimeZone(TIME_ZONE);
74100                formater.setLenient(false);
75100                return formater;
76              }
77           };
78  
79     /** Date Formater to use for DATE_TIME_FORMAT format. */
80100    public static final ThreadLocal DATE_TIME_FORMAT_FORMATER
81           = new ThreadLocal()
82100          {
83              /**
84               * Thread local date formater.
85               * @see java.lang.ThreadLocal#initialValue()
86               */
87              protected Object initialValue ()
88              {
89100                final DateFormat formater
90                       = new SimpleDateFormat(DATE_TIME_FORMAT,
91                          Constants.SYSTEM_LOCALE);
92100                formater.setTimeZone(TIME_ZONE);
93100                formater.setLenient(false);
94100                return formater;
95              }
96           };
97  
98     /**
99      * The name of this type.
100      */
101     public static final String TYPE_NAME = "Date";
102  
103     /**
104      * Timezone used by the protocol.
105      */
106100    public static final TimeZone TIME_ZONE = TimeZone.getTimeZone("UTC");
107  
108     /** Number of nano seconds in a milli second. */
109     public static final long NANOS_PER_MILLI = 1000000L;
110  
111     /** Number of milli seconds in a second. */
112     public static final int MILLIS_PER_SECOND = 1000;
113  
114     /** Number of nano seconds in a second. */
115     public static final long NANOS_PER_SECOND
116             = NANOS_PER_MILLI * MILLIS_PER_SECOND;
117  
118     /**
119      * Number of seconds in a minute.
120      */
121     public static final int SECONDS_PER_MINUTE = 60;
122  
123     /**
124      * Number of milli seconds in a minute.
125      */
126     public static final int MILLIS_PER_MINUTE
127           = MILLIS_PER_SECOND * SECONDS_PER_MINUTE;
128  
129     /**
130      * Number of milli seconds in an hour.
131      */
132     public static final int MILLIS_PER_HOUR = MILLIS_PER_MINUTE * 60;
133     /**
134      * Number of milliseconds per day.
135      */
136     public static final int MILLIS_PER_DAY = MILLIS_PER_MINUTE * 60 * 24;
137  
138     /**
139      * Number of milliseconds per week.
140      */
141     public static final int MILLIS_PER_WEEK = MILLIS_PER_DAY * 7;
142  
143     /**
144      * Number of months per year.
145      */
146     public static final int MONTH_PER_YEAR = 12;
147  
148     /**
149      * This date represents the 1.1.1970 00:00:00.000.
150      */
151100    public static final Date OLD_DATE = new Date(0);
152  
153     /**
154      * This date represents the largest possible date
155      * (9999 * 365 * 24 * 60 * 60 * 1000).
156      */
157100    public static final Date FUTURE_DATE = new Date(315328464000000L);
158  
159     /**
160      * The format used to write schema dateTime types.
161      */
162     public static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
163  
164     /**
165      * The format used to write schema dateTime types, if milli seconds
166      * are not equal 0.
167      */
168     public static final String DATE_TIME_FORMAT_WITH_MILLIS
169           = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
170  
171     /**
172      * The format used to parse and write schema date types.
173      */
174     public static final String DATE_FORMAT = "yyyy-MM-dd'Z'";
175  
176     /**
177      * use this serialVersionUID for serialization.
178      */
179     static final long serialVersionUID = -5924234143761665938L;
180  
181     /**
182      * The number of (milli)seconds since January 1, 1970, 00:00:00 GMT
183      * represented by this date.
184      * The millis are always reset to 0.
185      */
186     private final long mTime;
187  
188     /**
189      * Holds the string representation once it was computed.
190      */
191100    private transient String mString = null;
192  
193  
194     /**
195      * Creates a new instance of Date taking the given long as ms from
196      * 1.1.1970.
197      *
198      * @param time the number of milliseconds.
199      *
200      */
201     public Date (long time)
202100    {
203100       mTime = time;
204100    }
205  
206  
207     /**
208      * Creates a new instance of Date taking the given long as ms from
209      * 1.1.1970.
210      *
211      * @param time the number of milliseconds.
212      * @return a newly generated Date object taking the given long as ms from
213      *       .1.1970.
214      * @see java.util.Date#Date()
215      */
216     public static Date fromLong (long time)
217     {
218100       return new Date(time);
219     }
220  
221     /**
222      * Creates a new instance of Date from a java.util.Date Object.
223      * @param date the date as {@link java.sql.Date java.util.Date}.
224      * @return a newly generated Date object representing the same time as the
225      *         given date.
226      */
227     public static Date fromUtilDate (java.util.Date date)
228     {
229100       return new Date(date.getTime());
230     }
231  
232     /**
233      * Creates a new instance of Date holding the value as found in the given
234      * java.sql.Date.
235      * @param date the date as {@link java.sql.Date java.sql.Date}.
236      * @return a newly generated Date object representing the same time as the
237      *         given date.
238      */
239     public static Date fromSqlDate (java.sql.Date date)
240     {
241100       return new Date(date.getTime());
242     }
243  
244     /**
245      * Creates a new instance of Date holding the value as found in the given
246      * java.sql.Timestamp.
247      * @param timestamp the date as
248      *        {@link java.sql.Timestamp java.sql.Timestamp}.
249      * @return a newly generated Date object representing the same time as the
250      *         given date.
251      */
252     public static Date fromSqlTimestamp (java.sql.Timestamp timestamp)
253     {
254100       return new Date(timestamp.getTime());
255     }
256  
257     /**
258      * Parses the given String with the given format pattern.
259      * NULL is returned if an empty string "" is given as parameter. (This is
260      * to allow empty elements as used in some places.)
261      * @param date the date in given notation
262      * @param pattern the pattern to be used for parsing.
263      * @return a newly generated Date object representing the time given in the
264      *         date or NULL, if the given parameter was an empty string "".
265      * @throws ParseException if the given date is not in the format of the
266      *         given pattern.
267      * @see SimpleDateFormat
268      */
269     public static Date fromString (String date, String pattern)
270           throws ParseException
271     {
272100       Date result = null;
273  
274100       if (date.length() != 0)
275        {
276100          final SimpleDateFormat dateFormat = new SimpleDateFormat(pattern,
277              Constants.SYSTEM_LOCALE);
278100          dateFormat.setLenient(false);
279100          dateFormat.setTimeZone(TIME_ZONE);
280100          result = Date.fromUtilDate(dateFormat.parse(date));
281        }
282100       return result;
283     }
284  
285     /**
286      * Parses the given String as returned by the toString method.
287      * @param date the date in String representation
288      * @return a newly generated Date object representing the time given in the
289      *         date, or null if the input string was null.
290      * @throws ParseException if the given date is not in the format of the
291      *         Date.toString() format.
292      */
293     public static Date fromString (String date)
294           throws ParseException
295     {
296        Date result;
297100       if (date != null && date.length() != 0)
298        {
299           try
300           {
301100             result = Date.fromUtilDate(
302                    ((DateFormat) DATE_TIME_FORMAT_WITH_MILLIS_FORMATER.get()).
303                       parse(date));
304           }
305100          catch (ParseException x)
306           {
307100             result = Date.fromUtilDate(
308                    ((DateFormat) DATE_TIME_FORMAT_FORMATER.get()).
309                       parse(date));
310100          }
311        }
312        else
313        {
314100          result = null;
315        }
316100       return result;
317     }
318  
319     /**
320      * Returns a Date object that holds the current time.
321      * @return a newly generated Date object representing current time.
322      */
323     public static Date now ()
324     {
325100       return new Date(System.currentTimeMillis());
326     }
327  
328     /**
329      * Returns a Date object that holds the current time plus the given
330      * milliseconds in the future.
331      * @param offset the number of millis to step into the future.
332      * @return a newly generated Date object.
333      */
334     public static Date nowPlus (long offset)
335     {
336100       return new Date(System.currentTimeMillis() + offset);
337     }
338  
339     /**
340      * Returns the number of days since the Unix Epoch (1970/01/01).
341      * @return the number of days since the Unix Epoch (1970/01/01).
342      */
343     public static int getDaysSinceEpoch ()
344     {
345100       return (int) (System.currentTimeMillis() / MILLIS_PER_DAY);
346     }
347  
348     /**
349      * Returns the number of days between Unix Epoch (1970/01/01) and
350      * <code>d</code>.
351      * @param d the date until when the number of days should be computed
352      * @return the number of days between Unix Epoch and <code>d</code>.
353      */
354     public static int getDaysSinceEpoch (Date d)
355     {
356100       return (int) (d.getTime() / MILLIS_PER_DAY);
357     }
358  
359     /**
360      * Returns the earliest of the two dates.
361      * @param a date a to compare.
362      * @param b date b to compare.
363      * @return the earliest of the two dates.
364      */
365     public static Date earliest (Date a, Date b)
366     {
367100       return a.before(b) ? a : b;
368     }
369  
370     /**
371      * Returns the latest of the two dates.
372      * @param a date a to compare.
373      * @param b date b to compare.
374      * @return the earliest of the two dates.
375      */
376     public static Date latest (Date a, Date b)
377     {
378100       return a.before(b) ? b : a;
379     }
380  
381     /**
382      * Returns a Date object that holds the time of this object plus the given
383      * milliseconds in the future.
384      * @param offset the number of millis to step into the future.
385      * @return a newly generated Date object.
386      */
387     public Date plus (long offset)
388     {
389100       return new Date(mTime + offset);
390     }
391  
392     /**
393      * Returns a Date object that holds the time of this object minus the given
394      * milliseconds in the past.
395      * @param offset the number of millis to step back from this date.
396      * @return a newly generated Date object.
397      */
398     public Date minus (long offset)
399     {
400100       return new Date(mTime - offset);
401     }
402  
403     /**
404      * Returns the date represented by this object as newly generated
405      * {@link java.util.Date java.util.Date} object.
406      * @return the date represented by this object as newly generated
407      * {@link java.util.Date java.util.Date} object.
408      */
409     public java.util.Date toUtilDate ()
410     {
411100       return new java.util.Date(mTime);
412     }
413  
414     /**
415      * Returns the date represented by this object as newly generated
416      * {@link java.sql.Date java.sql.Date} object.
417      * @return the date represented by this object as newly generated
418      * {@link java.sql.Date java.sql.Date} object.
419      */
420     public java.sql.Date toSqlDate ()
421     {
422100       return new java.sql.Date(mTime);
423     }
424  
425     /**
426      * Returns the date represented by this object as newly generated
427      * {@link java.sql.Timestamp java.sql.Timestamp} object.
428      * @return the date represented by this object as newly generated
429      * {@link java.sql.Timestamp java.sql.Timestamp} object.
430      */
431     public java.sql.Timestamp toSqlTimestamp ()
432     {
433100       return new java.sql.Timestamp(mTime);
434     }
435  
436      /**
437       * Returns a hash code value for this object. The result is the
438       * exclusive OR of the two halves of the primitive <tt>long</tt>
439       * value returned by the {@link Date#getTime()}
440       * method. That is, the hash code is the value of the expression:
441       * <blockquote><pre>
442       * (int)(this.getTime()^(this.getTime() &gt;&gt;&gt; 32))</pre></blockquote>
443       *
444       * @return a hash code value for this object.
445       */
446     public int hashCode ()
447     {
448100       return HashCodeUtil.hash(HashCodeUtil.SEED, mTime);
449     }
450  
451     /**
452       * Compares two dates for equality.
453       * @param obj the object to compare with.
454       * @return <code>true</code> if the objects are the same;
455       *          <code>false</code> otherwise.
456      */
457     public boolean equals (Object obj)
458     {
459100       return ((obj instanceof Date) && (((Date) obj).mTime == mTime));
460     }
461  
462     /**
463      * Returns the date as formatted string using the given pattern.
464      * @param pattern the pattern describing the date and time format
465      * @return the date as formatted string using the given pattern.
466      * @see SimpleDateFormat
467      */
468     public String toString (String pattern)
469     {
470100       final SimpleDateFormat dateFormat
471              = new SimpleDateFormat(pattern, Constants.SYSTEM_LOCALE);
472100       dateFormat.setTimeZone(TIME_ZONE);
473100       return dateFormat.format(new java.util.Date(mTime));
474     }
475  
476     /**
477      * Returns the String representation format is according schema dateTime
478      * representation.
479      * @return the String representation format is according schema dateTime
480      * representation.
481      */
482     public String toString ()
483     {
484100       if (mString == null)
485        {
486100          mString
487                 = ((DateFormat) DATE_TIME_FORMAT_WITH_MILLIS_FORMATER.get()).
488                    format(toUtilDate());
489        }
490100       return mString;
491     }
492  
493     /**
494      * Returns the String representation format is according schema date
495      * representation.
496      * @return the String representation format is according schema date
497      * representation.
498      */
499     public String toDateString ()
500     {
501        // To gain speed we might use a thread local SimpleDateFormat
502100       return toString(DATE_FORMAT);
503     }
504  
505     /**
506      * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
507      * represented by this Date object.
508      * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
509      * represented by this Date object.
510      */
511     public long getTime ()
512     {
513100       return mTime;
514     }
515  
516      /**
517       * Compares this Date to another Object.
518       *
519       * @param o the <code>Object</code> to be compared.
520       * @return the value <code>0</code> if the argument is a Date
521       *      equal to this Date; a value less than <code>0</code> if the
522       *      argument is a Date after this Date; and a value greater than
523       *      <code>0</code> if the argument is a Date before this Date.
524       * @exception ClassCastException if the argument is not a
525       *        <code>org.jcoderz.ipp.Date</code>.
526       * @exception NullPointerException if the argument is <code>null</code>.
527       * @see java.lang.Comparable
528       */
529     public int compareTo (Object o)
530           throws NullPointerException, ClassCastException
531     {
532100       final Date other = ((Date) o);
533100       int result = 0;
534  
535100       if (before(other))
536        {
537100          result = -1;
538        }
539100       else if (after(other))
540        {
541100          result = 1;
542        }
543100       return result;
544     }
545  
546     /**
547      * Checks if the this date is before the given date.
548      * @param other the date to compare with.
549      * @return true, if the this date is before the given date.
550      */
551     public boolean before (Date other)
552     {
553100       return mTime < other.mTime;
554     }
555  
556     /**
557      * Checks if the this date is before or equal to the given date.
558      * @param other the date to compare with.
559      * @return true, if the this date is before or equal to the given date.
560      */
561     public boolean beforeOrEqual (Date other)
562     {
563100       return mTime <= other.mTime;
564     }
565  
566     /**
567      * Checks if this date is after the given date.
568      * @param other the date to compare with.
569      * @return true, if this date is after the given date.
570      */
571     public boolean after (Date other)
572     {
573100       return mTime > other.mTime;
574     }
575  
576     /**
577      * Checks if this date is after or equal to the given date.
578      * @param other the date to compare with.
579      * @return true, if this date is after or equal to the given date.
580      */
581     public boolean afterOrEqual (Date other)
582     {
583100       return mTime >= other.mTime;
584     }
585  
586     /**
587      * Returns the elapsed number of milliseconds from this date to now.
588      * @return the elapsed number of milliseconds from this date to now.
589      */
590     public long elapsedMillis ()
591     {
592100       return System.currentTimeMillis() - mTime;
593     }
594  
595     /**
596      * Returns the elapsed number of milliseconds from this date to other.
597      * The result is negative if <tt>other</tt> is before this date.
598      * @param other the date to compare with this date.
599      * @return the elapsed number of milliseconds from this date to other.
600      */
601     public long elapsedMillis (Date other)
602     {
603100       return other.mTime - mTime;
604     }
605  
606     /**
607      * Read resolve method to ensure the class invariants.
608      * @return a Date instance that surely fulfils the class invariants.
609      */
610     private Object readResolve ()
611     {
612100       return new Date(mTime);
613     }
614  }

Findings in this File