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