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 */
016package org.joda.time.field;
017
018import java.io.Serializable;
019
020import org.joda.time.DurationField;
021import 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 */
032public 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}