001/* 002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos 003 * 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions are met: 008 * 009 * * Redistributions of source code must retain the above copyright notice, 010 * this list of conditions and the following disclaimer. 011 * 012 * * Redistributions in binary form must reproduce the above copyright notice, 013 * this list of conditions and the following disclaimer in the documentation 014 * and/or other materials provided with the distribution. 015 * 016 * * Neither the name of JSR-310 nor the names of its contributors 017 * may be used to endorse or promote products derived from this software 018 * without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 */ 032package org.threeten.bp; 033 034import static org.threeten.bp.LocalTime.HOURS_PER_DAY; 035import static org.threeten.bp.LocalTime.MICROS_PER_DAY; 036import static org.threeten.bp.LocalTime.MILLIS_PER_DAY; 037import static org.threeten.bp.LocalTime.MINUTES_PER_DAY; 038import static org.threeten.bp.LocalTime.NANOS_PER_DAY; 039import static org.threeten.bp.LocalTime.NANOS_PER_HOUR; 040import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE; 041import static org.threeten.bp.LocalTime.NANOS_PER_SECOND; 042import static org.threeten.bp.LocalTime.SECONDS_PER_DAY; 043 044import java.io.DataInput; 045import java.io.DataOutput; 046import java.io.IOException; 047import java.io.InvalidObjectException; 048import java.io.ObjectStreamException; 049import java.io.Serializable; 050import java.util.Objects; 051 052import org.threeten.bp.format.DateTimeFormatter; 053import org.threeten.bp.format.DateTimeFormatters; 054import org.threeten.bp.format.DateTimeParseException; 055import org.threeten.bp.jdk8.DefaultInterfaceChronoLocalDateTime; 056import org.threeten.bp.jdk8.Jdk8Methods; 057import org.threeten.bp.temporal.ChronoField; 058import org.threeten.bp.temporal.ChronoLocalDateTime; 059import org.threeten.bp.temporal.ChronoUnit; 060import org.threeten.bp.temporal.ISOChrono; 061import org.threeten.bp.temporal.Temporal; 062import org.threeten.bp.temporal.TemporalAccessor; 063import org.threeten.bp.temporal.TemporalAdder; 064import org.threeten.bp.temporal.TemporalAdjuster; 065import org.threeten.bp.temporal.TemporalAdjusters; 066import org.threeten.bp.temporal.TemporalField; 067import org.threeten.bp.temporal.TemporalQuery; 068import org.threeten.bp.temporal.TemporalSubtractor; 069import org.threeten.bp.temporal.TemporalUnit; 070import org.threeten.bp.temporal.ValueRange; 071import org.threeten.bp.zone.ZoneRules; 072 073/** 074 * A date-time without a time-zone in the ISO-8601 calendar system, 075 * such as {@code 2007-12-03T10:15:30}. 076 * <p> 077 * {@code LocalDateTime} is an immutable date-time object that represents a date-time, 078 * often viewed as year-month-day-hour-minute-second. Other date and time fields, 079 * such as day-of-year, day-of-week and week-of-year, can also be accessed. 080 * Time is represented to nanosecond precision. 081 * For example, the value "2nd October 2007 at 13:45.30.123456789" can be 082 * stored in a {@code LocalDateTime}. 083 * <p> 084 * This class does not store or represent a time-zone. 085 * Instead, it is a description of the date, as used for birthdays, combined with 086 * the local time as seen on a wall clock. 087 * It cannot represent an instant on the time-line without additional information 088 * such as an offset or time-zone. 089 * <p> 090 * The ISO-8601 calendar system is the modern civil calendar system used today 091 * in most of the world. It is equivalent to the proleptic Gregorian calendar 092 * system, in which today's rules for leap years are applied for all time. 093 * For most applications written today, the ISO-8601 rules are entirely suitable. 094 * However, any application that makes use of historical dates, and requires them 095 * to be accurate will find the ISO-8601 approach unsuitable. 096 * 097 * <h3>Specification for implementors</h3> 098 * This class is immutable and thread-safe. 099 */ 100public final class LocalDateTime 101 extends DefaultInterfaceChronoLocalDateTime<ISOChrono> 102 implements Temporal, TemporalAdjuster, ChronoLocalDateTime<ISOChrono>, Serializable { 103 104 /** 105 * The minimum supported {@code LocalDateTime}, '-999999999-01-01T00:00:00'. 106 * This is the local date-time of midnight at the start of the minimum date. 107 * This combines {@link LocalDate#MIN} and {@link LocalTime#MIN}. 108 * This could be used by an application as a "far past" date-time. 109 */ 110 public static final LocalDateTime MIN = LocalDateTime.of(LocalDate.MIN, LocalTime.MIN); 111 /** 112 * The maximum supported {@code LocalDateTime}, '+999999999-12-31T23:59:59.999999999'. 113 * This is the local date-time just before midnight at the end of the maximum date. 114 * This combines {@link LocalDate#MAX} and {@link LocalTime#MAX}. 115 * This could be used by an application as a "far future" date-time. 116 */ 117 public static final LocalDateTime MAX = LocalDateTime.of(LocalDate.MAX, LocalTime.MAX); 118 119 /** 120 * Serialization version. 121 */ 122 private static final long serialVersionUID = 6207766400415563566L; 123 124 /** 125 * The date part. 126 */ 127 private final LocalDate date; 128 /** 129 * The time part. 130 */ 131 private final LocalTime time; 132 133 //----------------------------------------------------------------------- 134 /** 135 * Obtains the current date-time from the system clock in the default time-zone. 136 * <p> 137 * This will query the {@link Clock#systemDefaultZone() system clock} in the default 138 * time-zone to obtain the current date-time. 139 * <p> 140 * Using this method will prevent the ability to use an alternate clock for testing 141 * because the clock is hard-coded. 142 * 143 * @return the current date-time using the system clock and default time-zone, not null 144 */ 145 public static LocalDateTime now() { 146 return now(Clock.systemDefaultZone()); 147 } 148 149 /** 150 * Obtains the current date-time from the system clock in the specified time-zone. 151 * <p> 152 * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date-time. 153 * Specifying the time-zone avoids dependence on the default time-zone. 154 * <p> 155 * Using this method will prevent the ability to use an alternate clock for testing 156 * because the clock is hard-coded. 157 * 158 * @param zone the zone ID to use, not null 159 * @return the current date-time using the system clock, not null 160 */ 161 public static LocalDateTime now(ZoneId zone) { 162 return now(Clock.system(zone)); 163 } 164 165 /** 166 * Obtains the current date-time from the specified clock. 167 * <p> 168 * This will query the specified clock to obtain the current date-time. 169 * Using this method allows the use of an alternate clock for testing. 170 * The alternate clock may be introduced using {@link Clock dependency injection}. 171 * 172 * @param clock the clock to use, not null 173 * @return the current date-time, not null 174 */ 175 public static LocalDateTime now(Clock clock) { 176 Objects.requireNonNull(clock, "clock"); 177 final Instant now = clock.instant(); // called once 178 ZoneOffset offset = clock.getZone().getRules().getOffset(now); 179 return ofEpochSecond(now.getEpochSecond(), now.getNano(), offset); 180 } 181 182 //----------------------------------------------------------------------- 183 /** 184 * Obtains an instance of {@code LocalDateTime} from year, month, 185 * day, hour and minute, setting the second and nanosecond to zero. 186 * <p> 187 * The day must be valid for the year and month, otherwise an exception will be thrown. 188 * The second and nanosecond fields will be set to zero. 189 * 190 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 191 * @param month the month-of-year to represent, not null 192 * @param dayOfMonth the day-of-month to represent, from 1 to 31 193 * @param hour the hour-of-day to represent, from 0 to 23 194 * @param minute the minute-of-hour to represent, from 0 to 59 195 * @return the local date-time, not null 196 * @throws DateTimeException if the value of any field is out of range 197 * @throws DateTimeException if the day-of-month is invalid for the month-year 198 */ 199 public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute) { 200 LocalDate date = LocalDate.of(year, month, dayOfMonth); 201 LocalTime time = LocalTime.of(hour, minute); 202 return new LocalDateTime(date, time); 203 } 204 205 /** 206 * Obtains an instance of {@code LocalDateTime} from year, month, 207 * day, hour, minute and second, setting the nanosecond to zero. 208 * <p> 209 * The day must be valid for the year and month, otherwise an exception will be thrown. 210 * The nanosecond field will be set to zero. 211 * 212 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 213 * @param month the month-of-year to represent, not null 214 * @param dayOfMonth the day-of-month to represent, from 1 to 31 215 * @param hour the hour-of-day to represent, from 0 to 23 216 * @param minute the minute-of-hour to represent, from 0 to 59 217 * @param second the second-of-minute to represent, from 0 to 59 218 * @return the local date-time, not null 219 * @throws DateTimeException if the value of any field is out of range 220 * @throws DateTimeException if the day-of-month is invalid for the month-year 221 */ 222 public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second) { 223 LocalDate date = LocalDate.of(year, month, dayOfMonth); 224 LocalTime time = LocalTime.of(hour, minute, second); 225 return new LocalDateTime(date, time); 226 } 227 228 /** 229 * Obtains an instance of {@code LocalDateTime} from year, month, 230 * day, hour, minute, second and nanosecond. 231 * <p> 232 * The day must be valid for the year and month, otherwise an exception will be thrown. 233 * 234 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 235 * @param month the month-of-year to represent, not null 236 * @param dayOfMonth the day-of-month to represent, from 1 to 31 237 * @param hour the hour-of-day to represent, from 0 to 23 238 * @param minute the minute-of-hour to represent, from 0 to 59 239 * @param second the second-of-minute to represent, from 0 to 59 240 * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999 241 * @return the local date-time, not null 242 * @throws DateTimeException if the value of any field is out of range 243 * @throws DateTimeException if the day-of-month is invalid for the month-year 244 */ 245 public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) { 246 LocalDate date = LocalDate.of(year, month, dayOfMonth); 247 LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond); 248 return new LocalDateTime(date, time); 249 } 250 251 //----------------------------------------------------------------------- 252 /** 253 * Obtains an instance of {@code LocalDateTime} from year, month, 254 * day, hour and minute, setting the second and nanosecond to zero. 255 * <p> 256 * The day must be valid for the year and month, otherwise an exception will be thrown. 257 * The second and nanosecond fields will be set to zero. 258 * 259 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 260 * @param month the month-of-year to represent, from 1 (January) to 12 (December) 261 * @param dayOfMonth the day-of-month to represent, from 1 to 31 262 * @param hour the hour-of-day to represent, from 0 to 23 263 * @param minute the minute-of-hour to represent, from 0 to 59 264 * @return the local date-time, not null 265 * @throws DateTimeException if the value of any field is out of range 266 * @throws DateTimeException if the day-of-month is invalid for the month-year 267 */ 268 public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute) { 269 LocalDate date = LocalDate.of(year, month, dayOfMonth); 270 LocalTime time = LocalTime.of(hour, minute); 271 return new LocalDateTime(date, time); 272 } 273 274 /** 275 * Obtains an instance of {@code LocalDateTime} from year, month, 276 * day, hour, minute and second, setting the nanosecond to zero. 277 * <p> 278 * The day must be valid for the year and month, otherwise an exception will be thrown. 279 * The nanosecond field will be set to zero. 280 * 281 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 282 * @param month the month-of-year to represent, from 1 (January) to 12 (December) 283 * @param dayOfMonth the day-of-month to represent, from 1 to 31 284 * @param hour the hour-of-day to represent, from 0 to 23 285 * @param minute the minute-of-hour to represent, from 0 to 59 286 * @param second the second-of-minute to represent, from 0 to 59 287 * @return the local date-time, not null 288 * @throws DateTimeException if the value of any field is out of range 289 * @throws DateTimeException if the day-of-month is invalid for the month-year 290 */ 291 public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second) { 292 LocalDate date = LocalDate.of(year, month, dayOfMonth); 293 LocalTime time = LocalTime.of(hour, minute, second); 294 return new LocalDateTime(date, time); 295 } 296 297 /** 298 * Obtains an instance of {@code LocalDateTime} from year, month, 299 * day, hour, minute, second and nanosecond. 300 * <p> 301 * The day must be valid for the year and month, otherwise an exception will be thrown. 302 * 303 * @param year the year to represent, from MIN_YEAR to MAX_YEAR 304 * @param month the month-of-year to represent, from 1 (January) to 12 (December) 305 * @param dayOfMonth the day-of-month to represent, from 1 to 31 306 * @param hour the hour-of-day to represent, from 0 to 23 307 * @param minute the minute-of-hour to represent, from 0 to 59 308 * @param second the second-of-minute to represent, from 0 to 59 309 * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999 310 * @return the local date-time, not null 311 * @throws DateTimeException if the value of any field is out of range 312 * @throws DateTimeException if the day-of-month is invalid for the month-year 313 */ 314 public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) { 315 LocalDate date = LocalDate.of(year, month, dayOfMonth); 316 LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond); 317 return new LocalDateTime(date, time); 318 } 319 320 /** 321 * Obtains an instance of {@code LocalDateTime} from a date and time. 322 * 323 * @param date the local date, not null 324 * @param time the local time, not null 325 * @return the local date-time, not null 326 */ 327 public static LocalDateTime of(LocalDate date, LocalTime time) { 328 Objects.requireNonNull(date, "date"); 329 Objects.requireNonNull(time, "time"); 330 return new LocalDateTime(date, time); 331 } 332 333 //------------------------------------------------------------------------- 334 /** 335 * Obtains an instance of {@code LocalDateTime} from an {@code Instant} and zone ID. 336 * <p> 337 * This creates a local date-time based on the specified instant. 338 * First, the offset from UTC/Greenwich is obtained using the zone ID and instant, 339 * which is simple as there is only one valid offset for each instant. 340 * Then, the instant and offset are used to calculate the local date-time. 341 * 342 * @param instant the instant to create the date-time from, not null 343 * @param zone the time-zone, which may be an offset, not null 344 * @return the local date-time, not null 345 * @throws DateTimeException if the result exceeds the supported range 346 */ 347 public static LocalDateTime ofInstant(Instant instant, ZoneId zone) { 348 Objects.requireNonNull(instant, "instant"); 349 Objects.requireNonNull(zone, "zone"); 350 ZoneRules rules = zone.getRules(); 351 ZoneOffset offset = rules.getOffset(instant); 352 return ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset); 353 } 354 355 /** 356 * Obtains an instance of {@code LocalDateTime} using seconds from the 357 * epoch of 1970-01-01T00:00:00Z. 358 * <p> 359 * This allows the {@link ChronoField#INSTANT_SECONDS epoch-second} field 360 * to be converted to a local date-time. This is primarily intended for 361 * low-level conversions rather than general application usage. 362 * 363 * @param epochSecond the number of seconds from the epoch of 1970-01-01T00:00:00Z 364 * @param nanoOfSecond the nanosecond within the second, from 0 to 999,999,999 365 * @param offset the zone offset, not null 366 * @return the local date-time, not null 367 * @throws DateTimeException if the result exceeds the supported range 368 */ 369 public static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) { 370 Objects.requireNonNull(offset, "offset"); 371 long localSecond = epochSecond + offset.getTotalSeconds(); // overflow caught later 372 long localEpochDay = Jdk8Methods.floorDiv(localSecond, SECONDS_PER_DAY); 373 int secsOfDay = Jdk8Methods.floorMod(localSecond, SECONDS_PER_DAY); 374 LocalDate date = LocalDate.ofEpochDay(localEpochDay); 375 LocalTime time = LocalTime.ofSecondOfDay(secsOfDay, nanoOfSecond); 376 return new LocalDateTime(date, time); 377 } 378 379 //----------------------------------------------------------------------- 380 /** 381 * Obtains an instance of {@code LocalDateTime} from a temporal object. 382 * <p> 383 * A {@code TemporalAccessor} represents some form of date and time information. 384 * This factory converts the arbitrary temporal object to an instance of {@code LocalDateTime}. 385 * <p> 386 * The conversion extracts and combines {@code LocalDate} and {@code LocalTime}. 387 * <p> 388 * This method matches the signature of the functional interface {@link TemporalQuery} 389 * allowing it to be used as a query via method reference, {@code LocalDateTime::from}. 390 * 391 * @param temporal the temporal object to convert, not null 392 * @return the local date-time, not null 393 * @throws DateTimeException if unable to convert to a {@code LocalDateTime} 394 */ 395 public static LocalDateTime from(TemporalAccessor temporal) { 396 if (temporal instanceof LocalDateTime) { 397 return (LocalDateTime) temporal; 398 } else if (temporal instanceof ZonedDateTime) { 399 return ((ZonedDateTime) temporal).getDateTime(); 400 } 401 try { 402 LocalDate date = LocalDate.from(temporal); 403 LocalTime time = LocalTime.from(temporal); 404 return new LocalDateTime(date, time); 405 } catch (DateTimeException ex) { 406 throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " + temporal.getClass(), ex); 407 } 408 } 409 410 //----------------------------------------------------------------------- 411 /** 412 * Obtains an instance of {@code LocalDateTime} from a text string such as {@code 2007-12-03T10:15:30}. 413 * <p> 414 * The string must represent a valid date-time and is parsed using 415 * {@link org.threeten.bp.format.DateTimeFormatters#isoLocalDateTime()}. 416 * 417 * @param text the text to parse such as "2007-12-03T10:15:30", not null 418 * @return the parsed local date-time, not null 419 * @throws DateTimeParseException if the text cannot be parsed 420 */ 421 public static LocalDateTime parse(CharSequence text) { 422 return parse(text, DateTimeFormatters.isoLocalDateTime()); 423 } 424 425 /** 426 * Obtains an instance of {@code LocalDateTime} from a text string using a specific formatter. 427 * <p> 428 * The text is parsed using the formatter, returning a date-time. 429 * 430 * @param text the text to parse, not null 431 * @param formatter the formatter to use, not null 432 * @return the parsed local date-time, not null 433 * @throws DateTimeParseException if the text cannot be parsed 434 */ 435 public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) { 436 Objects.requireNonNull(formatter, "formatter"); 437 return formatter.parse(text, LocalDateTime.class); 438 } 439 440 //----------------------------------------------------------------------- 441 /** 442 * Constructor. 443 * 444 * @param date the date part of the date-time, validated not null 445 * @param time the time part of the date-time, validated not null 446 */ 447 private LocalDateTime(LocalDate date, LocalTime time) { 448 this.date = date; 449 this.time = time; 450 } 451 452 /** 453 * Returns a copy of this date-time with the new date and time, checking 454 * to see if a new object is in fact required. 455 * 456 * @param newDate the date of the new date-time, not null 457 * @param newTime the time of the new date-time, not null 458 * @return the date-time, not null 459 */ 460 private LocalDateTime with(LocalDate newDate, LocalTime newTime) { 461 if (date == newDate && time == newTime) { 462 return this; 463 } 464 return new LocalDateTime(newDate, newTime); 465 } 466 467 //----------------------------------------------------------------------- 468 /** 469 * Checks if the specified field is supported. 470 * <p> 471 * This checks if this date-time can be queried for the specified field. 472 * If false, then calling the {@link #range(TemporalField) range} and 473 * {@link #get(TemporalField) get} methods will throw an exception. 474 * <p> 475 * If the field is a {@link ChronoField} then the query is implemented here. 476 * The supported fields are: 477 * <ul> 478 * <li>{@code NANO_OF_SECOND} 479 * <li>{@code NANO_OF_DAY} 480 * <li>{@code MICRO_OF_SECOND} 481 * <li>{@code MICRO_OF_DAY} 482 * <li>{@code MILLI_OF_SECOND} 483 * <li>{@code MILLI_OF_DAY} 484 * <li>{@code SECOND_OF_MINUTE} 485 * <li>{@code SECOND_OF_DAY} 486 * <li>{@code MINUTE_OF_HOUR} 487 * <li>{@code MINUTE_OF_DAY} 488 * <li>{@code HOUR_OF_AMPM} 489 * <li>{@code CLOCK_HOUR_OF_AMPM} 490 * <li>{@code HOUR_OF_DAY} 491 * <li>{@code CLOCK_HOUR_OF_DAY} 492 * <li>{@code AMPM_OF_DAY} 493 * <li>{@code DAY_OF_WEEK} 494 * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH} 495 * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR} 496 * <li>{@code DAY_OF_MONTH} 497 * <li>{@code DAY_OF_YEAR} 498 * <li>{@code EPOCH_DAY} 499 * <li>{@code ALIGNED_WEEK_OF_MONTH} 500 * <li>{@code ALIGNED_WEEK_OF_YEAR} 501 * <li>{@code MONTH_OF_YEAR} 502 * <li>{@code EPOCH_MONTH} 503 * <li>{@code YEAR_OF_ERA} 504 * <li>{@code YEAR} 505 * <li>{@code ERA} 506 * </ul> 507 * All other {@code ChronoField} instances will return false. 508 * <p> 509 * If the field is not a {@code ChronoField}, then the result of this method 510 * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)} 511 * passing {@code this} as the argument. 512 * Whether the field is supported is determined by the field. 513 * 514 * @param field the field to check, null returns false 515 * @return true if the field is supported on this date-time, false if not 516 */ 517 @Override 518 public boolean isSupported(TemporalField field) { 519 if (field instanceof ChronoField) { 520 ChronoField f = (ChronoField) field; 521 return f.isDateField() || f.isTimeField(); 522 } 523 return field != null && field.doIsSupported(this); 524 } 525 526 /** 527 * Gets the range of valid values for the specified field. 528 * <p> 529 * The range object expresses the minimum and maximum valid values for a field. 530 * This date-time is used to enhance the accuracy of the returned range. 531 * If it is not possible to return the range, because the field is not supported 532 * or for some other reason, an exception is thrown. 533 * <p> 534 * If the field is a {@link ChronoField} then the query is implemented here. 535 * The {@link #isSupported(TemporalField) supported fields} will return 536 * appropriate range instances. 537 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 538 * <p> 539 * If the field is not a {@code ChronoField}, then the result of this method 540 * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)} 541 * passing {@code this} as the argument. 542 * Whether the range can be obtained is determined by the field. 543 * 544 * @param field the field to query the range for, not null 545 * @return the range of valid values for the field, not null 546 * @throws DateTimeException if the range for the field cannot be obtained 547 */ 548 @Override 549 public ValueRange range(TemporalField field) { 550 if (field instanceof ChronoField) { 551 ChronoField f = (ChronoField) field; 552 return (f.isTimeField() ? time.range(field) : date.range(field)); 553 } 554 return field.doRange(this); 555 } 556 557 /** 558 * Gets the value of the specified field from this date-time as an {@code int}. 559 * <p> 560 * This queries this date-time for the value for the specified field. 561 * The returned value will always be within the valid range of values for the field. 562 * If it is not possible to return the value, because the field is not supported 563 * or for some other reason, an exception is thrown. 564 * <p> 565 * If the field is a {@link ChronoField} then the query is implemented here. 566 * The {@link #isSupported(TemporalField) supported fields} will return valid 567 * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY}, 568 * {@code EPOCH_DAY} and {@code EPOCH_MONTH} which are too large to fit in 569 * an {@code int} and throw a {@code DateTimeException}. 570 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 571 * <p> 572 * If the field is not a {@code ChronoField}, then the result of this method 573 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 574 * passing {@code this} as the argument. Whether the value can be obtained, 575 * and what the value represents, is determined by the field. 576 * 577 * @param field the field to get, not null 578 * @return the value for the field 579 * @throws DateTimeException if a value for the field cannot be obtained 580 * @throws ArithmeticException if numeric overflow occurs 581 */ 582 @Override 583 public int get(TemporalField field) { 584 if (field instanceof ChronoField) { 585 ChronoField f = (ChronoField) field; 586 return (f.isTimeField() ? time.get(field) : date.get(field)); 587 } 588 return super.get(field); 589 } 590 591 /** 592 * Gets the value of the specified field from this date-time as a {@code long}. 593 * <p> 594 * This queries this date-time for the value for the specified field. 595 * If it is not possible to return the value, because the field is not supported 596 * or for some other reason, an exception is thrown. 597 * <p> 598 * If the field is a {@link ChronoField} then the query is implemented here. 599 * The {@link #isSupported(TemporalField) supported fields} will return valid 600 * values based on this date-time. 601 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 602 * <p> 603 * If the field is not a {@code ChronoField}, then the result of this method 604 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 605 * passing {@code this} as the argument. Whether the value can be obtained, 606 * and what the value represents, is determined by the field. 607 * 608 * @param field the field to get, not null 609 * @return the value for the field 610 * @throws DateTimeException if a value for the field cannot be obtained 611 * @throws ArithmeticException if numeric overflow occurs 612 */ 613 @Override 614 public long getLong(TemporalField field) { 615 if (field instanceof ChronoField) { 616 ChronoField f = (ChronoField) field; 617 return (f.isTimeField() ? time.getLong(field) : date.getLong(field)); 618 } 619 return field.doGet(this); 620 } 621 622 //----------------------------------------------------------------------- 623 /** 624 * Gets the {@code LocalDate} part of this date-time. 625 * <p> 626 * This returns a {@code LocalDate} with the same year, month and day 627 * as this date-time. 628 * 629 * @return the date part of this date-time, not null 630 */ 631 @Override 632 public LocalDate getDate() { 633 return date; 634 } 635 636 /** 637 * Gets the year field. 638 * <p> 639 * This method returns the primitive {@code int} value for the year. 640 * <p> 641 * The year returned by this method is proleptic as per {@code get(YEAR)}. 642 * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}. 643 * 644 * @return the year, from MIN_YEAR to MAX_YEAR 645 */ 646 public int getYear() { 647 return date.getYear(); 648 } 649 650 /** 651 * Gets the month-of-year field from 1 to 12. 652 * <p> 653 * This method returns the month as an {@code int} from 1 to 12. 654 * Application code is frequently clearer if the enum {@link Month} 655 * is used by calling {@link #getMonth()}. 656 * 657 * @return the month-of-year, from 1 to 12 658 * @see #getMonth() 659 */ 660 public int getMonthValue() { 661 return date.getMonthValue(); 662 } 663 664 /** 665 * Gets the month-of-year field using the {@code Month} enum. 666 * <p> 667 * This method returns the enum {@link Month} for the month. 668 * This avoids confusion as to what {@code int} values mean. 669 * If you need access to the primitive {@code int} value then the enum 670 * provides the {@link Month#getValue() int value}. 671 * 672 * @return the month-of-year, not null 673 * @see #getMonthValue() 674 */ 675 public Month getMonth() { 676 return date.getMonth(); 677 } 678 679 /** 680 * Gets the day-of-month field. 681 * <p> 682 * This method returns the primitive {@code int} value for the day-of-month. 683 * 684 * @return the day-of-month, from 1 to 31 685 */ 686 public int getDayOfMonth() { 687 return date.getDayOfMonth(); 688 } 689 690 /** 691 * Gets the day-of-year field. 692 * <p> 693 * This method returns the primitive {@code int} value for the day-of-year. 694 * 695 * @return the day-of-year, from 1 to 365, or 366 in a leap year 696 */ 697 public int getDayOfYear() { 698 return date.getDayOfYear(); 699 } 700 701 /** 702 * Gets the day-of-week field, which is an enum {@code DayOfWeek}. 703 * <p> 704 * This method returns the enum {@link DayOfWeek} for the day-of-week. 705 * This avoids confusion as to what {@code int} values mean. 706 * If you need access to the primitive {@code int} value then the enum 707 * provides the {@link DayOfWeek#getValue() int value}. 708 * <p> 709 * Additional information can be obtained from the {@code DayOfWeek}. 710 * This includes textual names of the values. 711 * 712 * @return the day-of-week, not null 713 */ 714 public DayOfWeek getDayOfWeek() { 715 return date.getDayOfWeek(); 716 } 717 718 //----------------------------------------------------------------------- 719 /** 720 * Gets the {@code LocalTime} part of this date-time. 721 * <p> 722 * This returns a {@code LocalTime} with the same hour, minute, second and 723 * nanosecond as this date-time. 724 * 725 * @return the time part of this date-time, not null 726 */ 727 @Override 728 public LocalTime getTime() { 729 return time; 730 } 731 732 /** 733 * Gets the hour-of-day field. 734 * 735 * @return the hour-of-day, from 0 to 23 736 */ 737 public int getHour() { 738 return time.getHour(); 739 } 740 741 /** 742 * Gets the minute-of-hour field. 743 * 744 * @return the minute-of-hour, from 0 to 59 745 */ 746 public int getMinute() { 747 return time.getMinute(); 748 } 749 750 /** 751 * Gets the second-of-minute field. 752 * 753 * @return the second-of-minute, from 0 to 59 754 */ 755 public int getSecond() { 756 return time.getSecond(); 757 } 758 759 /** 760 * Gets the nano-of-second field. 761 * 762 * @return the nano-of-second, from 0 to 999,999,999 763 */ 764 public int getNano() { 765 return time.getNano(); 766 } 767 768 //----------------------------------------------------------------------- 769 /** 770 * Returns an adjusted copy of this date-time. 771 * <p> 772 * This returns a new {@code LocalDateTime}, based on this one, with the date-time adjusted. 773 * The adjustment takes place using the specified adjuster strategy object. 774 * Read the documentation of the adjuster to understand what adjustment will be made. 775 * <p> 776 * A simple adjuster might simply set the one of the fields, such as the year field. 777 * A more complex adjuster might set the date to the last day of the month. 778 * A selection of common adjustments is provided in {@link TemporalAdjusters}. 779 * These include finding the "last day of the month" and "next Wednesday". 780 * Key date-time classes also implement the {@code TemporalAdjuster} interface, 781 * such as {@link Month} and {@link MonthDay MonthDay}. 782 * The adjuster is responsible for handling special cases, such as the varying 783 * lengths of month and leap years. 784 * <p> 785 * For example this code returns a date on the last day of July: 786 * <pre> 787 * import static org.threeten.bp.Month.*; 788 * import static org.threeten.bp.temporal.Adjusters.*; 789 * 790 * result = localDateTime.with(JULY).with(lastDayOfMonth()); 791 * </pre> 792 * <p> 793 * The classes {@link LocalDate} and {@link LocalTime} implement {@code TemporalAdjuster}, 794 * thus this method can be used to change the date, time or offset: 795 * <pre> 796 * result = localDateTime.with(date); 797 * result = localDateTime.with(time); 798 * </pre> 799 * <p> 800 * The result of this method is obtained by invoking the 801 * {@link TemporalAdjuster#adjustInto(Temporal)} method on the 802 * specified adjuster passing {@code this} as the argument. 803 * <p> 804 * This instance is immutable and unaffected by this method call. 805 * 806 * @param adjuster the adjuster to use, not null 807 * @return a {@code LocalDateTime} based on {@code this} with the adjustment made, not null 808 * @throws DateTimeException if the adjustment cannot be made 809 * @throws ArithmeticException if numeric overflow occurs 810 */ 811 @Override 812 public LocalDateTime with(TemporalAdjuster adjuster) { 813 // optimizations 814 if (adjuster instanceof LocalDate) { 815 return with((LocalDate) adjuster, time); 816 } else if (adjuster instanceof LocalTime) { 817 return with(date, (LocalTime) adjuster); 818 } else if (adjuster instanceof LocalDateTime) { 819 return (LocalDateTime) adjuster; 820 } 821 return (LocalDateTime) adjuster.adjustInto(this); 822 } 823 824 /** 825 * Returns a copy of this date-time with the specified field set to a new value. 826 * <p> 827 * This returns a new {@code LocalDateTime}, based on this one, with the value 828 * for the specified field changed. 829 * This can be used to change any supported field, such as the year, month or day-of-month. 830 * If it is not possible to set the value, because the field is not supported or for 831 * some other reason, an exception is thrown. 832 * <p> 833 * In some cases, changing the specified field can cause the resulting date-time to become invalid, 834 * such as changing the month from 31st January to February would make the day-of-month invalid. 835 * In cases like this, the field is responsible for resolving the date. Typically it will choose 836 * the previous valid date, which would be the last valid day of February in this example. 837 * <p> 838 * If the field is a {@link ChronoField} then the adjustment is implemented here. 839 * The {@link #isSupported(TemporalField) supported fields} will behave as per 840 * the matching method on {@link LocalDate#with(TemporalField, long) LocalDate} 841 * or {@link LocalTime#with(TemporalField, long) LocalTime}. 842 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 843 * <p> 844 * If the field is not a {@code ChronoField}, then the result of this method 845 * is obtained by invoking {@code TemporalField.doWith(Temporal, long)} 846 * passing {@code this} as the argument. In this case, the field determines 847 * whether and how to adjust the instant. 848 * <p> 849 * This instance is immutable and unaffected by this method call. 850 * 851 * @param field the field to set in the result, not null 852 * @param newValue the new value of the field in the result 853 * @return a {@code LocalDateTime} based on {@code this} with the specified field set, not null 854 * @throws DateTimeException if the field cannot be set 855 * @throws ArithmeticException if numeric overflow occurs 856 */ 857 @Override 858 public LocalDateTime with(TemporalField field, long newValue) { 859 if (field instanceof ChronoField) { 860 ChronoField f = (ChronoField) field; 861 if (f.isTimeField()) { 862 return with(date, time.with(field, newValue)); 863 } else { 864 return with(date.with(field, newValue), time); 865 } 866 } 867 return field.doWith(this, newValue); 868 } 869 870 //----------------------------------------------------------------------- 871 /** 872 * Returns a copy of this {@code LocalDateTime} with the year altered. 873 * The time does not affect the calculation and will be the same in the result. 874 * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month. 875 * <p> 876 * This instance is immutable and unaffected by this method call. 877 * 878 * @param year the year to set in the result, from MIN_YEAR to MAX_YEAR 879 * @return a {@code LocalDateTime} based on this date-time with the requested year, not null 880 * @throws DateTimeException if the year value is invalid 881 */ 882 public LocalDateTime withYear(int year) { 883 return with(date.withYear(year), time); 884 } 885 886 /** 887 * Returns a copy of this {@code LocalDateTime} with the month-of-year altered. 888 * The time does not affect the calculation and will be the same in the result. 889 * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month. 890 * <p> 891 * This instance is immutable and unaffected by this method call. 892 * 893 * @param month the month-of-year to set in the result, from 1 (January) to 12 (December) 894 * @return a {@code LocalDateTime} based on this date-time with the requested month, not null 895 * @throws DateTimeException if the month-of-year value is invalid 896 */ 897 public LocalDateTime withMonth(int month) { 898 return with(date.withMonth(month), time); 899 } 900 901 /** 902 * Returns a copy of this {@code LocalDateTime} with the day-of-month altered. 903 * If the resulting {@code LocalDateTime} is invalid, an exception is thrown. 904 * The time does not affect the calculation and will be the same in the result. 905 * <p> 906 * This instance is immutable and unaffected by this method call. 907 * 908 * @param dayOfMonth the day-of-month to set in the result, from 1 to 28-31 909 * @return a {@code LocalDateTime} based on this date-time with the requested day, not null 910 * @throws DateTimeException if the day-of-month value is invalid 911 * @throws DateTimeException if the day-of-month is invalid for the month-year 912 */ 913 public LocalDateTime withDayOfMonth(int dayOfMonth) { 914 return with(date.withDayOfMonth(dayOfMonth), time); 915 } 916 917 /** 918 * Returns a copy of this {@code LocalDateTime} with the day-of-year altered. 919 * If the resulting {@code LocalDateTime} is invalid, an exception is thrown. 920 * <p> 921 * This instance is immutable and unaffected by this method call. 922 * 923 * @param dayOfYear the day-of-year to set in the result, from 1 to 365-366 924 * @return a {@code LocalDateTime} based on this date with the requested day, not null 925 * @throws DateTimeException if the day-of-year value is invalid 926 * @throws DateTimeException if the day-of-year is invalid for the year 927 */ 928 public LocalDateTime withDayOfYear(int dayOfYear) { 929 return with(date.withDayOfYear(dayOfYear), time); 930 } 931 932 //----------------------------------------------------------------------- 933 /** 934 * Returns a copy of this {@code LocalDateTime} with the hour-of-day value altered. 935 * <p> 936 * This instance is immutable and unaffected by this method call. 937 * 938 * @param hour the hour-of-day to set in the result, from 0 to 23 939 * @return a {@code LocalDateTime} based on this date-time with the requested hour, not null 940 * @throws DateTimeException if the hour value is invalid 941 */ 942 public LocalDateTime withHour(int hour) { 943 LocalTime newTime = time.withHour(hour); 944 return with(date, newTime); 945 } 946 947 /** 948 * Returns a copy of this {@code LocalDateTime} with the minute-of-hour value altered. 949 * <p> 950 * This instance is immutable and unaffected by this method call. 951 * 952 * @param minute the minute-of-hour to set in the result, from 0 to 59 953 * @return a {@code LocalDateTime} based on this date-time with the requested minute, not null 954 * @throws DateTimeException if the minute value is invalid 955 */ 956 public LocalDateTime withMinute(int minute) { 957 LocalTime newTime = time.withMinute(minute); 958 return with(date, newTime); 959 } 960 961 /** 962 * Returns a copy of this {@code LocalDateTime} with the second-of-minute value altered. 963 * <p> 964 * This instance is immutable and unaffected by this method call. 965 * 966 * @param second the second-of-minute to set in the result, from 0 to 59 967 * @return a {@code LocalDateTime} based on this date-time with the requested second, not null 968 * @throws DateTimeException if the second value is invalid 969 */ 970 public LocalDateTime withSecond(int second) { 971 LocalTime newTime = time.withSecond(second); 972 return with(date, newTime); 973 } 974 975 /** 976 * Returns a copy of this {@code LocalDateTime} with the nano-of-second value altered. 977 * <p> 978 * This instance is immutable and unaffected by this method call. 979 * 980 * @param nanoOfSecond the nano-of-second to set in the result, from 0 to 999,999,999 981 * @return a {@code LocalDateTime} based on this date-time with the requested nanosecond, not null 982 * @throws DateTimeException if the nano value is invalid 983 */ 984 public LocalDateTime withNano(int nanoOfSecond) { 985 LocalTime newTime = time.withNano(nanoOfSecond); 986 return with(date, newTime); 987 } 988 989 //----------------------------------------------------------------------- 990 /** 991 * Returns a copy of this {@code LocalDateTime} with the time truncated. 992 * <p> 993 * Truncation returns a copy of the original date-time with fields 994 * smaller than the specified unit set to zero. 995 * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit 996 * will set the second-of-minute and nano-of-second field to zero. 997 * <p> 998 * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time 999 * units with an exact duration can be used, other units throw an exception. 1000 * <p> 1001 * This instance is immutable and unaffected by this method call. 1002 * 1003 * @param unit the unit to truncate to, not null 1004 * @return a {@code LocalDateTime} based on this date-time with the time truncated, not null 1005 * @throws DateTimeException if unable to truncate 1006 */ 1007 public LocalDateTime truncatedTo(TemporalUnit unit) { 1008 return with(date, time.truncatedTo(unit)); 1009 } 1010 1011 //----------------------------------------------------------------------- 1012 /** 1013 * Returns a copy of this date-time with the specified period added. 1014 * <p> 1015 * This method returns a new date-time based on this time with the specified period added. 1016 * The adder is typically {@link Period} but may be any other type implementing 1017 * the {@link TemporalAdder} interface. 1018 * The calculation is delegated to the specified adjuster, which typically calls 1019 * back to {@link #plus(long, TemporalUnit)}. 1020 * <p> 1021 * This instance is immutable and unaffected by this method call. 1022 * 1023 * @param adder the adder to use, not null 1024 * @return a {@code LocalDateTime} based on this date-time with the addition made, not null 1025 * @throws DateTimeException if the addition cannot be made 1026 * @throws ArithmeticException if numeric overflow occurs 1027 */ 1028 @Override 1029 public LocalDateTime plus(TemporalAdder adder) { 1030 return (LocalDateTime) adder.addTo(this); 1031 } 1032 1033 /** 1034 * Returns a copy of this date-time with the specified period added. 1035 * <p> 1036 * This method returns a new date-time based on this date-time with the specified period added. 1037 * This can be used to add any period that is defined by a unit, for example to add years, months or days. 1038 * The unit is responsible for the details of the calculation, including the resolution 1039 * of any edge cases in the calculation. 1040 * <p> 1041 * This instance is immutable and unaffected by this method call. 1042 * 1043 * @param amountToAdd the amount of the unit to add to the result, may be negative 1044 * @param unit the unit of the period to add, not null 1045 * @return a {@code LocalDateTime} based on this date-time with the specified period added, not null 1046 * @throws DateTimeException if the unit cannot be added to this type 1047 */ 1048 @Override 1049 public LocalDateTime plus(long amountToAdd, TemporalUnit unit) { 1050 if (unit instanceof ChronoUnit) { 1051 ChronoUnit f = (ChronoUnit) unit; 1052 switch (f) { 1053 case NANOS: return plusNanos(amountToAdd); 1054 case MICROS: return plusDays(amountToAdd / MICROS_PER_DAY).plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); 1055 case MILLIS: return plusDays(amountToAdd / MILLIS_PER_DAY).plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000); 1056 case SECONDS: return plusSeconds(amountToAdd); 1057 case MINUTES: return plusMinutes(amountToAdd); 1058 case HOURS: return plusHours(amountToAdd); 1059 case HALF_DAYS: return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12); // no overflow (256 is multiple of 2) 1060 } 1061 return with(date.plus(amountToAdd, unit), time); 1062 } 1063 return unit.doPlus(this, amountToAdd); 1064 } 1065 1066 //----------------------------------------------------------------------- 1067 /** 1068 * Returns a copy of this {@code LocalDateTime} with the specified period in years added. 1069 * <p> 1070 * This method adds the specified amount to the years field in three steps: 1071 * <ol> 1072 * <li>Add the input years to the year field</li> 1073 * <li>Check if the resulting date would be invalid</li> 1074 * <li>Adjust the day-of-month to the last valid day if necessary</li> 1075 * </ol> 1076 * <p> 1077 * For example, 2008-02-29 (leap year) plus one year would result in the 1078 * invalid date 2009-02-29 (standard year). Instead of returning an invalid 1079 * result, the last valid day of the month, 2009-02-28, is selected instead. 1080 * <p> 1081 * This instance is immutable and unaffected by this method call. 1082 * 1083 * @param years the years to add, may be negative 1084 * @return a {@code LocalDateTime} based on this date-time with the years added, not null 1085 * @throws DateTimeException if the result exceeds the supported date range 1086 */ 1087 public LocalDateTime plusYears(long years) { 1088 LocalDate newDate = date.plusYears(years); 1089 return with(newDate, time); 1090 } 1091 1092 /** 1093 * Returns a copy of this {@code LocalDateTime} with the specified period in months added. 1094 * <p> 1095 * This method adds the specified amount to the months field in three steps: 1096 * <ol> 1097 * <li>Add the input months to the month-of-year field</li> 1098 * <li>Check if the resulting date would be invalid</li> 1099 * <li>Adjust the day-of-month to the last valid day if necessary</li> 1100 * </ol> 1101 * <p> 1102 * For example, 2007-03-31 plus one month would result in the invalid date 1103 * 2007-04-31. Instead of returning an invalid result, the last valid day 1104 * of the month, 2007-04-30, is selected instead. 1105 * <p> 1106 * This instance is immutable and unaffected by this method call. 1107 * 1108 * @param months the months to add, may be negative 1109 * @return a {@code LocalDateTime} based on this date-time with the months added, not null 1110 * @throws DateTimeException if the result exceeds the supported date range 1111 */ 1112 public LocalDateTime plusMonths(long months) { 1113 LocalDate newDate = date.plusMonths(months); 1114 return with(newDate, time); 1115 } 1116 1117 /** 1118 * Returns a copy of this {@code LocalDateTime} with the specified period in weeks added. 1119 * <p> 1120 * This method adds the specified amount in weeks to the days field incrementing 1121 * the month and year fields as necessary to ensure the result remains valid. 1122 * The result is only invalid if the maximum/minimum year is exceeded. 1123 * <p> 1124 * For example, 2008-12-31 plus one week would result in 2009-01-07. 1125 * <p> 1126 * This instance is immutable and unaffected by this method call. 1127 * 1128 * @param weeks the weeks to add, may be negative 1129 * @return a {@code LocalDateTime} based on this date-time with the weeks added, not null 1130 * @throws DateTimeException if the result exceeds the supported date range 1131 */ 1132 public LocalDateTime plusWeeks(long weeks) { 1133 LocalDate newDate = date.plusWeeks(weeks); 1134 return with(newDate, time); 1135 } 1136 1137 /** 1138 * Returns a copy of this {@code LocalDateTime} with the specified period in days added. 1139 * <p> 1140 * This method adds the specified amount to the days field incrementing the 1141 * month and year fields as necessary to ensure the result remains valid. 1142 * The result is only invalid if the maximum/minimum year is exceeded. 1143 * <p> 1144 * For example, 2008-12-31 plus one day would result in 2009-01-01. 1145 * <p> 1146 * This instance is immutable and unaffected by this method call. 1147 * 1148 * @param days the days to add, may be negative 1149 * @return a {@code LocalDateTime} based on this date-time with the days added, not null 1150 * @throws DateTimeException if the result exceeds the supported date range 1151 */ 1152 public LocalDateTime plusDays(long days) { 1153 LocalDate newDate = date.plusDays(days); 1154 return with(newDate, time); 1155 } 1156 1157 //----------------------------------------------------------------------- 1158 /** 1159 * Returns a copy of this {@code LocalDateTime} with the specified period in hours added. 1160 * <p> 1161 * This instance is immutable and unaffected by this method call. 1162 * 1163 * @param hours the hours to add, may be negative 1164 * @return a {@code LocalDateTime} based on this date-time with the hours added, not null 1165 * @throws DateTimeException if the result exceeds the supported date range 1166 */ 1167 public LocalDateTime plusHours(long hours) { 1168 return plusWithOverflow(date, hours, 0, 0, 0, 1); 1169 } 1170 1171 /** 1172 * Returns a copy of this {@code LocalDateTime} with the specified period in minutes added. 1173 * <p> 1174 * This instance is immutable and unaffected by this method call. 1175 * 1176 * @param minutes the minutes to add, may be negative 1177 * @return a {@code LocalDateTime} based on this date-time with the minutes added, not null 1178 * @throws DateTimeException if the result exceeds the supported date range 1179 */ 1180 public LocalDateTime plusMinutes(long minutes) { 1181 return plusWithOverflow(date, 0, minutes, 0, 0, 1); 1182 } 1183 1184 /** 1185 * Returns a copy of this {@code LocalDateTime} with the specified period in seconds added. 1186 * <p> 1187 * This instance is immutable and unaffected by this method call. 1188 * 1189 * @param seconds the seconds to add, may be negative 1190 * @return a {@code LocalDateTime} based on this date-time with the seconds added, not null 1191 * @throws DateTimeException if the result exceeds the supported date range 1192 */ 1193 public LocalDateTime plusSeconds(long seconds) { 1194 return plusWithOverflow(date, 0, 0, seconds, 0, 1); 1195 } 1196 1197 /** 1198 * Returns a copy of this {@code LocalDateTime} with the specified period in nanoseconds added. 1199 * <p> 1200 * This instance is immutable and unaffected by this method call. 1201 * 1202 * @param nanos the nanos to add, may be negative 1203 * @return a {@code LocalDateTime} based on this date-time with the nanoseconds added, not null 1204 * @throws DateTimeException if the result exceeds the supported date range 1205 */ 1206 public LocalDateTime plusNanos(long nanos) { 1207 return plusWithOverflow(date, 0, 0, 0, nanos, 1); 1208 } 1209 1210 //----------------------------------------------------------------------- 1211 /** 1212 * Returns a copy of this date-time with the specified period subtracted. 1213 * <p> 1214 * This method returns a new date-time based on this time with the specified period subtracted. 1215 * The subtractor is typically {@link Period} but may be any other type implementing 1216 * the {@link TemporalSubtractor} interface. 1217 * The calculation is delegated to the specified adjuster, which typically calls 1218 * back to {@link #minus(long, TemporalUnit)}. 1219 * <p> 1220 * This instance is immutable and unaffected by this method call. 1221 * 1222 * @param subtractor the subtractor to use, not null 1223 * @return a {@code LocalDateTime} based on this date-time with the subtraction made, not null 1224 * @throws DateTimeException if the subtraction cannot be made 1225 * @throws ArithmeticException if numeric overflow occurs 1226 */ 1227 @Override 1228 public LocalDateTime minus(TemporalSubtractor subtractor) { 1229 return (LocalDateTime) subtractor.subtractFrom(this); 1230 } 1231 1232 /** 1233 * Returns a copy of this date-time with the specified period subtracted. 1234 * <p> 1235 * This method returns a new date-time based on this date-time with the specified period subtracted. 1236 * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days. 1237 * The unit is responsible for the details of the calculation, including the resolution 1238 * of any edge cases in the calculation. 1239 * <p> 1240 * This instance is immutable and unaffected by this method call. 1241 * 1242 * @param amountToSubtract the amount of the unit to subtract from the result, may be negative 1243 * @param unit the unit of the period to subtract, not null 1244 * @return a {@code LocalDateTime} based on this date-time with the specified period subtracted, not null 1245 * @throws DateTimeException if the unit cannot be added to this type 1246 */ 1247 @Override 1248 public LocalDateTime minus(long amountToSubtract, TemporalUnit unit) { 1249 return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); 1250 } 1251 1252 //----------------------------------------------------------------------- 1253 /** 1254 * Returns a copy of this {@code LocalDateTime} with the specified period in years subtracted. 1255 * <p> 1256 * This method subtracts the specified amount from the years field in three steps: 1257 * <ol> 1258 * <li>Subtract the input years from the year field</li> 1259 * <li>Check if the resulting date would be invalid</li> 1260 * <li>Adjust the day-of-month to the last valid day if necessary</li> 1261 * </ol> 1262 * <p> 1263 * For example, 2008-02-29 (leap year) minus one year would result in the 1264 * invalid date 2009-02-29 (standard year). Instead of returning an invalid 1265 * result, the last valid day of the month, 2009-02-28, is selected instead. 1266 * <p> 1267 * This instance is immutable and unaffected by this method call. 1268 * 1269 * @param years the years to subtract, may be negative 1270 * @return a {@code LocalDateTime} based on this date-time with the years subtracted, not null 1271 * @throws DateTimeException if the result exceeds the supported date range 1272 */ 1273 public LocalDateTime minusYears(long years) { 1274 return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years)); 1275 } 1276 1277 /** 1278 * Returns a copy of this {@code LocalDateTime} with the specified period in months subtracted. 1279 * <p> 1280 * This method subtracts the specified amount from the months field in three steps: 1281 * <ol> 1282 * <li>Subtract the input months from the month-of-year field</li> 1283 * <li>Check if the resulting date would be invalid</li> 1284 * <li>Adjust the day-of-month to the last valid day if necessary</li> 1285 * </ol> 1286 * <p> 1287 * For example, 2007-03-31 minus one month would result in the invalid date 1288 * 2007-04-31. Instead of returning an invalid result, the last valid day 1289 * of the month, 2007-04-30, is selected instead. 1290 * <p> 1291 * This instance is immutable and unaffected by this method call. 1292 * 1293 * @param months the months to subtract, may be negative 1294 * @return a {@code LocalDateTime} based on this date-time with the months subtracted, not null 1295 * @throws DateTimeException if the result exceeds the supported date range 1296 */ 1297 public LocalDateTime minusMonths(long months) { 1298 return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months)); 1299 } 1300 1301 /** 1302 * Returns a copy of this {@code LocalDateTime} with the specified period in weeks subtracted. 1303 * <p> 1304 * This method subtracts the specified amount in weeks from the days field decrementing 1305 * the month and year fields as necessary to ensure the result remains valid. 1306 * The result is only invalid if the maximum/minimum year is exceeded. 1307 * <p> 1308 * For example, 2009-01-07 minus one week would result in 2008-12-31. 1309 * <p> 1310 * This instance is immutable and unaffected by this method call. 1311 * 1312 * @param weeks the weeks to subtract, may be negative 1313 * @return a {@code LocalDateTime} based on this date-time with the weeks subtracted, not null 1314 * @throws DateTimeException if the result exceeds the supported date range 1315 */ 1316 public LocalDateTime minusWeeks(long weeks) { 1317 return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks)); 1318 } 1319 1320 /** 1321 * Returns a copy of this {@code LocalDateTime} with the specified period in days subtracted. 1322 * <p> 1323 * This method subtracts the specified amount from the days field incrementing the 1324 * month and year fields as necessary to ensure the result remains valid. 1325 * The result is only invalid if the maximum/minimum year is exceeded. 1326 * <p> 1327 * For example, 2009-01-01 minus one day would result in 2008-12-31. 1328 * <p> 1329 * This instance is immutable and unaffected by this method call. 1330 * 1331 * @param days the days to subtract, may be negative 1332 * @return a {@code LocalDateTime} based on this date-time with the days subtracted, not null 1333 * @throws DateTimeException if the result exceeds the supported date range 1334 */ 1335 public LocalDateTime minusDays(long days) { 1336 return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days)); 1337 } 1338 1339 //----------------------------------------------------------------------- 1340 /** 1341 * Returns a copy of this {@code LocalDateTime} with the specified period in hours subtracted. 1342 * <p> 1343 * This instance is immutable and unaffected by this method call. 1344 * 1345 * @param hours the hours to subtract, may be negative 1346 * @return a {@code LocalDateTime} based on this date-time with the hours subtracted, not null 1347 * @throws DateTimeException if the result exceeds the supported date range 1348 */ 1349 public LocalDateTime minusHours(long hours) { 1350 return plusWithOverflow(date, hours, 0, 0, 0, -1); 1351 } 1352 1353 /** 1354 * Returns a copy of this {@code LocalDateTime} with the specified period in minutes subtracted. 1355 * <p> 1356 * This instance is immutable and unaffected by this method call. 1357 * 1358 * @param minutes the minutes to subtract, may be negative 1359 * @return a {@code LocalDateTime} based on this date-time with the minutes subtracted, not null 1360 * @throws DateTimeException if the result exceeds the supported date range 1361 */ 1362 public LocalDateTime minusMinutes(long minutes) { 1363 return plusWithOverflow(date, 0, minutes, 0, 0, -1); 1364 } 1365 1366 /** 1367 * Returns a copy of this {@code LocalDateTime} with the specified period in seconds subtracted. 1368 * <p> 1369 * This instance is immutable and unaffected by this method call. 1370 * 1371 * @param seconds the seconds to subtract, may be negative 1372 * @return a {@code LocalDateTime} based on this date-time with the seconds subtracted, not null 1373 * @throws DateTimeException if the result exceeds the supported date range 1374 */ 1375 public LocalDateTime minusSeconds(long seconds) { 1376 return plusWithOverflow(date, 0, 0, seconds, 0, -1); 1377 } 1378 1379 /** 1380 * Returns a copy of this {@code LocalDateTime} with the specified period in nanoseconds subtracted. 1381 * <p> 1382 * This instance is immutable and unaffected by this method call. 1383 * 1384 * @param nanos the nanos to subtract, may be negative 1385 * @return a {@code LocalDateTime} based on this date-time with the nanoseconds subtracted, not null 1386 * @throws DateTimeException if the result exceeds the supported date range 1387 */ 1388 public LocalDateTime minusNanos(long nanos) { 1389 return plusWithOverflow(date, 0, 0, 0, nanos, -1); 1390 } 1391 1392 //----------------------------------------------------------------------- 1393 /** 1394 * Returns a copy of this {@code LocalDateTime} with the specified period added. 1395 * <p> 1396 * This instance is immutable and unaffected by this method call. 1397 * 1398 * @param newDate the new date to base the calculation on, not null 1399 * @param hours the hours to add, may be negative 1400 * @param minutes the minutes to add, may be negative 1401 * @param seconds the seconds to add, may be negative 1402 * @param nanos the nanos to add, may be negative 1403 * @param sign the sign to determine add or subtract 1404 * @return the combined result, not null 1405 */ 1406 private LocalDateTime plusWithOverflow(LocalDate newDate, long hours, long minutes, long seconds, long nanos, int sign) { 1407 // 9223372036854775808 long, 2147483648 int 1408 if ((hours | minutes | seconds | nanos) == 0) { 1409 return with(newDate, time); 1410 } 1411 long totDays = nanos / NANOS_PER_DAY + // max/24*60*60*1B 1412 seconds / SECONDS_PER_DAY + // max/24*60*60 1413 minutes / MINUTES_PER_DAY + // max/24*60 1414 hours / HOURS_PER_DAY; // max/24 1415 totDays *= sign; // total max*0.4237... 1416 long totNanos = nanos % NANOS_PER_DAY + // max 86400000000000 1417 (seconds % SECONDS_PER_DAY) * NANOS_PER_SECOND + // max 86400000000000 1418 (minutes % MINUTES_PER_DAY) * NANOS_PER_MINUTE + // max 86400000000000 1419 (hours % HOURS_PER_DAY) * NANOS_PER_HOUR; // max 86400000000000 1420 long curNoD = time.toNanoOfDay(); // max 86400000000000 1421 totNanos = totNanos * sign + curNoD; // total 432000000000000 1422 totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY); 1423 long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY); 1424 LocalTime newTime = (newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD)); 1425 return with(newDate.plusDays(totDays), newTime); 1426 } 1427 1428 //----------------------------------------------------------------------- 1429 /** 1430 * Queries this date-time using the specified query. 1431 * <p> 1432 * This queries this date-time using the specified query strategy object. 1433 * The {@code TemporalQuery} object defines the logic to be used to 1434 * obtain the result. Read the documentation of the query to understand 1435 * what the result of this method will be. 1436 * <p> 1437 * The result of this method is obtained by invoking the 1438 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the 1439 * specified query passing {@code this} as the argument. 1440 * 1441 * @param <R> the type of the result 1442 * @param query the query to invoke, not null 1443 * @return the query result, null may be returned (defined by the query) 1444 * @throws DateTimeException if unable to query (defined by the query) 1445 * @throws ArithmeticException if numeric overflow occurs (defined by the query) 1446 */ 1447 @Override // override for Javadoc 1448 public <R> R query(TemporalQuery<R> query) { 1449 return super.query(query); 1450 } 1451 1452 /** 1453 * Adjusts the specified temporal object to have the same date and time as this object. 1454 * <p> 1455 * This returns a temporal object of the same observable type as the input 1456 * with the date and time changed to be the same as this. 1457 * <p> 1458 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} 1459 * twice, passing {@link ChronoField#EPOCH_DAY} and 1460 * {@link ChronoField#NANO_OF_DAY} as the fields. 1461 * <p> 1462 * In most cases, it is clearer to reverse the calling pattern by using 1463 * {@link Temporal#with(TemporalAdjuster)}: 1464 * <pre> 1465 * // these two lines are equivalent, but the second approach is recommended 1466 * temporal = thisLocalDateTime.adjustInto(temporal); 1467 * temporal = temporal.with(thisLocalDateTime); 1468 * </pre> 1469 * <p> 1470 * This instance is immutable and unaffected by this method call. 1471 * 1472 * @param temporal the target object to be adjusted, not null 1473 * @return the adjusted object, not null 1474 * @throws DateTimeException if unable to make the adjustment 1475 * @throws ArithmeticException if numeric overflow occurs 1476 */ 1477 @Override // override for Javadoc 1478 public Temporal adjustInto(Temporal temporal) { 1479 return super.adjustInto(temporal); 1480 } 1481 1482 /** 1483 * Calculates the period between this date-time and another date-time in 1484 * terms of the specified unit. 1485 * <p> 1486 * This calculates the period between two date-times in terms of a single unit. 1487 * The start and end points are {@code this} and the specified date-time. 1488 * The result will be negative if the end is before the start. 1489 * The {@code Temporal} passed to this method must be a {@code LocalDateTime}. 1490 * For example, the period in days between two date-times can be calculated 1491 * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. 1492 * <p> 1493 * The calculation returns a whole number, representing the number of 1494 * complete units between the two date-times. 1495 * For example, the period in months between 2012-06-15T00:00 and 2012-08-14T23:59 1496 * will only be one month as it is one minute short of two months. 1497 * <p> 1498 * This method operates in association with {@link TemporalUnit#between}. 1499 * The result of this method is a {@code long} representing the amount of 1500 * the specified unit. By contrast, the result of {@code between} is an 1501 * object that can be used directly in addition/subtraction: 1502 * <pre> 1503 * long period = start.periodUntil(end, MONTHS); // this method 1504 * dateTime.plus(MONTHS.between(start, end)); // use in plus/minus 1505 * </pre> 1506 * <p> 1507 * The calculation is implemented in this method for {@link ChronoUnit}. 1508 * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS}, 1509 * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS}, 1510 * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES}, 1511 * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported. 1512 * Other {@code ChronoUnit} values will throw an exception. 1513 * <p> 1514 * If the unit is not a {@code ChronoUnit}, then the result of this method 1515 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} 1516 * passing {@code this} as the first argument and the input temporal as 1517 * the second argument. 1518 * <p> 1519 * This instance is immutable and unaffected by this method call. 1520 * 1521 * @param endDateTime the end date-time, which must be a {@code LocalDateTime}, not null 1522 * @param unit the unit to measure the period in, not null 1523 * @return the amount of the period between this date-time and the end date-time 1524 * @throws DateTimeException if the period cannot be calculated 1525 * @throws ArithmeticException if numeric overflow occurs 1526 */ 1527 @Override 1528 public long periodUntil(Temporal endDateTime, TemporalUnit unit) { 1529 if (endDateTime instanceof LocalDateTime == false) { 1530 Objects.requireNonNull(endDateTime, "endDateTime"); 1531 throw new DateTimeException("Unable to calculate period between objects of two different types"); 1532 } 1533 LocalDateTime end = (LocalDateTime) endDateTime; 1534 if (unit instanceof ChronoUnit) { 1535 ChronoUnit f = (ChronoUnit) unit; 1536 if (f.isTimeUnit()) { 1537 long amount = date.daysUntil(end.date); 1538 switch (f) { 1539 case NANOS: amount = Jdk8Methods.safeMultiply(amount, NANOS_PER_DAY); break; 1540 case MICROS: amount = Jdk8Methods.safeMultiply(amount, MICROS_PER_DAY); break; 1541 case MILLIS: amount = Jdk8Methods.safeMultiply(amount, MILLIS_PER_DAY); break; 1542 case SECONDS: amount = Jdk8Methods.safeMultiply(amount, SECONDS_PER_DAY); break; 1543 case MINUTES: amount = Jdk8Methods.safeMultiply(amount, MINUTES_PER_DAY); break; 1544 case HOURS: amount = Jdk8Methods.safeMultiply(amount, HOURS_PER_DAY); break; 1545 case HALF_DAYS: amount = Jdk8Methods.safeMultiply(amount, 2); break; 1546 } 1547 return Jdk8Methods.safeAdd(amount, time.periodUntil(end.time, unit)); 1548 } 1549 LocalDate endDate = end.date; 1550 if (end.time.isBefore(time)) { 1551 endDate = endDate.minusDays(1); 1552 } 1553 return date.periodUntil(endDate, unit); 1554 } 1555 return unit.between(this, endDateTime).getAmount(); 1556 } 1557 1558 //----------------------------------------------------------------------- 1559 /** 1560 * Returns an offset date-time formed from this date-time and the specified offset. 1561 * <p> 1562 * This combines this date-time with the specified offset to form an {@code OffsetDateTime}. 1563 * All possible combinations of date-time and offset are valid. 1564 * <p> 1565 * This instance is immutable and unaffected by this method call. 1566 * 1567 * @param offset the offset to combine with, not null 1568 * @return the offset date-time formed from this date-time and the specified offset, not null 1569 */ 1570 public OffsetDateTime atOffset(ZoneOffset offset) { 1571 return OffsetDateTime.of(this, offset); 1572 } 1573 1574 /** 1575 * Returns a zoned date-time formed from this date-time and the specified time-zone. 1576 * <p> 1577 * This creates a zoned date-time matching the input date-time as closely as possible. 1578 * Time-zone rules, such as daylight savings, mean that not every local date-time 1579 * is valid for the specified zone, thus the local date-time may be adjusted. 1580 * <p> 1581 * The local date-time is resolved to a single instant on the time-line. 1582 * This is achieved by finding a valid offset from UTC/Greenwich for the local 1583 * date-time as defined by the {@link ZoneRules rules} of the zone ID. 1584 *<p> 1585 * In most cases, there is only one valid offset for a local date-time. 1586 * In the case of an overlap, where clocks are set back, there are two valid offsets. 1587 * This method uses the earlier offset typically corresponding to "summer". 1588 * <p> 1589 * In the case of a gap, where clocks jump forward, there is no valid offset. 1590 * Instead, the local date-time is adjusted to be later by the length of the gap. 1591 * For a typical one hour daylight savings change, the local date-time will be 1592 * moved one hour later into the offset typically corresponding to "summer". 1593 * <p> 1594 * To obtain the later offset during an overlap, call 1595 * {@link ZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method. 1596 * To throw an exception when there is a gap or overlap, use 1597 * {@link ZonedDateTime#ofStrict(LocalDateTime, ZoneOffset, ZoneId)}. 1598 * <p> 1599 * This instance is immutable and unaffected by this method call. 1600 * 1601 * @param zone the time-zone to use, not null 1602 * @return the zoned date-time formed from this date-time, not null 1603 */ 1604 @Override 1605 public ZonedDateTime atZone(ZoneId zone) { 1606 return ZonedDateTime.of(this, zone); 1607 } 1608 1609 //----------------------------------------------------------------------- 1610 /** 1611 * Compares this date-time to another date-time. 1612 * <p> 1613 * The comparison is primarily based on the date-time, from earliest to latest. 1614 * It is "consistent with equals", as defined by {@link Comparable}. 1615 * <p> 1616 * If all the date-times being compared are instances of {@code LocalDateTime}, 1617 * then the comparison will be entirely based on the date-time. 1618 * If some dates being compared are in different chronologies, then the 1619 * chronology is also considered, see {@link ChronoLocalDateTime#compareTo}. 1620 * 1621 * @param other the other date-time to compare to, not null 1622 * @return the comparator value, negative if less, positive if greater 1623 */ 1624 @Override // override for Javadoc and performance 1625 public int compareTo(ChronoLocalDateTime<?> other) { 1626 if (other instanceof LocalDateTime) { 1627 return compareTo0((LocalDateTime) other); 1628 } 1629 return super.compareTo(other); 1630 } 1631 1632 private int compareTo0(LocalDateTime other) { 1633 int cmp = date.compareTo0(other.getDate()); 1634 if (cmp == 0) { 1635 cmp = time.compareTo(other.getTime()); 1636 } 1637 return cmp; 1638 } 1639 1640 /** 1641 * Checks if this date-time is after the specified date-time. 1642 * <p> 1643 * This checks to see if this date-time represents a point on the 1644 * local time-line after the other date-time. 1645 * <pre> 1646 * LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00); 1647 * LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00); 1648 * a.isAfter(b) == false 1649 * a.isAfter(a) == false 1650 * b.isAfter(a) == true 1651 * </pre> 1652 * <p> 1653 * This method only considers the position of the two date-times on the local time-line. 1654 * It does not take into account the chronology, or calendar system. 1655 * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)}, 1656 * but is the same approach as {@link #DATE_TIME_COMPARATOR}. 1657 * 1658 * @param other the other date-time to compare to, not null 1659 * @return true if this date-time is after the specified date-time 1660 */ 1661 @Override // override for Javadoc and performance 1662 public boolean isAfter(ChronoLocalDateTime<?> other) { 1663 if (other instanceof LocalDateTime) { 1664 return compareTo0((LocalDateTime) other) > 0; 1665 } 1666 return super.isAfter(other); 1667 } 1668 1669 /** 1670 * Checks if this date-time is before the specified date-time. 1671 * <p> 1672 * This checks to see if this date-time represents a point on the 1673 * local time-line before the other date-time. 1674 * <pre> 1675 * LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00); 1676 * LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00); 1677 * a.isBefore(b) == true 1678 * a.isBefore(a) == false 1679 * b.isBefore(a) == false 1680 * </pre> 1681 * <p> 1682 * This method only considers the position of the two date-times on the local time-line. 1683 * It does not take into account the chronology, or calendar system. 1684 * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)}, 1685 * but is the same approach as {@link #DATE_TIME_COMPARATOR}. 1686 * 1687 * @param other the other date-time to compare to, not null 1688 * @return true if this date-time is before the specified date-time 1689 */ 1690 @Override // override for Javadoc and performance 1691 public boolean isBefore(ChronoLocalDateTime<?> other) { 1692 if (other instanceof LocalDateTime) { 1693 return compareTo0((LocalDateTime) other) < 0; 1694 } 1695 return super.isBefore(other); 1696 } 1697 1698 /** 1699 * Checks if this date-time is equal to the specified date-time. 1700 * <p> 1701 * This checks to see if this date-time represents the same point on the 1702 * local time-line as the other date-time. 1703 * <pre> 1704 * LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00); 1705 * LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00); 1706 * a.isEqual(b) == false 1707 * a.isEqual(a) == true 1708 * b.isEqual(a) == false 1709 * </pre> 1710 * <p> 1711 * This method only considers the position of the two date-times on the local time-line. 1712 * It does not take into account the chronology, or calendar system. 1713 * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)}, 1714 * but is the same approach as {@link #DATE_TIME_COMPARATOR}. 1715 * 1716 * @param other the other date-time to compare to, not null 1717 * @return true if this date-time is equal to the specified date-time 1718 */ 1719 @Override // override for Javadoc and performance 1720 public boolean isEqual(ChronoLocalDateTime<?> other) { 1721 if (other instanceof LocalDateTime) { 1722 return compareTo0((LocalDateTime) other) == 0; 1723 } 1724 return super.isEqual(other); 1725 } 1726 1727 //----------------------------------------------------------------------- 1728 /** 1729 * Checks if this date-time is equal to another date-time. 1730 * <p> 1731 * Compares this {@code LocalDateTime} with another ensuring that the date-time is the same. 1732 * Only objects of type {@code LocalDateTime} are compared, other types return false. 1733 * 1734 * @param obj the object to check, null returns false 1735 * @return true if this is equal to the other date-time 1736 */ 1737 @Override 1738 public boolean equals(Object obj) { 1739 if (this == obj) { 1740 return true; 1741 } 1742 if (obj instanceof LocalDateTime) { 1743 LocalDateTime other = (LocalDateTime) obj; 1744 return date.equals(other.date) && time.equals(other.time); 1745 } 1746 return false; 1747 } 1748 1749 /** 1750 * A hash code for this date-time. 1751 * 1752 * @return a suitable hash code 1753 */ 1754 @Override 1755 public int hashCode() { 1756 return date.hashCode() ^ time.hashCode(); 1757 } 1758 1759 //----------------------------------------------------------------------- 1760 /** 1761 * Outputs this date-time as a {@code String}, such as {@code 2007-12-03T10:15:30}. 1762 * <p> 1763 * The output will be one of the following ISO-8601 formats: 1764 * <p><ul> 1765 * <li>{@code yyyy-MM-dd'T'HH:mm}</li> 1766 * <li>{@code yyyy-MM-dd'T'HH:mm:ss}</li> 1767 * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSS}</li> 1768 * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSS}</li> 1769 * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS}</li> 1770 * </ul><p> 1771 * The format used will be the shortest that outputs the full value of 1772 * the time where the omitted parts are implied to be zero. 1773 * 1774 * @return a string representation of this date-time, not null 1775 */ 1776 @Override 1777 public String toString() { 1778 return date.toString() + 'T' + time.toString(); 1779 } 1780 1781 /** 1782 * Outputs this date-time as a {@code String} using the formatter. 1783 * <p> 1784 * This date-time will be passed to the formatter 1785 * {@link DateTimeFormatter#print(TemporalAccessor) print method}. 1786 * 1787 * @param formatter the formatter to use, not null 1788 * @return the formatted date-time string, not null 1789 * @throws DateTimeException if an error occurs during printing 1790 */ 1791 @Override // override for Javadoc 1792 public String toString(DateTimeFormatter formatter) { 1793 return super.toString(formatter); 1794 } 1795 1796 //----------------------------------------------------------------------- 1797 private Object writeReplace() { 1798 return new Ser(Ser.LOCAL_DATE_TIME_TYPE, this); 1799 } 1800 1801 /** 1802 * Defend against malicious streams. 1803 * @return never 1804 * @throws InvalidObjectException always 1805 */ 1806 private Object readResolve() throws ObjectStreamException { 1807 throw new InvalidObjectException("Deserialization via serialization delegate"); 1808 } 1809 1810 void writeExternal(DataOutput out) throws IOException { 1811 date.writeExternal(out); 1812 time.writeExternal(out); 1813 } 1814 1815 static LocalDateTime readExternal(DataInput in) throws IOException { 1816 LocalDate date = LocalDate.readExternal(in); 1817 LocalTime time = LocalTime.readExternal(in); 1818 return LocalDateTime.of(date, time); 1819 } 1820 1821}