Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTime.java
41159 views
1
/*
2
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file:
31
*
32
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
33
*
34
* All rights reserved.
35
*
36
* Redistribution and use in source and binary forms, with or without
37
* modification, are permitted provided that the following conditions are met:
38
*
39
* * Redistributions of source code must retain the above copyright notice,
40
* this list of conditions and the following disclaimer.
41
*
42
* * Redistributions in binary form must reproduce the above copyright notice,
43
* this list of conditions and the following disclaimer in the documentation
44
* and/or other materials provided with the distribution.
45
*
46
* * Neither the name of JSR-310 nor the names of its contributors
47
* may be used to endorse or promote products derived from this software
48
* without specific prior written permission.
49
*
50
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61
*/
62
package java.time.chrono;
63
64
import static java.time.temporal.ChronoField.EPOCH_DAY;
65
import static java.time.temporal.ChronoField.NANO_OF_DAY;
66
import static java.time.temporal.ChronoUnit.FOREVER;
67
import static java.time.temporal.ChronoUnit.NANOS;
68
69
import java.io.Serializable;
70
import java.time.DateTimeException;
71
import java.time.Instant;
72
import java.time.LocalDateTime;
73
import java.time.LocalTime;
74
import java.time.ZoneId;
75
import java.time.ZoneOffset;
76
import java.time.format.DateTimeFormatter;
77
import java.time.temporal.ChronoField;
78
import java.time.temporal.ChronoUnit;
79
import java.time.temporal.Temporal;
80
import java.time.temporal.TemporalAccessor;
81
import java.time.temporal.TemporalAdjuster;
82
import java.time.temporal.TemporalAmount;
83
import java.time.temporal.TemporalField;
84
import java.time.temporal.TemporalQueries;
85
import java.time.temporal.TemporalQuery;
86
import java.time.temporal.TemporalUnit;
87
import java.time.zone.ZoneRules;
88
import java.util.Comparator;
89
import java.util.Objects;
90
91
/**
92
* A date-time without a time-zone in an arbitrary chronology, intended
93
* for advanced globalization use cases.
94
* <p>
95
* <b>Most applications should declare method signatures, fields and variables
96
* as {@link LocalDateTime}, not this interface.</b>
97
* <p>
98
* A {@code ChronoLocalDateTime} is the abstract representation of a local date-time
99
* where the {@code Chronology chronology}, or calendar system, is pluggable.
100
* The date-time is defined in terms of fields expressed by {@link TemporalField},
101
* where most common implementations are defined in {@link ChronoField}.
102
* The chronology defines how the calendar system operates and the meaning of
103
* the standard fields.
104
*
105
* <h2>When to use this interface</h2>
106
* The design of the API encourages the use of {@code LocalDateTime} rather than this
107
* interface, even in the case where the application needs to deal with multiple
108
* calendar systems. The rationale for this is explored in detail in {@link ChronoLocalDate}.
109
* <p>
110
* Ensure that the discussion in {@code ChronoLocalDate} has been read and understood
111
* before using this interface.
112
*
113
* @implSpec
114
* This interface must be implemented with care to ensure other classes operate correctly.
115
* All implementations that can be instantiated must be final, immutable and thread-safe.
116
* Subclasses should be Serializable wherever possible.
117
*
118
* @param <D> the concrete type for the date of this date-time
119
* @since 1.8
120
*/
121
public interface ChronoLocalDateTime<D extends ChronoLocalDate>
122
extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> {
123
124
/**
125
* Gets a comparator that compares {@code ChronoLocalDateTime} in
126
* time-line order ignoring the chronology.
127
* <p>
128
* This comparator differs from the comparison in {@link #compareTo} in that it
129
* only compares the underlying date-time and not the chronology.
130
* This allows dates in different calendar systems to be compared based
131
* on the position of the date-time on the local time-line.
132
* The underlying comparison is equivalent to comparing the epoch-day and nano-of-day.
133
*
134
* @return a comparator that compares in time-line order ignoring the chronology
135
* @see #isAfter
136
* @see #isBefore
137
* @see #isEqual
138
*/
139
static Comparator<ChronoLocalDateTime<?>> timeLineOrder() {
140
return (Comparator<ChronoLocalDateTime<? extends ChronoLocalDate>> & Serializable) (dateTime1, dateTime2) -> {
141
int cmp = Long.compare(dateTime1.toLocalDate().toEpochDay(), dateTime2.toLocalDate().toEpochDay());
142
if (cmp == 0) {
143
cmp = Long.compare(dateTime1.toLocalTime().toNanoOfDay(), dateTime2.toLocalTime().toNanoOfDay());
144
}
145
return cmp;
146
};
147
}
148
149
//-----------------------------------------------------------------------
150
/**
151
* Obtains an instance of {@code ChronoLocalDateTime} from a temporal object.
152
* <p>
153
* This obtains a local date-time based on the specified temporal.
154
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
155
* which this factory converts to an instance of {@code ChronoLocalDateTime}.
156
* <p>
157
* The conversion extracts and combines the chronology and the date-time
158
* from the temporal object. The behavior is equivalent to using
159
* {@link Chronology#localDateTime(TemporalAccessor)} with the extracted chronology.
160
* Implementations are permitted to perform optimizations such as accessing
161
* those fields that are equivalent to the relevant objects.
162
* <p>
163
* This method matches the signature of the functional interface {@link TemporalQuery}
164
* allowing it to be used as a query via method reference, {@code ChronoLocalDateTime::from}.
165
*
166
* @param temporal the temporal object to convert, not null
167
* @return the date-time, not null
168
* @throws DateTimeException if unable to convert to a {@code ChronoLocalDateTime}
169
* @see Chronology#localDateTime(TemporalAccessor)
170
*/
171
static ChronoLocalDateTime<?> from(TemporalAccessor temporal) {
172
if (temporal instanceof ChronoLocalDateTime) {
173
return (ChronoLocalDateTime<?>) temporal;
174
}
175
Objects.requireNonNull(temporal, "temporal");
176
Chronology chrono = temporal.query(TemporalQueries.chronology());
177
if (chrono == null) {
178
throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass());
179
}
180
return chrono.localDateTime(temporal);
181
}
182
183
//-----------------------------------------------------------------------
184
/**
185
* Gets the chronology of this date-time.
186
* <p>
187
* The {@code Chronology} represents the calendar system in use.
188
* The era and other fields in {@link ChronoField} are defined by the chronology.
189
*
190
* @return the chronology, not null
191
*/
192
default Chronology getChronology() {
193
return toLocalDate().getChronology();
194
}
195
196
/**
197
* Gets the local date part of this date-time.
198
* <p>
199
* This returns a local date with the same year, month and day
200
* as this date-time.
201
*
202
* @return the date part of this date-time, not null
203
*/
204
D toLocalDate();
205
206
/**
207
* Gets the local time part of this date-time.
208
* <p>
209
* This returns a local time with the same hour, minute, second and
210
* nanosecond as this date-time.
211
*
212
* @return the time part of this date-time, not null
213
*/
214
LocalTime toLocalTime();
215
216
/**
217
* Checks if the specified field is supported.
218
* <p>
219
* This checks if the specified field can be queried on this date-time.
220
* If false, then calling the {@link #range(TemporalField) range},
221
* {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}
222
* methods will throw an exception.
223
* <p>
224
* The set of supported fields is defined by the chronology and normally includes
225
* all {@code ChronoField} date and time fields.
226
* <p>
227
* If the field is not a {@code ChronoField}, then the result of this method
228
* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
229
* passing {@code this} as the argument.
230
* Whether the field is supported is determined by the field.
231
*
232
* @param field the field to check, null returns false
233
* @return true if the field can be queried, false if not
234
*/
235
@Override
236
boolean isSupported(TemporalField field);
237
238
/**
239
* Checks if the specified unit is supported.
240
* <p>
241
* This checks if the specified unit can be added to or subtracted from this date-time.
242
* If false, then calling the {@link #plus(long, TemporalUnit)} and
243
* {@link #minus(long, TemporalUnit) minus} methods will throw an exception.
244
* <p>
245
* The set of supported units is defined by the chronology and normally includes
246
* all {@code ChronoUnit} units except {@code FOREVER}.
247
* <p>
248
* If the unit is not a {@code ChronoUnit}, then the result of this method
249
* is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}
250
* passing {@code this} as the argument.
251
* Whether the unit is supported is determined by the unit.
252
*
253
* @param unit the unit to check, null returns false
254
* @return true if the unit can be added/subtracted, false if not
255
*/
256
@Override
257
default boolean isSupported(TemporalUnit unit) {
258
if (unit instanceof ChronoUnit) {
259
return unit != FOREVER;
260
}
261
return unit != null && unit.isSupportedBy(this);
262
}
263
264
//-----------------------------------------------------------------------
265
// override for covariant return type
266
/**
267
* {@inheritDoc}
268
* @throws DateTimeException {@inheritDoc}
269
* @throws ArithmeticException {@inheritDoc}
270
*/
271
@Override
272
default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) {
273
return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
274
}
275
276
/**
277
* {@inheritDoc}
278
* @throws DateTimeException {@inheritDoc}
279
* @throws ArithmeticException {@inheritDoc}
280
*/
281
@Override
282
ChronoLocalDateTime<D> with(TemporalField field, long newValue);
283
284
/**
285
* {@inheritDoc}
286
* @throws DateTimeException {@inheritDoc}
287
* @throws ArithmeticException {@inheritDoc}
288
*/
289
@Override
290
default ChronoLocalDateTime<D> plus(TemporalAmount amount) {
291
return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
292
}
293
294
/**
295
* {@inheritDoc}
296
* @throws DateTimeException {@inheritDoc}
297
* @throws ArithmeticException {@inheritDoc}
298
*/
299
@Override
300
ChronoLocalDateTime<D> plus(long amountToAdd, TemporalUnit unit);
301
302
/**
303
* {@inheritDoc}
304
* @throws DateTimeException {@inheritDoc}
305
* @throws ArithmeticException {@inheritDoc}
306
*/
307
@Override
308
default ChronoLocalDateTime<D> minus(TemporalAmount amount) {
309
return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
310
}
311
312
/**
313
* {@inheritDoc}
314
* @throws DateTimeException {@inheritDoc}
315
* @throws ArithmeticException {@inheritDoc}
316
*/
317
@Override
318
default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
319
return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
320
}
321
322
//-----------------------------------------------------------------------
323
/**
324
* Queries this date-time using the specified query.
325
* <p>
326
* This queries this date-time using the specified query strategy object.
327
* The {@code TemporalQuery} object defines the logic to be used to
328
* obtain the result. Read the documentation of the query to understand
329
* what the result of this method will be.
330
* <p>
331
* The result of this method is obtained by invoking the
332
* {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
333
* specified query passing {@code this} as the argument.
334
*
335
* @param <R> the type of the result
336
* @param query the query to invoke, not null
337
* @return the query result, null may be returned (defined by the query)
338
* @throws DateTimeException if unable to query (defined by the query)
339
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
340
*/
341
@SuppressWarnings("unchecked")
342
@Override
343
default <R> R query(TemporalQuery<R> query) {
344
if (query == TemporalQueries.zoneId() || query == TemporalQueries.zone() || query == TemporalQueries.offset()) {
345
return null;
346
} else if (query == TemporalQueries.localTime()) {
347
return (R) toLocalTime();
348
} else if (query == TemporalQueries.chronology()) {
349
return (R) getChronology();
350
} else if (query == TemporalQueries.precision()) {
351
return (R) NANOS;
352
}
353
// inline TemporalAccessor.super.query(query) as an optimization
354
// non-JDK classes are not permitted to make this optimization
355
return query.queryFrom(this);
356
}
357
358
/**
359
* Adjusts the specified temporal object to have the same date and time as this object.
360
* <p>
361
* This returns a temporal object of the same observable type as the input
362
* with the date and time changed to be the same as this.
363
* <p>
364
* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
365
* twice, passing {@link ChronoField#EPOCH_DAY} and
366
* {@link ChronoField#NANO_OF_DAY} as the fields.
367
* <p>
368
* In most cases, it is clearer to reverse the calling pattern by using
369
* {@link Temporal#with(TemporalAdjuster)}:
370
* <pre>
371
* // these two lines are equivalent, but the second approach is recommended
372
* temporal = thisLocalDateTime.adjustInto(temporal);
373
* temporal = temporal.with(thisLocalDateTime);
374
* </pre>
375
* <p>
376
* This instance is immutable and unaffected by this method call.
377
*
378
* @param temporal the target object to be adjusted, not null
379
* @return the adjusted object, not null
380
* @throws DateTimeException if unable to make the adjustment
381
* @throws ArithmeticException if numeric overflow occurs
382
*/
383
@Override
384
default Temporal adjustInto(Temporal temporal) {
385
return temporal
386
.with(EPOCH_DAY, toLocalDate().toEpochDay())
387
.with(NANO_OF_DAY, toLocalTime().toNanoOfDay());
388
}
389
390
/**
391
* Formats this date-time using the specified formatter.
392
* <p>
393
* This date-time will be passed to the formatter to produce a string.
394
* <p>
395
* The default implementation must behave as follows:
396
* <pre>
397
* return formatter.format(this);
398
* </pre>
399
*
400
* @param formatter the formatter to use, not null
401
* @return the formatted date-time string, not null
402
* @throws DateTimeException if an error occurs during printing
403
*/
404
default String format(DateTimeFormatter formatter) {
405
Objects.requireNonNull(formatter, "formatter");
406
return formatter.format(this);
407
}
408
409
//-----------------------------------------------------------------------
410
/**
411
* Combines this time with a time-zone to create a {@code ChronoZonedDateTime}.
412
* <p>
413
* This returns a {@code ChronoZonedDateTime} formed from this date-time at the
414
* specified time-zone. The result will match this date-time as closely as possible.
415
* Time-zone rules, such as daylight savings, mean that not every local date-time
416
* is valid for the specified zone, thus the local date-time may be adjusted.
417
* <p>
418
* The local date-time is resolved to a single instant on the time-line.
419
* This is achieved by finding a valid offset from UTC/Greenwich for the local
420
* date-time as defined by the {@link ZoneRules rules} of the zone ID.
421
*<p>
422
* In most cases, there is only one valid offset for a local date-time.
423
* In the case of an overlap, where clocks are set back, there are two valid offsets.
424
* This method uses the earlier offset typically corresponding to "summer".
425
* <p>
426
* In the case of a gap, where clocks jump forward, there is no valid offset.
427
* Instead, the local date-time is adjusted to be later by the length of the gap.
428
* For a typical one hour daylight savings change, the local date-time will be
429
* moved one hour later into the offset typically corresponding to "summer".
430
* <p>
431
* To obtain the later offset during an overlap, call
432
* {@link ChronoZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method.
433
*
434
* @param zone the time-zone to use, not null
435
* @return the zoned date-time formed from this date-time, not null
436
*/
437
ChronoZonedDateTime<D> atZone(ZoneId zone);
438
439
//-----------------------------------------------------------------------
440
/**
441
* Converts this date-time to an {@code Instant}.
442
* <p>
443
* This combines this local date-time and the specified offset to form
444
* an {@code Instant}.
445
* <p>
446
* This default implementation calculates from the epoch-day of the date and the
447
* second-of-day of the time.
448
*
449
* @param offset the offset to use for the conversion, not null
450
* @return an {@code Instant} representing the same instant, not null
451
*/
452
default Instant toInstant(ZoneOffset offset) {
453
return Instant.ofEpochSecond(toEpochSecond(offset), toLocalTime().getNano());
454
}
455
456
/**
457
* Converts this date-time to the number of seconds from the epoch
458
* of 1970-01-01T00:00:00Z.
459
* <p>
460
* This combines this local date-time and the specified offset to calculate the
461
* epoch-second value, which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
462
* Instants on the time-line after the epoch are positive, earlier are negative.
463
* <p>
464
* This default implementation calculates from the epoch-day of the date and the
465
* second-of-day of the time.
466
*
467
* @param offset the offset to use for the conversion, not null
468
* @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
469
*/
470
default long toEpochSecond(ZoneOffset offset) {
471
Objects.requireNonNull(offset, "offset");
472
long epochDay = toLocalDate().toEpochDay();
473
long secs = epochDay * 86400 + toLocalTime().toSecondOfDay();
474
secs -= offset.getTotalSeconds();
475
return secs;
476
}
477
478
//-----------------------------------------------------------------------
479
/**
480
* Compares this date-time to another date-time, including the chronology.
481
* <p>
482
* The comparison is based first on the underlying time-line date-time, then
483
* on the chronology.
484
* It is "consistent with equals", as defined by {@link Comparable}.
485
* <p>
486
* For example, the following is the comparator order:
487
* <ol>
488
* <li>{@code 2012-12-03T12:00 (ISO)}</li>
489
* <li>{@code 2012-12-04T12:00 (ISO)}</li>
490
* <li>{@code 2555-12-04T12:00 (ThaiBuddhist)}</li>
491
* <li>{@code 2012-12-05T12:00 (ISO)}</li>
492
* </ol>
493
* Values #2 and #3 represent the same date-time on the time-line.
494
* When two values represent the same date-time, the chronology ID is compared to distinguish them.
495
* This step is needed to make the ordering "consistent with equals".
496
* <p>
497
* If all the date-time objects being compared are in the same chronology, then the
498
* additional chronology stage is not required and only the local date-time is used.
499
* <p>
500
* This default implementation performs the comparison defined above.
501
*
502
* @param other the other date-time to compare to, not null
503
* @return the comparator value, negative if less, positive if greater
504
*/
505
@Override
506
default int compareTo(ChronoLocalDateTime<?> other) {
507
int cmp = toLocalDate().compareTo(other.toLocalDate());
508
if (cmp == 0) {
509
cmp = toLocalTime().compareTo(other.toLocalTime());
510
if (cmp == 0) {
511
cmp = getChronology().compareTo(other.getChronology());
512
}
513
}
514
return cmp;
515
}
516
517
/**
518
* Checks if this date-time is after the specified date-time ignoring the chronology.
519
* <p>
520
* This method differs from the comparison in {@link #compareTo} in that it
521
* only compares the underlying date-time and not the chronology.
522
* This allows dates in different calendar systems to be compared based
523
* on the time-line position.
524
* <p>
525
* This default implementation performs the comparison based on the epoch-day
526
* and nano-of-day.
527
*
528
* @param other the other date-time to compare to, not null
529
* @return true if this is after the specified date-time
530
*/
531
default boolean isAfter(ChronoLocalDateTime<?> other) {
532
long thisEpDay = this.toLocalDate().toEpochDay();
533
long otherEpDay = other.toLocalDate().toEpochDay();
534
return thisEpDay > otherEpDay ||
535
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() > other.toLocalTime().toNanoOfDay());
536
}
537
538
/**
539
* Checks if this date-time is before the specified date-time ignoring the chronology.
540
* <p>
541
* This method differs from the comparison in {@link #compareTo} in that it
542
* only compares the underlying date-time and not the chronology.
543
* This allows dates in different calendar systems to be compared based
544
* on the time-line position.
545
* <p>
546
* This default implementation performs the comparison based on the epoch-day
547
* and nano-of-day.
548
*
549
* @param other the other date-time to compare to, not null
550
* @return true if this is before the specified date-time
551
*/
552
default boolean isBefore(ChronoLocalDateTime<?> other) {
553
long thisEpDay = this.toLocalDate().toEpochDay();
554
long otherEpDay = other.toLocalDate().toEpochDay();
555
return thisEpDay < otherEpDay ||
556
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() < other.toLocalTime().toNanoOfDay());
557
}
558
559
/**
560
* Checks if this date-time is equal to the specified date-time ignoring the chronology.
561
* <p>
562
* This method differs from the comparison in {@link #compareTo} in that it
563
* only compares the underlying date and time and not the chronology.
564
* This allows date-times in different calendar systems to be compared based
565
* on the time-line position.
566
* <p>
567
* This default implementation performs the comparison based on the epoch-day
568
* and nano-of-day.
569
*
570
* @param other the other date-time to compare to, not null
571
* @return true if the underlying date-time is equal to the specified date-time on the timeline
572
*/
573
default boolean isEqual(ChronoLocalDateTime<?> other) {
574
// Do the time check first, it is cheaper than computing EPOCH day.
575
return this.toLocalTime().toNanoOfDay() == other.toLocalTime().toNanoOfDay() &&
576
this.toLocalDate().toEpochDay() == other.toLocalDate().toEpochDay();
577
}
578
579
/**
580
* Checks if this date-time is equal to another date-time, including the chronology.
581
* <p>
582
* Compares this date-time with another ensuring that the date-time and chronology are the same.
583
*
584
* @param obj the object to check, null returns false
585
* @return true if this is equal to the other date
586
*/
587
@Override
588
boolean equals(Object obj);
589
590
/**
591
* A hash code for this date-time.
592
*
593
* @return a suitable hash code
594
*/
595
@Override
596
int hashCode();
597
598
//-----------------------------------------------------------------------
599
/**
600
* Outputs this date-time as a {@code String}.
601
* <p>
602
* The output will include the full local date-time.
603
*
604
* @return a string representation of this date-time, not null
605
*/
606
@Override
607
String toString();
608
609
}
610
611