001    package org.nakedobjects.applib.value;
002    
003    import java.util.Calendar;
004    import java.util.Date;
005    
006    import org.nakedobjects.applib.annotation.Value;
007    import org.nakedobjects.applib.clock.Clock;
008    
009    
010    /**
011     * Value object representing a date and time value.
012     */
013    @Value(semanticsProviderName = "org.nakedobjects.metamodel.value.DateTimeValueSemanticsProvider")
014    public class DateTime extends Magnitude {
015        
016        private static final long serialVersionUID = 1L;
017        private final Date date;
018    
019        /**
020         * Create a Time object for storing a timeStamp set to the current time.
021         */
022        public DateTime() {
023            final Calendar cal = Calendar.getInstance();
024            final java.util.Date d = new java.util.Date(Clock.getTime());
025            cal.setTime(d);
026            cal.set(Calendar.MILLISECOND, 0);
027            date = cal.getTime();
028        }
029    
030        public DateTime(final Date date) {
031            this.date = date;
032        }
033    
034        public DateTime(int year, int month, int day) {
035            this(year, month, day, 0, 0);
036        }
037    
038        /**
039         * Create a Date object set to the specified day, month and year.
040         */
041        public DateTime(final int year, final int month, final int day, final int hour, final int minute) {
042            this(year, month, day, hour, minute, 0);
043        }
044    
045        public DateTime(final int year, final int month, final int day, final int hour, final int minute, final int second) {
046            checkTime(year, month, day, hour, minute);
047            final Calendar cal = Calendar.getInstance();
048            cal.set(year, month - 1, day, hour, minute, second);
049            cal.set(Calendar.MILLISECOND, 0);
050            date = cal.getTime();
051        }
052    
053        private void checkTime(final int year, final int month, final int day, final int hour, final int minute) {
054            if ((month < 1) || (month > 12)) {
055                throw new IllegalArgumentException("Month must be in the range 1 - 12 inclusive " + month);
056            }
057    
058            final Calendar cal = Calendar.getInstance();
059    
060            cal.set(year, month - 1, 0);
061    
062            final int lastDayOfMonth = cal.getMaximum(Calendar.DAY_OF_MONTH);
063    
064            if ((day < 1) || (day > lastDayOfMonth)) {
065                throw new IllegalArgumentException("Day must be in the range 1 - " + lastDayOfMonth + " inclusive " + day);
066            }
067    
068            if ((hour < 0) || (hour > 23)) {
069                throw new IllegalArgumentException("Hour must be in the range 0 - 23 inclusive " + hour);
070            }
071    
072            if ((minute < 0) || (minute > 59)) {
073                throw new IllegalArgumentException("Minute must be in the range 0 - 59 inclusive " + minute);
074            }
075        }
076    
077        /**
078         * Add the specified days, years and months to this date value.
079         */
080        public DateTime add(final int years, final int months, final int days, final int hours, final int minutes) {
081            final Calendar cal = Calendar.getInstance();
082            cal.setTime(date);
083            cal.add(Calendar.MINUTE, minutes);
084            cal.add(Calendar.HOUR_OF_DAY, hours);
085            cal.add(Calendar.DAY_OF_MONTH, days);
086            cal.add(Calendar.MONTH, months);
087            cal.add(Calendar.YEAR, years);
088            return createDateTime(cal.getTime());
089        }
090    
091        public Calendar calendarValue() {
092            final Calendar c = Calendar.getInstance();
093            c.setTime(date);
094            return c;
095        }
096    
097        protected DateTime createDateTime(final Date date) {
098            return new DateTime(date);
099        }
100    
101        public java.util.Date dateValue() {
102            return new Date(date.getTime());
103        }
104    
105        @Override
106        public boolean equals(final Object obj) {
107            if (obj instanceof DateTime) {
108                final DateTime d = (DateTime) obj;
109                return d.date.equals(date);
110            }
111            return super.equals(obj);
112        }
113    
114        public int getDay() {
115            final Calendar c = Calendar.getInstance();
116            c.setTime(date);
117            return c.get(Calendar.DAY_OF_MONTH);
118        }
119    
120        public int getHour() {
121            final Calendar c = Calendar.getInstance();
122            c.setTime(date);
123            return c.get(Calendar.HOUR_OF_DAY);
124        }
125    
126        public int getMinute() {
127            final Calendar c = Calendar.getInstance();
128            c.setTime(date);
129            return c.get(Calendar.MINUTE);
130        }
131    
132        public int getMonth() {
133            final Calendar c = Calendar.getInstance();
134            c.setTime(date);
135            return c.get(Calendar.MONTH) + 1;
136        }
137    
138        public int getYear() {
139            final Calendar c = Calendar.getInstance();
140            c.setTime(date);
141            return c.get(Calendar.YEAR);
142        }
143    
144        /**
145         * returns true if the time stamp of this object has the same value as the specified time
146         */
147        @Override
148        public boolean isEqualTo(final Magnitude timeStamp) {
149            if (timeStamp instanceof DateTime) {
150                return this.date.equals(((DateTime) timeStamp).date);
151            } else {
152                throw new IllegalArgumentException("Parameter must be of type Time");
153            }
154        }
155    
156        /**
157         * returns true if the timeStamp of this object is earlier than the specified timeStamp
158         */
159        @Override
160        public boolean isLessThan(final Magnitude timeStamp) {
161            if (timeStamp instanceof DateTime) {
162                return date.before(((DateTime) timeStamp).date);
163            } else {
164                throw new IllegalArgumentException("Parameter must be of type Time");
165            }
166        }
167    
168        public long longValue() {
169            return date.getTime();
170        }
171    
172        @Override
173        public String toString() {
174            return longValue() + " [DateTime]";
175        }
176    }
177    // Copyright (c) Naked Objects Group Ltd.