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.DurationField;
019 import org.joda.time.DurationFieldType;
020
021 /**
022 * Scales a DurationField such that it's unit millis becomes larger in
023 * magnitude.
024 * <p>
025 * ScaledDurationField is thread-safe and immutable.
026 *
027 * @see PreciseDurationField
028 *
029 * @author Brian S O'Neill
030 * @since 1.0
031 */
032 public class ScaledDurationField extends DecoratedDurationField {
033
034 private static final long serialVersionUID = -3205227092378684157L;
035
036 private final int iScalar;
037
038 /**
039 * Constructor
040 *
041 * @param field the field to wrap, like "year()".
042 * @param type the type this field will actually use
043 * @param scalar scalar, such as 100 years in a century
044 * @throws IllegalArgumentException if scalar is zero or one.
045 */
046 public ScaledDurationField(DurationField field, DurationFieldType type, int scalar) {
047 super(field, type);
048 if (scalar == 0 || scalar == 1) {
049 throw new IllegalArgumentException("The scalar must not be 0 or 1");
050 }
051 iScalar = scalar;
052 }
053
054 public int getValue(long duration) {
055 return getWrappedField().getValue(duration) / iScalar;
056 }
057
058 public long getValueAsLong(long duration) {
059 return getWrappedField().getValueAsLong(duration) / iScalar;
060 }
061
062 public int getValue(long duration, long instant) {
063 return getWrappedField().getValue(duration, instant) / iScalar;
064 }
065
066 public long getValueAsLong(long duration, long instant) {
067 return getWrappedField().getValueAsLong(duration, instant) / iScalar;
068 }
069
070 public long getMillis(int value) {
071 long scaled = ((long) value) * ((long) iScalar);
072 return getWrappedField().getMillis(scaled);
073 }
074
075 public long getMillis(long value) {
076 long scaled = FieldUtils.safeMultiply(value, iScalar);
077 return getWrappedField().getMillis(scaled);
078 }
079
080 public long getMillis(int value, long instant) {
081 long scaled = ((long) value) * ((long) iScalar);
082 return getWrappedField().getMillis(scaled, instant);
083 }
084
085 public long getMillis(long value, long instant) {
086 long scaled = FieldUtils.safeMultiply(value, iScalar);
087 return getWrappedField().getMillis(scaled, instant);
088 }
089
090 public long add(long instant, int value) {
091 long scaled = ((long) value) * ((long) iScalar);
092 return getWrappedField().add(instant, scaled);
093 }
094
095 public long add(long instant, long value) {
096 long scaled = FieldUtils.safeMultiply(value, iScalar);
097 return getWrappedField().add(instant, scaled);
098 }
099
100 public int getDifference(long minuendInstant, long subtrahendInstant) {
101 return getWrappedField().getDifference(minuendInstant, subtrahendInstant) / iScalar;
102 }
103
104 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
105 return getWrappedField().getDifferenceAsLong(minuendInstant, subtrahendInstant) / iScalar;
106 }
107
108 public long getUnitMillis() {
109 return getWrappedField().getUnitMillis() * iScalar;
110 }
111
112 //-----------------------------------------------------------------------
113 /**
114 * Returns the scalar applied, in the field's units.
115 *
116 * @return the scalar
117 */
118 public int getScalar() {
119 return iScalar;
120 }
121
122 /**
123 * Compares this duration field to another.
124 * Two fields are equal if of the same type and duration.
125 *
126 * @param obj the object to compare to
127 * @return if equal
128 */
129 public boolean equals(Object obj) {
130 if (this == obj) {
131 return true;
132 } else if (obj instanceof ScaledDurationField) {
133 ScaledDurationField other = (ScaledDurationField) obj;
134 return (getWrappedField().equals(other.getWrappedField())) &&
135 (getType() == other.getType()) &&
136 (iScalar == other.iScalar);
137 }
138 return false;
139 }
140
141 /**
142 * Gets a hash code for this instance.
143 *
144 * @return a suitable hashcode
145 */
146 public int hashCode() {
147 long scalar = iScalar;
148 int hash = (int) (scalar ^ (scalar >>> 32));
149 hash += getType().hashCode();
150 hash += getWrappedField().hashCode();
151 return hash;
152 }
153
154 }