-
Notifications
You must be signed in to change notification settings - Fork 670
/
Copy pathChronoPeriod.java
441 lines (400 loc) · 19.1 KB
/
ChronoPeriod.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package java.time.chrono;
import java.time.DateTimeException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.util.List;
import java.util.Objects;
/**
* A date-based amount of time, such as '3 years, 4 months and 5 days' in an
* arbitrary chronology, intended for advanced globalization use cases.
* <p>
* This interface models a date-based amount of time in a calendar system.
* While most calendar systems use years, months and days, some do not.
* Therefore, this interface operates solely in terms of a set of supported
* units that are defined by the {@code Chronology}.
* The set of supported units is fixed for a given chronology.
* The amount of a supported unit may be set to zero.
* <p>
* The period is modeled as a directed amount of time, meaning that individual
* parts of the period may be negative.
*
* @implSpec This interface must be implemented with care to ensure other classes operate correctly.
* All implementations that can be instantiated must be final, immutable and thread-safe.
* Subclasses should be Serializable wherever possible.
* @since 1.8
*/
// 时间段,包含年/月/日部件,精确到天;允许在子类中将"日期"部件绑定到某种历法系统
public interface ChronoPeriod extends TemporalAmount {
/*▼ 部件 ████████████████████████████████████████████████████████████████████████████████┓ */
/**
* Checks if all the supported units of this period are zero.
*
* @return true if this period is zero-length
*/
// 判断当前"时间段"的值是否为0,即该"时间段"内所有计时部件的值为0
default boolean isZero() {
for(TemporalUnit unit : getUnits()) {
if(get(unit) != 0) {
return false;
}
}
return true;
}
/**
* Gets the chronology that defines the meaning of the supported units.
* <p>
* The period is defined by the chronology.
* It controls the supported units and restricts addition/subtraction
* to {@code ChronoLocalDate} instances of the same chronology.
*
* @return the chronology defining the period, not null
*/
// 返回当前"时间段"采用的历法系统
Chronology getChronology();
/*▲ 部件 ████████████████████████████████████████████████████████████████████████████████┛ */
/*▼ 基本运算 ████████████████████████████████████████████████████████████████████████████████┓ */
/**
* Returns a copy of this period with the specified period added.
* <p>
* If the specified amount is a {@code ChronoPeriod} then it must have
* the same chronology as this period. Implementations may choose to
* accept or reject other {@code TemporalAmount} implementations.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToAdd the period to add, not null
*
* @return a {@code ChronoPeriod} based on this period with the requested period added, not null
*
* @throws ArithmeticException if numeric overflow occurs
*/
/*
* 对当前"时间段"的值与参数中的"时间段"求和
*
* 如果求和后的值与当前"时间段"的值相等,则直接返回当前"时间段"对象。
* 否则,需要构造"求和"后的新对象再返回。
*/
ChronoPeriod plus(TemporalAmount amountToAdd);
/**
* Returns a copy of this period with the specified period subtracted.
* <p>
* If the specified amount is a {@code ChronoPeriod} then it must have
* the same chronology as this period. Implementations may choose to
* accept or reject other {@code TemporalAmount} implementations.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToSubtract the period to subtract, not null
*
* @return a {@code ChronoPeriod} based on this period with the requested period subtracted, not null
*
* @throws ArithmeticException if numeric overflow occurs
*/
/*
* 对当前"时间段"的值与参数中的"时间段"求差
*
* 如果求差后的值与当前"时间段"的值相等,则直接返回当前"时间段"对象。
* 否则,需要构造"求差"后的新对象再返回。
*/
ChronoPeriod minus(TemporalAmount amountToSubtract);
/**
* Returns a new instance with each amount in this period in this period
* multiplied by the specified scalar.
* <p>
* This returns a period with each supported unit individually multiplied.
* For example, a period of "2 years, -3 months and 4 days" multiplied by
* 3 will return "6 years, -9 months and 12 days".
* No normalization is performed.
*
* @param scalar the scalar to multiply by, not null
*
* @return a {@code ChronoPeriod} based on this period with the amounts multiplied
* by the scalar, not null
*
* @throws ArithmeticException if numeric overflow occurs
*/
/*
* 在当前"时间段"的值上乘以scalar(即放大scalar倍)
*
* 如果乘以后的值与当前"时间段"的值相等,则直接返回当前"时间段"对象。
* 否则,需要构造"乘以"操作后的新对象再返回。
*/
ChronoPeriod multipliedBy(int scalar);
/**
* Returns a new instance with each amount in this period negated.
* <p>
* This returns a period with each supported unit individually negated.
* For example, a period of "2 years, -3 months and 4 days" will be
* negated to "-2 years, 3 months and -4 days".
* No normalization is performed.
*
* @return a {@code ChronoPeriod} based on this period with the amounts negated, not null
*
* @throws ArithmeticException if numeric overflow occurs, which only happens if
* one of the units has the value {@code Long.MIN_VALUE}
*/
// 取相反数
default ChronoPeriod negated() {
return multipliedBy(-1);
}
/**
* Checks if any of the supported units of this period are negative.
*
* @return true if any unit of this period is negative
*/
// 判断当前"时间段"是否为负
default boolean isNegative() {
for(TemporalUnit unit : getUnits()) {
if(get(unit)<0) {
return true;
}
}
return false;
}
/*▲ 基本运算 ████████████████████████████████████████████████████████████████████████████████┛ */
/*▼ 增加/减少 ████████████████████████████████████████████████████████████████████████████████┓ */
/**
* Adds this period to the specified temporal object.
* <p>
* This returns a temporal object of the same observable type as the input
* with this period added.
* <p>
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#plus(TemporalAmount)}.
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = thisPeriod.addTo(dateTime);
* dateTime = dateTime.plus(thisPeriod);
* </pre>
* <p>
* The specified temporal must have the same chronology as this period.
* This returns a temporal with the non-zero supported units added.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param temporal the temporal object to adjust, not null
*
* @return an object of the same type with the adjustment made, not null
*
* @throws DateTimeException if unable to add
* @throws ArithmeticException if numeric overflow occurs
*/
/*
* 增加目标时间量temporal
*
* 尝试将当前"时间段"累加到指定的时间量temporal上,
* 如果累加后的值与原值相同,则返回temporal自身;否则,会构造一个新对象再返回。
*/
@Override
Temporal addTo(Temporal temporal);
/**
* Subtracts this period from the specified temporal object.
* <p>
* This returns a temporal object of the same observable type as the input
* with this period subtracted.
* <p>
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#minus(TemporalAmount)}.
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = thisPeriod.subtractFrom(dateTime);
* dateTime = dateTime.minus(thisPeriod);
* </pre>
* <p>
* The specified temporal must have the same chronology as this period.
* This returns a temporal with the non-zero supported units subtracted.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param temporal the temporal object to adjust, not null
*
* @return an object of the same type with the adjustment made, not null
*
* @throws DateTimeException if unable to subtract
* @throws ArithmeticException if numeric overflow occurs
*/
/*
* 减少目标时间量temporal
*
* 尝试从指定的时间量temporal上减去当前"时间段",
* 如果减少后的值与原值相同,则返回temporal自身;否则,会构造一个新对象再返回。
*/
@Override
Temporal subtractFrom(Temporal temporal);
/*▲ 增加/减少 ████████████████████████████████████████████████████████████████████████████████┛ */
/*▼ 时间量单位 ████████████████████████████████████████████████████████████████████████████████┓ */
/**
* Gets the set of units supported by this period.
* <p>
* The supported units are chronology specific.
* They will typically be {@link ChronoUnit#YEARS YEARS},
* {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
* They are returned in order from largest to smallest.
* <p>
* This set can be used in conjunction with {@link #get(TemporalUnit)}
* to access the entire state of the period.
*
* @return a list containing the supported units, not null
*/
// 返回当前"时间段"上可用的时间量单位,这其实是该"时间段"的组成部件
@Override
List<TemporalUnit> getUnits();
/**
* Gets the value of the requested unit.
* <p>
* The supported units are chronology specific.
* They will typically be {@link ChronoUnit#YEARS YEARS},
* {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
* Requesting an unsupported unit will throw an exception.
*
* @param unit the {@code TemporalUnit} for which to return the value
*
* @return the long value of the unit
*
* @throws DateTimeException if the unit is not supported
* @throws UnsupportedTemporalTypeException if the unit is not supported
*/
// 返回当前"时间段"中指定的时间量单位unit对应的时间量数值
@Override
long get(TemporalUnit unit);
/*▲ 时间量单位 ████████████████████████████████████████████████████████████████████████████████┛ */
/*▼ 杂项 ████████████████████████████████████████████████████████████████████████████████┓ */
/**
* Obtains a {@code ChronoPeriod} consisting of amount of time between two dates.
* <p>
* The start date is included, but the end date is not.
* The period is calculated using {@link ChronoLocalDate#until(ChronoLocalDate)}.
* As such, the calculation is chronology specific.
* <p>
* The chronology of the first date is used.
* The chronology of the second date is ignored, with the date being converted
* to the target chronology system before the calculation starts.
* <p>
* The result of this method can be a negative period if the end is before the start.
* In most cases, the positive/negative sign will be the same in each of the supported fields.
*
* @param startDateInclusive the start date, inclusive, specifying the chronology of the calculation, not null
* @param endDateExclusive the end date, exclusive, in any chronology, not null
*
* @return the period between this date and the end date, not null
*
* @see ChronoLocalDate#until(ChronoLocalDate)
*/
// 计算两个时间量之间相差多少个"时间段"
static ChronoPeriod between(ChronoLocalDate startDateInclusive, ChronoLocalDate endDateExclusive) {
Objects.requireNonNull(startDateInclusive, "startDateInclusive");
Objects.requireNonNull(endDateExclusive, "endDateExclusive");
return startDateInclusive.until(endDateExclusive);
}
/**
* Returns a copy of this period with the amounts of each unit normalized.
* <p>
* The process of normalization is specific to each calendar system.
* For example, in the ISO calendar system, the years and months are
* normalized but the days are not, such that "15 months" would be
* normalized to "1 year and 3 months".
* <p>
* This instance is immutable and unaffected by this method call.
*
* @return a {@code ChronoPeriod} based on this period with the amounts of each
* unit normalized, not null
*
* @throws ArithmeticException if numeric overflow occurs
*/
// 返回当前"时间段"的一个规范表示:即先从比较大的单位开始填充数据
ChronoPeriod normalized();
/*▲ 杂项 ████████████████████████████████████████████████████████████████████████████████┛ */
/**
* Outputs this period as a {@code String}.
* <p>
* The output will include the period amounts and chronology.
*
* @return a string representation of this period, not null
*/
@Override
String toString();
/**
* Checks if this period is equal to another period, including the chronology.
* <p>
* Compares this period with another ensuring that the type, each amount and
* the chronology are the same.
* Note that this means that a period of "15 Months" is not equal to a period
* of "1 Year and 3 Months".
*
* @param obj the object to check, null returns false
*
* @return true if this is equal to the other period
*/
@Override
boolean equals(Object obj);
/**
* A hash code for this period.
*
* @return a suitable hash code
*/
@Override
int hashCode();
}