1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.joda.time.field;
17
18 import org.joda.time.DateTimeFieldType;
19 import org.joda.time.DurationField;
20 import org.joda.time.DurationFieldType;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public abstract class ImpreciseDateTimeField extends BaseDateTimeField {
42
43 private static final long serialVersionUID = 7190739608550251860L;
44
45 final long iUnitMillis;
46 private final DurationField iDurationField;
47
48
49
50
51
52
53
54 public ImpreciseDateTimeField(DateTimeFieldType type, long unitMillis) {
55 super(type);
56 iUnitMillis = unitMillis;
57 iDurationField = new LinkedDurationField(type.getDurationType());
58 }
59
60 public abstract int get(long instant);
61
62 public abstract long set(long instant, int value);
63
64 public abstract long add(long instant, int value);
65
66 public abstract long add(long instant, long value);
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public int getDifference(long minuendInstant, long subtrahendInstant) {
91 return FieldUtils.safeToInt(getDifferenceAsLong(minuendInstant, subtrahendInstant));
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
118 if (minuendInstant < subtrahendInstant) {
119 return -getDifferenceAsLong(subtrahendInstant, minuendInstant);
120 }
121
122 long difference = (minuendInstant - subtrahendInstant) / iUnitMillis;
123 if (add(subtrahendInstant, difference) < minuendInstant) {
124 do {
125 difference++;
126 } while (add(subtrahendInstant, difference) <= minuendInstant);
127 difference--;
128 } else if (add(subtrahendInstant, difference) > minuendInstant) {
129 do {
130 difference--;
131 } while (add(subtrahendInstant, difference) > minuendInstant);
132 }
133 return difference;
134 }
135
136 public final DurationField getDurationField() {
137 return iDurationField;
138 }
139
140 public abstract DurationField getRangeDurationField();
141
142 public abstract long roundFloor(long instant);
143
144 protected final long getDurationUnitMillis() {
145 return iUnitMillis;
146 }
147
148 private final class LinkedDurationField extends BaseDurationField {
149 private static final long serialVersionUID = -203813474600094134L;
150
151 LinkedDurationField(DurationFieldType type) {
152 super(type);
153 }
154
155 public boolean isPrecise() {
156 return false;
157 }
158
159 public long getUnitMillis() {
160 return iUnitMillis;
161 }
162
163 public int getValue(long duration, long instant) {
164 return ImpreciseDateTimeField.this
165 .getDifference(instant + duration, instant);
166 }
167
168 public long getValueAsLong(long duration, long instant) {
169 return ImpreciseDateTimeField.this
170 .getDifferenceAsLong(instant + duration, instant);
171 }
172
173 public long getMillis(int value, long instant) {
174 return ImpreciseDateTimeField.this.add(instant, value) - instant;
175 }
176
177 public long getMillis(long value, long instant) {
178 return ImpreciseDateTimeField.this.add(instant, value) - instant;
179 }
180
181 public long add(long instant, int value) {
182 return ImpreciseDateTimeField.this.add(instant, value);
183 }
184
185 public long add(long instant, long value) {
186 return ImpreciseDateTimeField.this.add(instant, value);
187 }
188
189 public int getDifference(long minuendInstant, long subtrahendInstant) {
190 return ImpreciseDateTimeField.this
191 .getDifference(minuendInstant, subtrahendInstant);
192 }
193
194 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
195 return ImpreciseDateTimeField.this
196 .getDifferenceAsLong(minuendInstant, subtrahendInstant);
197 }
198 }
199
200 }