001    /*
002     *  Copyright 2001-2009 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time.field;
017    
018    import java.io.Serializable;
019    
020    import org.joda.time.DurationField;
021    import org.joda.time.DurationFieldType;
022    
023    /**
024     * Duration field class representing a field with a fixed unit length of one
025     * millisecond.
026     * <p>
027     * MillisDurationField is thread-safe and immutable.
028     *
029     * @author Brian S O'Neill
030     * @since 1.0
031     */
032    public final class MillisDurationField extends DurationField implements Serializable {
033    
034        /** Serialization lock. */
035        private static final long serialVersionUID = 2656707858124633367L;
036    
037        /** Singleton instance. */
038        public static final DurationField INSTANCE = new MillisDurationField();
039    
040        /**
041         * Restricted constructor.
042         */
043        private MillisDurationField() {
044            super();
045        }
046        
047        //------------------------------------------------------------------------
048        public DurationFieldType getType() {
049            return DurationFieldType.millis();
050        }
051    
052        public String getName() {
053            return "millis";
054        }
055    
056        /**
057         * Returns true as this field is supported.
058         * 
059         * @return true always
060         */
061        public boolean isSupported() {
062            return true;
063        }
064    
065        /**
066         * Returns true as this field is precise.
067         * 
068         * @return true always
069         */
070        public final boolean isPrecise() {
071            return true;
072        }
073    
074        /**
075         * Returns the amount of milliseconds per unit value of this field.
076         *
077         * @return one always
078         */
079        public final long getUnitMillis() {
080            return 1;
081        }
082    
083        //------------------------------------------------------------------------
084        public int getValue(long duration) {
085            return FieldUtils.safeToInt(duration);
086        }
087    
088        public long getValueAsLong(long duration) {
089            return duration;
090        }
091    
092        public int getValue(long duration, long instant) {
093            return FieldUtils.safeToInt(duration);
094        }
095    
096        public long getValueAsLong(long duration, long instant) {
097            return duration;
098        }
099    
100        public long getMillis(int value) {
101            return value;
102        }
103    
104        public long getMillis(long value) {
105            return value;
106        }
107    
108        public long getMillis(int value, long instant) {
109            return value;
110        }
111    
112        public long getMillis(long value, long instant) {
113            return value;
114        }
115    
116        public long add(long instant, int value) {
117            return FieldUtils.safeAdd(instant, value);
118        }
119    
120        public long add(long instant, long value) {
121            return FieldUtils.safeAdd(instant, value);
122        }
123    
124        public int getDifference(long minuendInstant, long subtrahendInstant) {
125            return FieldUtils.safeToInt(FieldUtils.safeSubtract(minuendInstant, subtrahendInstant));
126        }
127    
128        public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
129            return FieldUtils.safeSubtract(minuendInstant, subtrahendInstant);
130        }
131    
132        //------------------------------------------------------------------------
133        public int compareTo(DurationField otherField) {
134            long otherMillis = otherField.getUnitMillis();
135            long thisMillis = getUnitMillis();
136            // cannot do (thisMillis - otherMillis) as can overflow
137            if (thisMillis == otherMillis) {
138                return 0;
139            }
140            if (thisMillis < otherMillis) {
141                return -1;
142            } else {
143                return 1;
144            }
145        }
146    
147        public boolean equals(Object obj) {
148            if (obj instanceof MillisDurationField) {
149                return getUnitMillis() == ((MillisDurationField) obj).getUnitMillis();
150            }
151            return false;
152        }
153    
154        public int hashCode() {
155            return (int) getUnitMillis();
156        }
157    
158        /**
159         * Get a suitable debug string.
160         * 
161         * @return debug string
162         */
163        public String toString() {
164            return "DurationField[millis]";
165        }
166    
167        /**
168         * Deserialize to the singleton.
169         */
170        private Object readResolve() {
171            return INSTANCE;
172        }
173    
174    }