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