View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.Calendar;
27  import java.util.Date;
28  import java.util.GregorianCalendar;
29  import java.util.Locale;
30  import java.util.concurrent.TimeUnit;
31  import net.jcip.annotations.Immutable;
32  import org.modeshape.common.util.CheckArg;
33  import org.joda.time.Chronology;
34  import org.joda.time.DateTime;
35  import org.joda.time.DateTimeZone;
36  
37  /**
38   * Implementation of DateTime based upon the Joda-Time library.
39   */
40  @Immutable
41  public class JodaDateTime implements org.modeshape.graph.property.DateTime {
42  
43      private static final DateTimeZone UTC_ZONE = DateTimeZone.forID("UTC");
44  
45      /**
46       */
47      private static final long serialVersionUID = -730188225988292422L;
48  
49      private static final int MILLIS_IN_HOUR = 1000 * 60 * 60;
50  
51      private final DateTime instance;
52      private final long millisInUtc;
53  
54      public JodaDateTime() {
55          this.instance = new DateTime();
56          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
57      }
58  
59      public JodaDateTime( String iso8601 ) {
60          this.instance = new DateTime(iso8601);
61          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
62      }
63  
64      public JodaDateTime( String iso8601,
65                           String timeZoneId ) {
66          this.instance = new DateTime(iso8601, DateTimeZone.forID(timeZoneId));
67          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
68      }
69  
70      public JodaDateTime( long milliseconds ) {
71          this.instance = new DateTime(milliseconds);
72          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
73      }
74  
75      public JodaDateTime( long milliseconds,
76                           Chronology chronology ) {
77          this.instance = new DateTime(milliseconds, chronology);
78          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
79      }
80  
81      public JodaDateTime( long milliseconds,
82                           String timeZoneId ) {
83          this.instance = new DateTime(milliseconds, DateTimeZone.forID(timeZoneId));
84          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
85      }
86  
87      public JodaDateTime( DateTimeZone dateTimeZone ) {
88          this.instance = new DateTime(dateTimeZone);
89          this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
90      }
91  
92      public JodaDateTime( int year,
93                           int monthOfYear,
94                           int dayOfMonth,
95                           int hourOfDay,
96                           int minuteOfHour,
97                           int secondOfMinute,
98                           int millisecondsOfSecond ) {
99          this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisecondsOfSecond);
100         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
101     }
102 
103     public JodaDateTime( int year,
104                          int monthOfYear,
105                          int dayOfMonth,
106                          int hourOfDay,
107                          int minuteOfHour,
108                          int secondOfMinute,
109                          int millisecondsOfSecond,
110                          Chronology chronology ) {
111         this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
112                                      millisecondsOfSecond, chronology);
113         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
114     }
115 
116     public JodaDateTime( int year,
117                          int monthOfYear,
118                          int dayOfMonth,
119                          int hourOfDay,
120                          int minuteOfHour,
121                          int secondOfMinute,
122                          int millisecondsOfSecond,
123                          DateTimeZone dateTimeZone ) {
124         this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
125                                      millisecondsOfSecond, dateTimeZone);
126         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
127     }
128 
129     public JodaDateTime( int year,
130                          int monthOfYear,
131                          int dayOfMonth,
132                          int hourOfDay,
133                          int minuteOfHour,
134                          int secondOfMinute,
135                          int millisecondsOfSecond,
136                          int timeZoneOffsetHours ) {
137         this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
138                                      millisecondsOfSecond, DateTimeZone.forOffsetHours(timeZoneOffsetHours));
139         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
140     }
141 
142     public JodaDateTime( int year,
143                          int monthOfYear,
144                          int dayOfMonth,
145                          int hourOfDay,
146                          int minuteOfHour,
147                          int secondOfMinute,
148                          int millisecondsOfSecond,
149                          String timeZoneId ) {
150         this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
151                                      millisecondsOfSecond, DateTimeZone.forID(timeZoneId));
152         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
153     }
154 
155     public JodaDateTime( java.util.Date jdkDate ) {
156         this.instance = new DateTime(jdkDate);
157         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
158     }
159 
160     public JodaDateTime( java.util.Calendar jdkCalendar ) {
161         this.instance = new DateTime(jdkCalendar);
162         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
163     }
164 
165     public JodaDateTime( DateTime dateTime ) {
166         this.instance = dateTime; // it's immutable, so just hold onto the supplied instance
167         this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
168     }
169 
170     /**
171      * {@inheritDoc}
172      */
173     public int getCenturyOfEra() {
174         return this.instance.getCenturyOfEra();
175     }
176 
177     /**
178      * {@inheritDoc}
179      */
180     public int getDayOfMonth() {
181         return this.instance.getDayOfMonth();
182     }
183 
184     /**
185      * {@inheritDoc}
186      */
187     public int getDayOfWeek() {
188         return this.instance.getDayOfWeek();
189     }
190 
191     /**
192      * {@inheritDoc}
193      */
194     public int getDayOfYear() {
195         return this.instance.getDayOfYear();
196     }
197 
198     /**
199      * {@inheritDoc}
200      */
201     public int getEra() {
202         return this.instance.getEra();
203     }
204 
205     /**
206      * {@inheritDoc}
207      */
208     public int getHourOfDay() {
209         return this.instance.getHourOfDay();
210     }
211 
212     /**
213      * {@inheritDoc}
214      */
215     public int getMillisOfSecond() {
216         return this.instance.getMillisOfSecond();
217     }
218 
219     /**
220      * {@inheritDoc}
221      */
222     public long getMilliseconds() {
223         return this.instance.getMillis();
224     }
225 
226     /**
227      * {@inheritDoc}
228      * 
229      * @see org.modeshape.graph.property.DateTime#getMillisecondsInUtc()
230      */
231     public long getMillisecondsInUtc() {
232         return millisInUtc;
233     }
234 
235     /**
236      * {@inheritDoc}
237      */
238     public int getMinuteOfHour() {
239         return this.instance.getMinuteOfHour();
240     }
241 
242     /**
243      * {@inheritDoc}
244      */
245     public int getMonthOfYear() {
246         return this.instance.getMonthOfYear();
247     }
248 
249     /**
250      * {@inheritDoc}
251      */
252     public int getSecondOfMinute() {
253         return this.instance.getSecondOfMinute();
254     }
255 
256     /**
257      * {@inheritDoc}
258      */
259     public String getString() {
260         return this.instance.toString(org.joda.time.format.ISODateTimeFormat.dateTime());
261     }
262 
263     /**
264      * {@inheritDoc}
265      */
266     public int getWeekOfWeekyear() {
267         return this.instance.getWeekOfWeekyear();
268     }
269 
270     /**
271      * {@inheritDoc}
272      */
273     public int getWeekyear() {
274         return this.instance.getWeekyear();
275     }
276 
277     /**
278      * {@inheritDoc}
279      */
280     public int getYear() {
281         return this.instance.getYear();
282     }
283 
284     /**
285      * {@inheritDoc}
286      */
287     public int getYearOfCentury() {
288         return this.instance.getYearOfCentury();
289     }
290 
291     /**
292      * {@inheritDoc}
293      */
294     public int getYearOfEra() {
295         return this.instance.getYearOfEra();
296     }
297 
298     /**
299      * {@inheritDoc}
300      */
301     public int getTimeZoneOffsetHours() {
302         // return this.instance.getZone().toTimeZone().getRawOffset() / MILLIS_IN_HOUR;
303         return this.instance.getZone().getOffset(this.instance.getMillis()) / MILLIS_IN_HOUR;
304     }
305 
306     /**
307      * {@inheritDoc}
308      */
309     public String getTimeZoneId() {
310         return this.instance.getZone().getID();
311     }
312 
313     /**
314      * {@inheritDoc}
315      */
316     public Calendar toCalendar() {
317         return toCalendar(null);
318     }
319 
320     /**
321      * {@inheritDoc}
322      */
323     public Calendar toCalendar( Locale locale ) {
324         return this.instance.toCalendar(locale);
325     }
326 
327     /**
328      * {@inheritDoc}
329      */
330     public Date toDate() {
331         return this.instance.toDate();
332     }
333 
334     /**
335      * {@inheritDoc}
336      */
337     public GregorianCalendar toGregorianCalendar() {
338         return this.instance.toGregorianCalendar();
339     }
340 
341     /**
342      * {@inheritDoc}
343      */
344     public int compareTo( org.modeshape.graph.property.DateTime that ) {
345         long diff = this.getMillisecondsInUtc() - that.getMillisecondsInUtc();
346         return diff == 0 ? 0 : diff > 0 ? 1 : -1;
347     }
348 
349     /**
350      * {@inheritDoc}
351      */
352     @Override
353     public int hashCode() {
354         return (int)this.millisInUtc;
355     }
356 
357     /**
358      * {@inheritDoc}
359      */
360     @Override
361     public boolean equals( Object obj ) {
362         if (obj == this) return true;
363         if (obj instanceof org.modeshape.graph.property.DateTime) {
364             org.modeshape.graph.property.DateTime that = (org.modeshape.graph.property.DateTime)obj;
365             return this.getMillisecondsInUtc() == that.getMillisecondsInUtc();
366         }
367         if (obj instanceof DateTime) {
368             DateTime that = (DateTime)obj;
369             return this.getMillisecondsInUtc() == that.withZone(UTC_ZONE).getMillis();
370         }
371         return false;
372     }
373 
374     /**
375      * {@inheritDoc}
376      */
377     @Override
378     public String toString() {
379         return getString();
380     }
381 
382     /**
383      * {@inheritDoc}
384      */
385     public org.modeshape.graph.property.DateTime toUtcTimeZone() {
386         DateTimeZone utc = DateTimeZone.forID("UTC");
387         if (this.instance.getZone().equals(utc)) return this;
388         DateTime jodaTime = this.instance.withZone(utc);
389         return new JodaDateTime(jodaTime);
390     }
391 
392     /**
393      * {@inheritDoc}
394      */
395     public org.modeshape.graph.property.DateTime toTimeZone( String timeZoneId ) {
396         CheckArg.isNotNull(timeZoneId, "time zone identifier");
397         DateTime jodaTime = this.instance.withZone(DateTimeZone.forID(timeZoneId));
398         return new JodaDateTime(jodaTime);
399     }
400 
401     /**
402      * {@inheritDoc}
403      * 
404      * @see org.modeshape.graph.property.DateTime#isBefore(org.modeshape.graph.property.DateTime)
405      */
406     public boolean isBefore( org.modeshape.graph.property.DateTime other ) {
407         return this.compareTo(other) < 0;
408     }
409 
410     /**
411      * {@inheritDoc}
412      * 
413      * @see org.modeshape.graph.property.DateTime#isSameAs(org.modeshape.graph.property.DateTime)
414      */
415     public boolean isSameAs( org.modeshape.graph.property.DateTime other ) {
416         if (other == this) return true;
417         if (other instanceof JodaDateTime) {
418             JodaDateTime that = (JodaDateTime)other;
419 
420             /*
421              * The equals semantics for JodaDateTimes are very strict, implying that not only are the two instants represented
422              * by the JodaDateTimes logically equivalent, but also that the Chronology and DateTimeZone are the same.  
423              * Here we use equals to ensure that the two DateTimes are equivalent.
424              */
425             return this.instance.equals(that.instance);
426         }
427         return this.instance.equals(other);
428     }
429 
430     /**
431      * {@inheritDoc}
432      * 
433      * @see org.modeshape.graph.property.DateTime#isAfter(org.modeshape.graph.property.DateTime)
434      */
435     public boolean isAfter( org.modeshape.graph.property.DateTime other ) {
436         return this.compareTo(other) > 0;
437     }
438 
439     /**
440      * {@inheritDoc}
441      * 
442      * @see org.modeshape.graph.property.DateTime#minus(long, java.util.concurrent.TimeUnit)
443      */
444     public org.modeshape.graph.property.DateTime minus( long timeAmount,
445                                                         TimeUnit unit ) {
446         CheckArg.isNotNull(unit, "unit");
447         return new JodaDateTime(this.instance.minus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
448     }
449 
450     /**
451      * {@inheritDoc}
452      * 
453      * @see org.modeshape.graph.property.DateTime#minusDays(int)
454      */
455     public org.modeshape.graph.property.DateTime minusDays( int days ) {
456         return new JodaDateTime(this.instance.minusDays(days));
457     }
458 
459     /**
460      * {@inheritDoc}
461      * 
462      * @see org.modeshape.graph.property.DateTime#minusHours(int)
463      */
464     public org.modeshape.graph.property.DateTime minusHours( int hours ) {
465         return new JodaDateTime(this.instance.minusHours(hours));
466     }
467 
468     /**
469      * {@inheritDoc}
470      * 
471      * @see org.modeshape.graph.property.DateTime#minusMillis(int)
472      */
473     public org.modeshape.graph.property.DateTime minusMillis( int milliseconds ) {
474         return new JodaDateTime(this.instance.minusMillis(milliseconds));
475     }
476 
477     /**
478      * {@inheritDoc}
479      * 
480      * @see org.modeshape.graph.property.DateTime#minusMinutes(int)
481      */
482     public org.modeshape.graph.property.DateTime minusMinutes( int minutes ) {
483         return new JodaDateTime(this.instance.minusMinutes(minutes));
484     }
485 
486     /**
487      * {@inheritDoc}
488      * 
489      * @see org.modeshape.graph.property.DateTime#minusMonths(int)
490      */
491     public org.modeshape.graph.property.DateTime minusMonths( int months ) {
492         return new JodaDateTime(this.instance.minusMonths(months));
493     }
494 
495     /**
496      * {@inheritDoc}
497      * 
498      * @see org.modeshape.graph.property.DateTime#minusSeconds(int)
499      */
500     public org.modeshape.graph.property.DateTime minusSeconds( int seconds ) {
501         return new JodaDateTime(this.instance.minusSeconds(seconds));
502     }
503 
504     /**
505      * {@inheritDoc}
506      * 
507      * @see org.modeshape.graph.property.DateTime#minusWeeks(int)
508      */
509     public org.modeshape.graph.property.DateTime minusWeeks( int weeks ) {
510         return new JodaDateTime(this.instance.minusWeeks(weeks));
511     }
512 
513     /**
514      * {@inheritDoc}
515      * 
516      * @see org.modeshape.graph.property.DateTime#minusYears(int)
517      */
518     public org.modeshape.graph.property.DateTime minusYears( int years ) {
519         return new JodaDateTime(this.instance.minusYears(years));
520     }
521 
522     /**
523      * {@inheritDoc}
524      * 
525      * @see org.modeshape.graph.property.DateTime#plus(long, java.util.concurrent.TimeUnit)
526      */
527     public org.modeshape.graph.property.DateTime plus( long timeAmount,
528                                                        TimeUnit unit ) {
529         CheckArg.isNotNull(unit, "unit");
530         return new JodaDateTime(this.instance.plus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
531     }
532 
533     /**
534      * {@inheritDoc}
535      * 
536      * @see org.modeshape.graph.property.DateTime#plusDays(int)
537      */
538     public org.modeshape.graph.property.DateTime plusDays( int days ) {
539         return new JodaDateTime(this.instance.plusDays(days));
540     }
541 
542     /**
543      * {@inheritDoc}
544      * 
545      * @see org.modeshape.graph.property.DateTime#plusHours(int)
546      */
547     public org.modeshape.graph.property.DateTime plusHours( int hours ) {
548         return new JodaDateTime(this.instance.plusHours(hours));
549     }
550 
551     /**
552      * {@inheritDoc}
553      * 
554      * @see org.modeshape.graph.property.DateTime#plusMillis(int)
555      */
556     public org.modeshape.graph.property.DateTime plusMillis( int milliseconds ) {
557         return new JodaDateTime(this.instance.plusMillis(milliseconds));
558     }
559 
560     /**
561      * {@inheritDoc}
562      * 
563      * @see org.modeshape.graph.property.DateTime#plusMinutes(int)
564      */
565     public org.modeshape.graph.property.DateTime plusMinutes( int minutes ) {
566         return new JodaDateTime(this.instance.plusMinutes(minutes));
567     }
568 
569     /**
570      * {@inheritDoc}
571      * 
572      * @see org.modeshape.graph.property.DateTime#plusMonths(int)
573      */
574     public org.modeshape.graph.property.DateTime plusMonths( int months ) {
575         return new JodaDateTime(this.instance.plusMonths(months));
576     }
577 
578     /**
579      * {@inheritDoc}
580      * 
581      * @see org.modeshape.graph.property.DateTime#plusSeconds(int)
582      */
583     public org.modeshape.graph.property.DateTime plusSeconds( int seconds ) {
584         return new JodaDateTime(this.instance.plusSeconds(seconds));
585     }
586 
587     /**
588      * {@inheritDoc}
589      * 
590      * @see org.modeshape.graph.property.DateTime#plusWeeks(int)
591      */
592     public org.modeshape.graph.property.DateTime plusWeeks( int weeks ) {
593         return new JodaDateTime(this.instance.plusWeeks(weeks));
594     }
595 
596     /**
597      * {@inheritDoc}
598      * 
599      * @see org.modeshape.graph.property.DateTime#plusYears(int)
600      */
601     public org.modeshape.graph.property.DateTime plusYears( int years ) {
602         return new JodaDateTime(this.instance.plusYears(years));
603     }
604 
605 }