001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.graph.properties.basic;
023    
024    import java.util.Calendar;
025    import java.util.Date;
026    import java.util.GregorianCalendar;
027    import java.util.Locale;
028    import java.util.concurrent.TimeUnit;
029    import net.jcip.annotations.Immutable;
030    import org.jboss.dna.common.util.CheckArg;
031    import org.joda.time.Chronology;
032    import org.joda.time.DateTime;
033    import org.joda.time.DateTimeZone;
034    
035    /**
036     * Implementation of DateTime based upon the Joda-Time library.
037     * 
038     * @author Randall Hauch
039     */
040    @Immutable
041    public class JodaDateTime implements org.jboss.dna.graph.properties.DateTime {
042    
043        /**
044         */
045        private static final long serialVersionUID = -730188225988292422L;
046    
047        private static final int MILLIS_IN_HOUR = 1000 * 60 * 60;
048    
049        private final DateTime instance;
050    
051        public JodaDateTime() {
052            this.instance = new DateTime();
053        }
054    
055        public JodaDateTime( String iso8601 ) {
056            this.instance = new DateTime(iso8601);
057        }
058    
059        public JodaDateTime( String iso8601,
060                             String timeZoneId ) {
061            this.instance = new DateTime(iso8601, DateTimeZone.forID(timeZoneId));
062        }
063    
064        public JodaDateTime( long milliseconds ) {
065            this.instance = new DateTime(milliseconds);
066        }
067    
068        public JodaDateTime( long milliseconds,
069                             Chronology chronology ) {
070            this.instance = new DateTime(milliseconds, chronology);
071        }
072    
073        public JodaDateTime( long milliseconds,
074                             String timeZoneId ) {
075            this.instance = new DateTime(milliseconds, DateTimeZone.forID(timeZoneId));
076        }
077    
078        public JodaDateTime( DateTimeZone dateTimeZone ) {
079            this.instance = new DateTime(dateTimeZone);
080        }
081    
082        public JodaDateTime( int year,
083                             int monthOfYear,
084                             int dayOfMonth,
085                             int hourOfDay,
086                             int minuteOfHour,
087                             int secondOfMinute,
088                             int millisecondsOfSecond ) {
089            this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisecondsOfSecond);
090        }
091    
092        public JodaDateTime( int year,
093                             int monthOfYear,
094                             int dayOfMonth,
095                             int hourOfDay,
096                             int minuteOfHour,
097                             int secondOfMinute,
098                             int millisecondsOfSecond,
099                             Chronology chronology ) {
100            this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
101                                         millisecondsOfSecond, chronology);
102        }
103    
104        public JodaDateTime( int year,
105                             int monthOfYear,
106                             int dayOfMonth,
107                             int hourOfDay,
108                             int minuteOfHour,
109                             int secondOfMinute,
110                             int millisecondsOfSecond,
111                             DateTimeZone dateTimeZone ) {
112            this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
113                                         millisecondsOfSecond, dateTimeZone);
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                             int timeZoneOffsetHours ) {
124            this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
125                                         millisecondsOfSecond, DateTimeZone.forOffsetHours(timeZoneOffsetHours));
126        }
127    
128        public JodaDateTime( int year,
129                             int monthOfYear,
130                             int dayOfMonth,
131                             int hourOfDay,
132                             int minuteOfHour,
133                             int secondOfMinute,
134                             int millisecondsOfSecond,
135                             String timeZoneId ) {
136            this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
137                                         millisecondsOfSecond, DateTimeZone.forID(timeZoneId));
138        }
139    
140        public JodaDateTime( java.util.Date jdkDate ) {
141            this.instance = new DateTime(jdkDate);
142        }
143    
144        public JodaDateTime( java.util.Calendar jdkCalendar ) {
145            this.instance = new DateTime(jdkCalendar);
146        }
147    
148        public JodaDateTime( DateTime dateTime ) {
149            this.instance = dateTime; // it's immutable, so just hold onto the supplied instance
150        }
151    
152        /**
153         * {@inheritDoc}
154         */
155        public int getCenturyOfEra() {
156            return this.instance.getCenturyOfEra();
157        }
158    
159        /**
160         * {@inheritDoc}
161         */
162        public int getDayOfMonth() {
163            return this.instance.getDayOfMonth();
164        }
165    
166        /**
167         * {@inheritDoc}
168         */
169        public int getDayOfWeek() {
170            return this.instance.getDayOfWeek();
171        }
172    
173        /**
174         * {@inheritDoc}
175         */
176        public int getDayOfYear() {
177            return this.instance.getDayOfYear();
178        }
179    
180        /**
181         * {@inheritDoc}
182         */
183        public int getEra() {
184            return this.instance.getEra();
185        }
186    
187        /**
188         * {@inheritDoc}
189         */
190        public int getHourOfDay() {
191            return this.instance.getHourOfDay();
192        }
193    
194        /**
195         * {@inheritDoc}
196         */
197        public int getMillisOfSecond() {
198            return this.instance.getMillisOfSecond();
199        }
200    
201        /**
202         * {@inheritDoc}
203         */
204        public long getMilliseconds() {
205            return this.instance.getMillis();
206        }
207    
208        /**
209         * {@inheritDoc}
210         */
211        public int getMinuteOfHour() {
212            return this.instance.getMinuteOfHour();
213        }
214    
215        /**
216         * {@inheritDoc}
217         */
218        public int getMonthOfYear() {
219            return this.instance.getMonthOfYear();
220        }
221    
222        /**
223         * {@inheritDoc}
224         */
225        public int getSecondOfMinute() {
226            return this.instance.getSecondOfMinute();
227        }
228    
229        /**
230         * {@inheritDoc}
231         */
232        public String getString() {
233            return this.instance.toString(org.joda.time.format.ISODateTimeFormat.dateTime());
234        }
235    
236        /**
237         * {@inheritDoc}
238         */
239        public int getWeekOfWeekyear() {
240            return this.instance.getWeekOfWeekyear();
241        }
242    
243        /**
244         * {@inheritDoc}
245         */
246        public int getWeekyear() {
247            return this.instance.getWeekyear();
248        }
249    
250        /**
251         * {@inheritDoc}
252         */
253        public int getYear() {
254            return this.instance.getYear();
255        }
256    
257        /**
258         * {@inheritDoc}
259         */
260        public int getYearOfCentury() {
261            return this.instance.getYearOfCentury();
262        }
263    
264        /**
265         * {@inheritDoc}
266         */
267        public int getYearOfEra() {
268            return this.instance.getYearOfEra();
269        }
270    
271        /**
272         * {@inheritDoc}
273         */
274        public int getTimeZoneOffsetHours() {
275            // return this.instance.getZone().toTimeZone().getRawOffset() / MILLIS_IN_HOUR;
276            return this.instance.getZone().getOffset(this.instance.getMillis()) / MILLIS_IN_HOUR;
277        }
278    
279        /**
280         * {@inheritDoc}
281         */
282        public String getTimeZoneId() {
283            return this.instance.getZone().getID();
284        }
285    
286        /**
287         * {@inheritDoc}
288         */
289        public Calendar toCalendar() {
290            return toCalendar(null);
291        }
292    
293        /**
294         * {@inheritDoc}
295         */
296        public Calendar toCalendar( Locale locale ) {
297            return this.instance.toCalendar(locale);
298        }
299    
300        /**
301         * {@inheritDoc}
302         */
303        public Date toDate() {
304            return this.instance.toDate();
305        }
306    
307        /**
308         * {@inheritDoc}
309         */
310        public GregorianCalendar toGregorianCalendar() {
311            return this.instance.toGregorianCalendar();
312        }
313    
314        /**
315         * {@inheritDoc}
316         */
317        public int compareTo( org.jboss.dna.graph.properties.DateTime that ) {
318            if (that instanceof JodaDateTime) {
319                return this.instance.compareTo(((JodaDateTime)that).instance);
320            }
321            long diff = this.toUtcTimeZone().getMilliseconds() - that.toUtcTimeZone().getMilliseconds();
322            return (int)diff;
323        }
324    
325        /**
326         * {@inheritDoc}
327         */
328        @Override
329        public int hashCode() {
330            return this.instance.hashCode();
331        }
332    
333        /**
334         * {@inheritDoc}
335         */
336        @Override
337        public boolean equals( Object obj ) {
338            if (obj == this) return true;
339            if (obj instanceof JodaDateTime) {
340                JodaDateTime that = (JodaDateTime)obj;
341                return this.instance.equals(that.instance);
342            }
343            if (obj instanceof DateTime) {
344                return this.instance.equals(obj);
345            }
346            return false;
347        }
348    
349        /**
350         * {@inheritDoc}
351         */
352        @Override
353        public String toString() {
354            return getString();
355        }
356    
357        /**
358         * {@inheritDoc}
359         */
360        public org.jboss.dna.graph.properties.DateTime toUtcTimeZone() {
361            DateTime jodaTime = this.instance.withZone(DateTimeZone.forID("UTC"));
362            return new JodaDateTime(jodaTime);
363        }
364    
365        /**
366         * {@inheritDoc}
367         */
368        public org.jboss.dna.graph.properties.DateTime toTimeZone( String timeZoneId ) {
369            CheckArg.isNotNull(timeZoneId, "time zone identifier");
370            DateTime jodaTime = this.instance.withZone(DateTimeZone.forID(timeZoneId));
371            return new JodaDateTime(jodaTime);
372        }
373    
374        /**
375         * {@inheritDoc}
376         * 
377         * @see org.jboss.dna.graph.properties.DateTime#isBefore(org.jboss.dna.graph.properties.DateTime)
378         */
379        public boolean isBefore( org.jboss.dna.graph.properties.DateTime other ) {
380            return this.compareTo(other) < 0;
381        }
382    
383        /**
384         * {@inheritDoc}
385         * 
386         * @see org.jboss.dna.graph.properties.DateTime#isSameAs(org.jboss.dna.graph.properties.DateTime)
387         */
388        public boolean isSameAs( org.jboss.dna.graph.properties.DateTime other ) {
389            return this.compareTo(other) == 0;
390        }
391    
392        /**
393         * {@inheritDoc}
394         * 
395         * @see org.jboss.dna.graph.properties.DateTime#isAfter(org.jboss.dna.graph.properties.DateTime)
396         */
397        public boolean isAfter( org.jboss.dna.graph.properties.DateTime other ) {
398            return this.compareTo(other) > 0;
399        }
400    
401        /**
402         * {@inheritDoc}
403         * 
404         * @see org.jboss.dna.graph.properties.DateTime#minus(long, java.util.concurrent.TimeUnit)
405         */
406        public org.jboss.dna.graph.properties.DateTime minus( long timeAmount,
407                                                              TimeUnit unit ) {
408            CheckArg.isNotNull(unit, "unit");
409            return new JodaDateTime(this.instance.minus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
410        }
411    
412        /**
413         * {@inheritDoc}
414         * 
415         * @see org.jboss.dna.graph.properties.DateTime#minusDays(int)
416         */
417        public org.jboss.dna.graph.properties.DateTime minusDays( int days ) {
418            return new JodaDateTime(this.instance.minusDays(days));
419        }
420    
421        /**
422         * {@inheritDoc}
423         * 
424         * @see org.jboss.dna.graph.properties.DateTime#minusHours(int)
425         */
426        public org.jboss.dna.graph.properties.DateTime minusHours( int hours ) {
427            return new JodaDateTime(this.instance.minusHours(hours));
428        }
429    
430        /**
431         * {@inheritDoc}
432         * 
433         * @see org.jboss.dna.graph.properties.DateTime#minusMillis(int)
434         */
435        public org.jboss.dna.graph.properties.DateTime minusMillis( int milliseconds ) {
436            return new JodaDateTime(this.instance.minusMillis(milliseconds));
437        }
438    
439        /**
440         * {@inheritDoc}
441         * 
442         * @see org.jboss.dna.graph.properties.DateTime#minusMinutes(int)
443         */
444        public org.jboss.dna.graph.properties.DateTime minusMinutes( int minutes ) {
445            return new JodaDateTime(this.instance.minusMinutes(minutes));
446        }
447    
448        /**
449         * {@inheritDoc}
450         * 
451         * @see org.jboss.dna.graph.properties.DateTime#minusMonths(int)
452         */
453        public org.jboss.dna.graph.properties.DateTime minusMonths( int months ) {
454            return new JodaDateTime(this.instance.minusMonths(months));
455        }
456    
457        /**
458         * {@inheritDoc}
459         * 
460         * @see org.jboss.dna.graph.properties.DateTime#minusSeconds(int)
461         */
462        public org.jboss.dna.graph.properties.DateTime minusSeconds( int seconds ) {
463            return new JodaDateTime(this.instance.minusSeconds(seconds));
464        }
465    
466        /**
467         * {@inheritDoc}
468         * 
469         * @see org.jboss.dna.graph.properties.DateTime#minusWeeks(int)
470         */
471        public org.jboss.dna.graph.properties.DateTime minusWeeks( int weeks ) {
472            return new JodaDateTime(this.instance.minusWeeks(weeks));
473        }
474    
475        /**
476         * {@inheritDoc}
477         * 
478         * @see org.jboss.dna.graph.properties.DateTime#minusYears(int)
479         */
480        public org.jboss.dna.graph.properties.DateTime minusYears( int years ) {
481            return new JodaDateTime(this.instance.minusYears(years));
482        }
483    
484        /**
485         * {@inheritDoc}
486         * 
487         * @see org.jboss.dna.graph.properties.DateTime#plus(long, java.util.concurrent.TimeUnit)
488         */
489        public org.jboss.dna.graph.properties.DateTime plus( long timeAmount,
490                                                             TimeUnit unit ) {
491            CheckArg.isNotNull(unit, "unit");
492            return new JodaDateTime(this.instance.plus(TimeUnit.MILLISECONDS.convert(timeAmount, unit)));
493        }
494    
495        /**
496         * {@inheritDoc}
497         * 
498         * @see org.jboss.dna.graph.properties.DateTime#plusDays(int)
499         */
500        public org.jboss.dna.graph.properties.DateTime plusDays( int days ) {
501            return new JodaDateTime(this.instance.plusDays(days));
502        }
503    
504        /**
505         * {@inheritDoc}
506         * 
507         * @see org.jboss.dna.graph.properties.DateTime#plusHours(int)
508         */
509        public org.jboss.dna.graph.properties.DateTime plusHours( int hours ) {
510            return new JodaDateTime(this.instance.plusHours(hours));
511        }
512    
513        /**
514         * {@inheritDoc}
515         * 
516         * @see org.jboss.dna.graph.properties.DateTime#plusMillis(int)
517         */
518        public org.jboss.dna.graph.properties.DateTime plusMillis( int milliseconds ) {
519            return new JodaDateTime(this.instance.plusMillis(milliseconds));
520        }
521    
522        /**
523         * {@inheritDoc}
524         * 
525         * @see org.jboss.dna.graph.properties.DateTime#plusMinutes(int)
526         */
527        public org.jboss.dna.graph.properties.DateTime plusMinutes( int minutes ) {
528            return new JodaDateTime(this.instance.plusMinutes(minutes));
529        }
530    
531        /**
532         * {@inheritDoc}
533         * 
534         * @see org.jboss.dna.graph.properties.DateTime#plusMonths(int)
535         */
536        public org.jboss.dna.graph.properties.DateTime plusMonths( int months ) {
537            return new JodaDateTime(this.instance.plusMonths(months));
538        }
539    
540        /**
541         * {@inheritDoc}
542         * 
543         * @see org.jboss.dna.graph.properties.DateTime#plusSeconds(int)
544         */
545        public org.jboss.dna.graph.properties.DateTime plusSeconds( int seconds ) {
546            return new JodaDateTime(this.instance.plusSeconds(seconds));
547        }
548    
549        /**
550         * {@inheritDoc}
551         * 
552         * @see org.jboss.dna.graph.properties.DateTime#plusWeeks(int)
553         */
554        public org.jboss.dna.graph.properties.DateTime plusWeeks( int weeks ) {
555            return new JodaDateTime(this.instance.plusWeeks(weeks));
556        }
557    
558        /**
559         * {@inheritDoc}
560         * 
561         * @see org.jboss.dna.graph.properties.DateTime#plusYears(int)
562         */
563        public org.jboss.dna.graph.properties.DateTime plusYears( int years ) {
564            return new JodaDateTime(this.instance.plusYears(years));
565        }
566    
567    }