1 /*
2  *  Copyright 2001-2005 Stephen Colebourne
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */

16 package org.joda.time.field;
17
18 import org.joda.time.DurationFieldType;
19
20 /**
21  * Duration field class representing a field with a fixed unit length.
22  * <p>
23  * PreciseDurationField is thread-safe and immutable.
24  * 
25  * @author Stephen Colebourne
26  * @author Brian S O'Neill
27  * @since 1.0
28  */

29 public class PreciseDurationField extends BaseDurationField {
30     
31     private static final long serialVersionUID = -8346152187724495365L;
32
33     /** The size of the unit */
34     private final long iUnitMillis;
35
36     /**
37      * Constructor.
38      * 
39      * @param type  the field type
40      * @param unitMillis  the unit milliseconds
41      */
    
42     public PreciseDurationField(DurationFieldType type, long unitMillis) {
43         super(type);
44         iUnitMillis = unitMillis;
45     }
46     
47     //------------------------------------------------------------------------
48     /**
49      * This field is precise.
50      * 
51      * @return true always
52      */

53     public final boolean isPrecise() {
54         return true;
55     }
56     
57     /**
58      * Returns the amount of milliseconds per unit value of this field.
59      *
60      * @return the unit size of this field, in milliseconds
61      */

62     public final long getUnitMillis() {
63         return iUnitMillis;
64     }
65
66     //------------------------------------------------------------------------
67     /**
68      * Get the value of this field from the milliseconds.
69      * 
70      * @param duration  the milliseconds to query, which may be negative
71      * @param instant  ignored
72      * @return the value of the field, in the units of the field, which may be
73      * negative
74      */

75     public long getValueAsLong(long duration, long instant) {
76         return duration / iUnitMillis;  // safe
77     }
78
79     /**
80      * Get the millisecond duration of this field from its value.
81      * 
82      * @param value  the value of the field, which may be negative
83      * @param instant  ignored
84      * @return the milliseconds that the field represents, which may be
85      * negative
86      */

87     public long getMillis(int value, long instant) {
88         return value * iUnitMillis;  // safe
89     }
90
91     /**
92      * Get the millisecond duration of this field from its value.
93      * 
94      * @param value  the value of the field, which may be negative
95      * @param instant  ignored
96      * @return the milliseconds that the field represents, which may be
97      * negative
98      */

99     public long getMillis(long value, long instant) {
100         return FieldUtils.safeMultiply(value, iUnitMillis);
101     }
102
103     public long add(long instant, int value) {
104         long addition = value * iUnitMillis;  // safe
105         return FieldUtils.safeAdd(instant, addition);
106     }
107
108     public long add(long instant, long value) {
109         long addition = FieldUtils.safeMultiply(value, iUnitMillis);
110         return FieldUtils.safeAdd(instant, addition);
111     }
112
113     public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
114         long difference = FieldUtils.safeSubtract(minuendInstant, subtrahendInstant);
115         return difference / iUnitMillis;
116     }
117
118     //-----------------------------------------------------------------------
119     /**
120      * Compares this duration field to another.
121      * Two fields are equal if of the same type and duration.
122      * 
123      * @param obj  the object to compare to
124      * @return if equal
125      */

126     public boolean equals(Object obj) {
127         if (this == obj) {
128             return true;
129         } else if (obj instanceof PreciseDurationField) {
130             PreciseDurationField other = (PreciseDurationField) obj;
131             return (getType() == other.getType()) && (iUnitMillis == other.iUnitMillis);
132         }
133         return false;
134     }
135
136     /**
137      * Gets a hash code for this instance.
138      * 
139      * @return a suitable hashcode
140      */

141     public int hashCode() {
142         long millis = iUnitMillis;
143         int hash = (int) (millis ^ (millis >>> 32));
144         hash += getType().hashCode();
145         return hash;
146     }
147
148 }
149