001 /*
002 * Copyright 2001-2005 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 org.joda.time.DurationFieldType;
019
020 /**
021 * Duration field class representing a field with a fixed unit length.
022 * <p>
023 * PreciseDurationField is thread-safe and immutable.
024 *
025 * @author Stephen Colebourne
026 * @author Brian S O'Neill
027 * @since 1.0
028 */
029 public class PreciseDurationField extends BaseDurationField {
030
031 private static final long serialVersionUID = -8346152187724495365L;
032
033 /** The size of the unit */
034 private final long iUnitMillis;
035
036 /**
037 * Constructor.
038 *
039 * @param type the field type
040 * @param unitMillis the unit milliseconds
041 */
042 public PreciseDurationField(DurationFieldType type, long unitMillis) {
043 super(type);
044 iUnitMillis = unitMillis;
045 }
046
047 //------------------------------------------------------------------------
048 /**
049 * This field is precise.
050 *
051 * @return true always
052 */
053 public final boolean isPrecise() {
054 return true;
055 }
056
057 /**
058 * Returns the amount of milliseconds per unit value of this field.
059 *
060 * @return the unit size of this field, in milliseconds
061 */
062 public final long getUnitMillis() {
063 return iUnitMillis;
064 }
065
066 //------------------------------------------------------------------------
067 /**
068 * Get the value of this field from the milliseconds.
069 *
070 * @param duration the milliseconds to query, which may be negative
071 * @param instant ignored
072 * @return the value of the field, in the units of the field, which may be
073 * negative
074 */
075 public long getValueAsLong(long duration, long instant) {
076 return duration / iUnitMillis; // safe
077 }
078
079 /**
080 * Get the millisecond duration of this field from its value.
081 *
082 * @param value the value of the field, which may be negative
083 * @param instant ignored
084 * @return the milliseconds that the field represents, which may be
085 * negative
086 */
087 public long getMillis(int value, long instant) {
088 return value * iUnitMillis; // safe
089 }
090
091 /**
092 * Get the millisecond duration of this field from its value.
093 *
094 * @param value the value of the field, which may be negative
095 * @param instant ignored
096 * @return the milliseconds that the field represents, which may be
097 * negative
098 */
099 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 }