001 /* 002 * Copyright 2001-2011 Stephen Colebourne 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.joda.time; 017 018 import java.io.IOException; 019 import java.io.ObjectInputStream; 020 import java.io.ObjectOutputStream; 021 import java.io.Serializable; 022 import java.util.Calendar; 023 import java.util.Date; 024 import java.util.Locale; 025 import java.util.TimeZone; 026 027 import org.joda.convert.FromString; 028 import org.joda.convert.ToString; 029 import org.joda.time.base.BaseLocal; 030 import org.joda.time.chrono.ISOChronology; 031 import org.joda.time.convert.ConverterManager; 032 import org.joda.time.convert.PartialConverter; 033 import org.joda.time.field.AbstractReadableInstantFieldProperty; 034 import org.joda.time.format.DateTimeFormat; 035 import org.joda.time.format.DateTimeFormatter; 036 import org.joda.time.format.ISODateTimeFormat; 037 038 /** 039 * LocalDateTime is an unmodifiable datetime class representing a 040 * datetime without a time zone. 041 * <p> 042 * LocalDateTime implements the {@link ReadablePartial} interface. 043 * To do this, certain methods focus on key fields Year, MonthOfYear, 044 * DayOfYear and MillisOfDay. 045 * However, <b>all</b> fields may in fact be queried. 046 * <p> 047 * Internally, LocalDateTime uses a single millisecond-based value to 048 * represent the local datetime. This value is only used internally and 049 * is not exposed to applications. 050 * <p> 051 * Calculations on LocalDateTime are performed using a {@link Chronology}. 052 * This chronology will be set internally to be in the UTC time zone 053 * for all calculations. 054 * 055 * <p>Each individual field can be queried in two ways: 056 * <ul> 057 * <li><code>getHourOfDay()</code> 058 * <li><code>hourOfDay().get()</code> 059 * </ul> 060 * The second technique also provides access to other useful methods on the 061 * field: 062 * <ul> 063 * <li>numeric value 064 * <li>text value 065 * <li>short text value 066 * <li>maximum/minimum values 067 * <li>add/subtract 068 * <li>set 069 * <li>rounding 070 * </ul> 071 * 072 * <p> 073 * LocalDateTime is thread-safe and immutable, provided that the Chronology is as well. 074 * All standard Chronology classes supplied are thread-safe and immutable. 075 * 076 * @author Stephen Colebourne 077 * @since 1.3 078 */ 079 public final class LocalDateTime 080 extends BaseLocal 081 implements ReadablePartial, Serializable { 082 083 /** Serialization lock */ 084 private static final long serialVersionUID = -268716875315837168L; 085 086 /** The index of the year field in the field array */ 087 private static final int YEAR = 0; 088 /** The index of the monthOfYear field in the field array */ 089 private static final int MONTH_OF_YEAR = 1; 090 /** The index of the dayOfMonth field in the field array */ 091 private static final int DAY_OF_MONTH = 2; 092 /** The index of the millis field in the field array */ 093 private static final int MILLIS_OF_DAY = 3; 094 095 /** The local millis from 1970-01-01T00:00:00 */ 096 private final long iLocalMillis; 097 /** The chronology to use in UTC */ 098 private final Chronology iChronology; 099 100 //----------------------------------------------------------------------- 101 /** 102 * Obtains a {@code LocalDateTime} set to the current system millisecond time 103 * using <code>ISOChronology</code> in the default time zone. 104 * The resulting object does not use the zone. 105 * 106 * @return the current date, not null 107 * @since 2.0 108 */ 109 public static LocalDateTime now() { 110 return new LocalDateTime(); 111 } 112 113 /** 114 * Obtains a {@code LocalDateTime} set to the current system millisecond time 115 * using <code>ISOChronology</code> in the specified time zone. 116 * The resulting object does not use the zone. 117 * 118 * @param zone the time zone, not null 119 * @return the current date, not null 120 * @since 2.0 121 */ 122 public static LocalDateTime now(DateTimeZone zone) { 123 if (zone == null) { 124 throw new NullPointerException("Zone must not be null"); 125 } 126 return new LocalDateTime(zone); 127 } 128 129 /** 130 * Obtains a {@code LocalDateTime} set to the current system millisecond time 131 * using the specified chronology. 132 * The resulting object does not use the zone. 133 * 134 * @param chronology the chronology, not null 135 * @return the current date, not null 136 * @since 2.0 137 */ 138 public static LocalDateTime now(Chronology chronology) { 139 if (chronology == null) { 140 throw new NullPointerException("Chronology must not be null"); 141 } 142 return new LocalDateTime(chronology); 143 } 144 145 //----------------------------------------------------------------------- 146 /** 147 * Parses a {@code LocalDateTime} from the specified string. 148 * <p> 149 * This uses {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 150 * 151 * @param str the string to parse, not null 152 * @since 2.0 153 */ 154 @FromString 155 public static LocalDateTime parse(String str) { 156 return parse(str, ISODateTimeFormat.localDateOptionalTimeParser()); 157 } 158 159 /** 160 * Parses a {@code LocalDateTime} from the specified string using a formatter. 161 * 162 * @param str the string to parse, not null 163 * @param formatter the formatter to use, not null 164 * @since 2.0 165 */ 166 public static LocalDateTime parse(String str, DateTimeFormatter formatter) { 167 return formatter.parseLocalDateTime(str); 168 } 169 170 //----------------------------------------------------------------------- 171 /** 172 * Constructs a LocalDateTime from a <code>java.util.Calendar</code> 173 * using exactly the same field values. 174 * <p> 175 * Each field is queried from the Calendar and assigned to the LocalDateTime. 176 * This is useful if you have been using the Calendar as a local date, 177 * ignoring the zone. 178 * <p> 179 * One advantage of this method is that this method is unaffected if the 180 * version of the time zone data differs between the JDK and Joda-Time. 181 * That is because the local field values are transferred, calculated using 182 * the JDK time zone data and without using the Joda-Time time zone data. 183 * <p> 184 * This factory method ignores the type of the calendar and always 185 * creates a LocalDateTime with ISO chronology. It is expected that you 186 * will only pass in instances of <code>GregorianCalendar</code> however 187 * this is not validated. 188 * 189 * @param calendar the Calendar to extract fields from 190 * @return the created LocalDateTime 191 * @throws IllegalArgumentException if the calendar is null 192 * @throws IllegalArgumentException if the date is invalid for the ISO chronology 193 */ 194 public static LocalDateTime fromCalendarFields(Calendar calendar) { 195 if (calendar == null) { 196 throw new IllegalArgumentException("The calendar must not be null"); 197 } 198 return new LocalDateTime( 199 calendar.get(Calendar.YEAR), 200 calendar.get(Calendar.MONTH) + 1, 201 calendar.get(Calendar.DAY_OF_MONTH), 202 calendar.get(Calendar.HOUR_OF_DAY), 203 calendar.get(Calendar.MINUTE), 204 calendar.get(Calendar.SECOND), 205 calendar.get(Calendar.MILLISECOND) 206 ); 207 } 208 209 /** 210 * Constructs a LocalDateTime from a <code>java.util.Date</code> 211 * using exactly the same field values. 212 * <p> 213 * Each field is queried from the Date and assigned to the LocalDateTime. 214 * This is useful if you have been using the Date as a local date, 215 * ignoring the zone. 216 * <p> 217 * One advantage of this method is that this method is unaffected if the 218 * version of the time zone data differs between the JDK and Joda-Time. 219 * That is because the local field values are transferred, calculated using 220 * the JDK time zone data and without using the Joda-Time time zone data. 221 * <p> 222 * This factory method always creates a LocalDateTime with ISO chronology. 223 * 224 * @param date the Date to extract fields from 225 * @return the created LocalDateTime 226 * @throws IllegalArgumentException if the calendar is null 227 * @throws IllegalArgumentException if the date is invalid for the ISO chronology 228 */ 229 @SuppressWarnings("deprecation") 230 public static LocalDateTime fromDateFields(Date date) { 231 if (date == null) { 232 throw new IllegalArgumentException("The date must not be null"); 233 } 234 return new LocalDateTime( 235 date.getYear() + 1900, 236 date.getMonth() + 1, 237 date.getDate(), 238 date.getHours(), 239 date.getMinutes(), 240 date.getSeconds(), 241 (int) (date.getTime() % 1000) 242 ); 243 } 244 245 //----------------------------------------------------------------------- 246 /** 247 * Constructs an instance set to the current local time evaluated using 248 * ISO chronology in the default zone. 249 * <p> 250 * Once the constructor is completed, the zone is no longer used. 251 * 252 * @see #now() 253 */ 254 public LocalDateTime() { 255 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance()); 256 } 257 258 /** 259 * Constructs an instance set to the current local time evaluated using 260 * ISO chronology in the specified zone. 261 * <p> 262 * If the specified time zone is null, the default zone is used. 263 * Once the constructor is completed, the zone is no longer used. 264 * 265 * @param zone the time zone, null means default zone 266 * @see #now(DateTimeZone) 267 */ 268 public LocalDateTime(DateTimeZone zone) { 269 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone)); 270 } 271 272 /** 273 * Constructs an instance set to the current local time evaluated using 274 * specified chronology. 275 * <p> 276 * If the chronology is null, ISO chronology in the default time zone is used. 277 * Once the constructor is completed, the zone is no longer used. 278 * 279 * @param chronology the chronology, null means ISOChronology in default zone 280 * @see #now(Chronology) 281 */ 282 public LocalDateTime(Chronology chronology) { 283 this(DateTimeUtils.currentTimeMillis(), chronology); 284 } 285 286 //----------------------------------------------------------------------- 287 /** 288 * Constructs an instance set to the local time defined by the specified 289 * instant evaluated using ISO chronology in the default zone. 290 * <p> 291 * Once the constructor is completed, the zone is no longer used. 292 * 293 * @param instant the milliseconds from 1970-01-01T00:00:00Z 294 */ 295 public LocalDateTime(long instant) { 296 this(instant, ISOChronology.getInstance()); 297 } 298 299 /** 300 * Constructs an instance set to the local time defined by the specified 301 * instant evaluated using ISO chronology in the specified zone. 302 * <p> 303 * If the specified time zone is null, the default zone is used. 304 * Once the constructor is completed, the zone is no longer used. 305 * 306 * @param instant the milliseconds from 1970-01-01T00:00:00Z 307 * @param zone the time zone, null means default zone 308 */ 309 public LocalDateTime(long instant, DateTimeZone zone) { 310 this(instant, ISOChronology.getInstance(zone)); 311 } 312 313 /** 314 * Constructs an instance set to the local time defined by the specified 315 * instant evaluated using the specified chronology. 316 * <p> 317 * If the chronology is null, ISO chronology in the default zone is used. 318 * Once the constructor is completed, the zone is no longer used. 319 * 320 * @param instant the milliseconds from 1970-01-01T00:00:00Z 321 * @param chronology the chronology, null means ISOChronology in default zone 322 */ 323 public LocalDateTime(long instant, Chronology chronology) { 324 chronology = DateTimeUtils.getChronology(chronology); 325 326 long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant); 327 iLocalMillis = localMillis; 328 iChronology = chronology.withUTC(); 329 } 330 331 //----------------------------------------------------------------------- 332 /** 333 * Constructs an instance from an Object that represents a datetime. 334 * <p> 335 * If the object contains no chronology, <code>ISOChronology</code> is used. 336 * If the object contains no time zone, the default zone is used. 337 * Once the constructor is completed, the zone is no longer used. 338 * <p> 339 * The recognised object types are defined in 340 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 341 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 342 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 343 * The default String converter ignores the zone and only parses the field values. 344 * 345 * @param instant the datetime object 346 * @throws IllegalArgumentException if the instant is invalid 347 */ 348 public LocalDateTime(Object instant) { 349 this(instant, (Chronology) null); 350 } 351 352 /** 353 * Constructs an instance from an Object that represents a datetime, 354 * forcing the time zone to that specified. 355 * <p> 356 * If the object contains no chronology, <code>ISOChronology</code> is used. 357 * If the specified time zone is null, the default zone is used. 358 * Once the constructor is completed, the zone is no longer used. 359 * <p> 360 * The recognised object types are defined in 361 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 362 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 363 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 364 * The default String converter ignores the zone and only parses the field values. 365 * 366 * @param instant the datetime object 367 * @param zone the time zone 368 * @throws IllegalArgumentException if the instant is invalid 369 */ 370 public LocalDateTime(Object instant, DateTimeZone zone) { 371 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 372 Chronology chronology = converter.getChronology(instant, zone); 373 chronology = DateTimeUtils.getChronology(chronology); 374 iChronology = chronology.withUTC(); 375 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser()); 376 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]); 377 } 378 379 /** 380 * Constructs an instance from an Object that represents a datetime, 381 * using the specified chronology. 382 * <p> 383 * If the chronology is null, ISO in the default time zone is used. 384 * Once the constructor is completed, the zone is no longer used. 385 * <p> 386 * The recognised object types are defined in 387 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 388 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 389 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 390 * The default String converter ignores the zone and only parses the field values. 391 * 392 * @param instant the datetime object 393 * @param chronology the chronology 394 * @throws IllegalArgumentException if the instant is invalid 395 */ 396 public LocalDateTime(Object instant, Chronology chronology) { 397 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 398 chronology = converter.getChronology(instant, chronology); 399 chronology = DateTimeUtils.getChronology(chronology); 400 iChronology = chronology.withUTC(); 401 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser()); 402 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]); 403 } 404 405 //----------------------------------------------------------------------- 406 /** 407 * Constructs an instance set to the specified date and time 408 * using <code>ISOChronology</code>. 409 * 410 * @param year the year 411 * @param monthOfYear the month of the year 412 * @param dayOfMonth the day of the month 413 * @param hourOfDay the hour of the day 414 * @param minuteOfHour the minute of the hour 415 */ 416 public LocalDateTime( 417 int year, 418 int monthOfYear, 419 int dayOfMonth, 420 int hourOfDay, 421 int minuteOfHour) { 422 this(year, monthOfYear, dayOfMonth, hourOfDay, 423 minuteOfHour, 0, 0, ISOChronology.getInstanceUTC()); 424 } 425 426 /** 427 * Constructs an instance set to the specified date and time 428 * using <code>ISOChronology</code>. 429 * 430 * @param year the year 431 * @param monthOfYear the month of the year 432 * @param dayOfMonth the day of the month 433 * @param hourOfDay the hour of the day 434 * @param minuteOfHour the minute of the hour 435 * @param secondOfMinute the second of the minute 436 */ 437 public LocalDateTime( 438 int year, 439 int monthOfYear, 440 int dayOfMonth, 441 int hourOfDay, 442 int minuteOfHour, 443 int secondOfMinute) { 444 this(year, monthOfYear, dayOfMonth, hourOfDay, 445 minuteOfHour, secondOfMinute, 0, ISOChronology.getInstanceUTC()); 446 } 447 448 /** 449 * Constructs an instance set to the specified date and time 450 * using <code>ISOChronology</code>. 451 * 452 * @param year the year 453 * @param monthOfYear the month of the year 454 * @param dayOfMonth the day of the month 455 * @param hourOfDay the hour of the day 456 * @param minuteOfHour the minute of the hour 457 * @param secondOfMinute the second of the minute 458 * @param millisOfSecond the millisecond of the second 459 */ 460 public LocalDateTime( 461 int year, 462 int monthOfYear, 463 int dayOfMonth, 464 int hourOfDay, 465 int minuteOfHour, 466 int secondOfMinute, 467 int millisOfSecond) { 468 this(year, monthOfYear, dayOfMonth, hourOfDay, 469 minuteOfHour, secondOfMinute, millisOfSecond, ISOChronology.getInstanceUTC()); 470 } 471 472 /** 473 * Constructs an instance set to the specified date and time 474 * using the specified chronology, whose zone is ignored. 475 * <p> 476 * If the chronology is null, <code>ISOChronology</code> is used. 477 * 478 * @param year the year 479 * @param monthOfYear the month of the year 480 * @param dayOfMonth the day of the month 481 * @param hourOfDay the hour of the day 482 * @param minuteOfHour the minute of the hour 483 * @param secondOfMinute the second of the minute 484 * @param millisOfSecond the millisecond of the second 485 * @param chronology the chronology, null means ISOChronology in default zone 486 */ 487 public LocalDateTime( 488 int year, 489 int monthOfYear, 490 int dayOfMonth, 491 int hourOfDay, 492 int minuteOfHour, 493 int secondOfMinute, 494 int millisOfSecond, 495 Chronology chronology) { 496 super(); 497 chronology = DateTimeUtils.getChronology(chronology).withUTC(); 498 long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, 499 hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond); 500 iChronology = chronology; 501 iLocalMillis = instant; 502 } 503 504 /** 505 * Handle broken serialization from other tools. 506 * @return the resolved object, not null 507 */ 508 private Object readResolve() { 509 if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) { 510 return new LocalDateTime(iLocalMillis, iChronology.withUTC()); 511 } 512 return this; 513 } 514 515 //----------------------------------------------------------------------- 516 /** 517 * Gets the number of fields in this partial, which is four. 518 * The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 519 * 520 * @return the field count, four 521 */ 522 public int size() { 523 return 4; 524 } 525 526 /** 527 * Gets the field for a specific index in the chronology specified. 528 * <p> 529 * This method must not use any instance variables. 530 * 531 * @param index the index to retrieve 532 * @param chrono the chronology to use 533 * @return the field 534 */ 535 protected DateTimeField getField(int index, Chronology chrono) { 536 switch (index) { 537 case YEAR: 538 return chrono.year(); 539 case MONTH_OF_YEAR: 540 return chrono.monthOfYear(); 541 case DAY_OF_MONTH: 542 return chrono.dayOfMonth(); 543 case MILLIS_OF_DAY: 544 return chrono.millisOfDay(); 545 default: 546 throw new IndexOutOfBoundsException("Invalid index: " + index); 547 } 548 } 549 550 /** 551 * Gets the value of the field at the specifed index. 552 * <p> 553 * This method is required to support the <code>ReadablePartial</code> 554 * interface. The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 555 * 556 * @param index the index, zero to two 557 * @return the value 558 * @throws IndexOutOfBoundsException if the index is invalid 559 */ 560 public int getValue(int index) { 561 switch (index) { 562 case YEAR: 563 return getChronology().year().get(getLocalMillis()); 564 case MONTH_OF_YEAR: 565 return getChronology().monthOfYear().get(getLocalMillis()); 566 case DAY_OF_MONTH: 567 return getChronology().dayOfMonth().get(getLocalMillis()); 568 case MILLIS_OF_DAY: 569 return getChronology().millisOfDay().get(getLocalMillis()); 570 default: 571 throw new IndexOutOfBoundsException("Invalid index: " + index); 572 } 573 } 574 575 //----------------------------------------------------------------------- 576 /** 577 * Get the value of one of the fields of a datetime. 578 * <p> 579 * This method gets the value of the specified field. 580 * For example: 581 * <pre> 582 * DateTime dt = new DateTime(); 583 * int year = dt.get(DateTimeFieldType.year()); 584 * </pre> 585 * 586 * @param type a field type, usually obtained from DateTimeFieldType, not null 587 * @return the value of that field 588 * @throws IllegalArgumentException if the field type is null 589 */ 590 public int get(DateTimeFieldType type) { 591 if (type == null) { 592 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 593 } 594 return type.getField(getChronology()).get(getLocalMillis()); 595 } 596 597 /** 598 * Checks if the field type specified is supported by this 599 * local datetime and chronology. 600 * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}. 601 * 602 * @param type a field type, usually obtained from DateTimeFieldType 603 * @return true if the field type is supported 604 */ 605 public boolean isSupported(DateTimeFieldType type) { 606 if (type == null) { 607 return false; 608 } 609 return type.getField(getChronology()).isSupported(); 610 } 611 612 /** 613 * Checks if the duration type specified is supported by this 614 * local datetime and chronology. 615 * 616 * @param type a duration type, usually obtained from DurationFieldType 617 * @return true if the field type is supported 618 */ 619 public boolean isSupported(DurationFieldType type) { 620 if (type == null) { 621 return false; 622 } 623 return type.getField(getChronology()).isSupported(); 624 } 625 626 //----------------------------------------------------------------------- 627 /** 628 * Gets the milliseconds of the datetime instant from the Java epoch 629 * of 1970-01-01T00:00:00 (not fixed to any specific time zone). 630 * 631 * @return the number of milliseconds since 1970-01-01T00:00:00 632 * @since 1.5 (previously private) 633 */ 634 protected long getLocalMillis() { 635 return iLocalMillis; 636 } 637 638 /** 639 * Gets the chronology of the datetime. 640 * 641 * @return the Chronology that the datetime is using 642 */ 643 public Chronology getChronology() { 644 return iChronology; 645 } 646 647 //----------------------------------------------------------------------- 648 /** 649 * Compares this ReadablePartial with another returning true if the chronology, 650 * field types and values are equal. 651 * 652 * @param partial an object to check against 653 * @return true if fields and values are equal 654 */ 655 public boolean equals(Object partial) { 656 // override to perform faster 657 if (this == partial) { 658 return true; 659 } 660 if (partial instanceof LocalDateTime) { 661 LocalDateTime other = (LocalDateTime) partial; 662 if (iChronology.equals(other.iChronology)) { 663 return iLocalMillis == other.iLocalMillis; 664 } 665 } 666 return super.equals(partial); 667 } 668 669 /** 670 * Compares this partial with another returning an integer 671 * indicating the order. 672 * <p> 673 * The fields are compared in order, from largest to smallest. 674 * The first field that is non-equal is used to determine the result. 675 * <p> 676 * The specified object must be a partial instance whose field types 677 * match those of this partial. 678 * 679 * @param partial an object to check against 680 * @return negative if this is less, zero if equal, positive if greater 681 * @throws ClassCastException if the partial is the wrong class 682 * or if it has field types that don't match 683 * @throws NullPointerException if the partial is null 684 */ 685 public int compareTo(ReadablePartial partial) { 686 // override to perform faster 687 if (this == partial) { 688 return 0; 689 } 690 if (partial instanceof LocalDateTime) { 691 LocalDateTime other = (LocalDateTime) partial; 692 if (iChronology.equals(other.iChronology)) { 693 return (iLocalMillis < other.iLocalMillis ? -1 : 694 (iLocalMillis == other.iLocalMillis ? 0 : 1)); 695 696 } 697 } 698 return super.compareTo(partial); 699 } 700 701 //----------------------------------------------------------------------- 702 /** 703 * Converts this object to a DateTime using the default zone. 704 * <p> 705 * This method will throw an exception if the datetime that would be 706 * created does not exist when the time zone is taken into account. 707 * 708 * @return <code>this</code> 709 */ 710 public DateTime toDateTime() { 711 return toDateTime((DateTimeZone) null); 712 } 713 714 /** 715 * Converts this object to a DateTime using the specified zone. 716 * <p> 717 * This method will throw an exception if the datetime that would be 718 * created does not exist when the time zone is taken into account. 719 * 720 * @param zone time zone to apply, or default if null 721 * @return a DateTime using the same millis 722 */ 723 public DateTime toDateTime(DateTimeZone zone) { 724 zone = DateTimeUtils.getZone(zone); 725 Chronology chrono = iChronology.withZone(zone); 726 return new DateTime( 727 getYear(), getMonthOfYear(), getDayOfMonth(), 728 getHourOfDay(), getMinuteOfHour(), 729 getSecondOfMinute(), getMillisOfSecond(), chrono); 730 } 731 732 //----------------------------------------------------------------------- 733 /** 734 * Converts this object to a LocalDate with the same date and chronology. 735 * 736 * @return a LocalDate with the same date and chronology 737 */ 738 public LocalDate toLocalDate() { 739 return new LocalDate(getLocalMillis(), getChronology()); 740 } 741 742 /** 743 * Converts this object to a LocalTime with the same time and chronology. 744 * 745 * @return a LocalTime with the same time and chronology 746 */ 747 public LocalTime toLocalTime() { 748 return new LocalTime(getLocalMillis(), getChronology()); 749 } 750 751 //----------------------------------------------------------------------- 752 /** 753 * Get the date time as a <code>java.util.Date</code>. 754 * <p> 755 * The <code>Date</code> object created has exactly the same fields as this 756 * date-time, except when the time would be invalid due to a daylight savings 757 * gap. In that case, the time will be set to the earliest valid time after the gap. 758 * <p> 759 * In the case of a daylight savings overlap, the earlier instant is selected. 760 * <p> 761 * Converting to a JDK Date is full of complications as the JDK Date constructor 762 * doesn't behave as you might expect around DST transitions. This method works 763 * by taking a first guess and then adjusting. This also handles the situation 764 * where the JDK time zone data differs from the Joda-Time time zone data. 765 * 766 * @return a Date initialised with this date-time, never null 767 * @since 2.0 768 */ 769 @SuppressWarnings("deprecation") 770 public Date toDate() { 771 int dom = getDayOfMonth(); 772 Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom, 773 getHourOfDay(), getMinuteOfHour(), getSecondOfMinute()); 774 date.setTime(date.getTime() + getMillisOfSecond()); 775 LocalDateTime check = LocalDateTime.fromDateFields(date); 776 if (check.isBefore(this)) { 777 // DST gap 778 // move forward in units of one minute until equal/after 779 while (check.isBefore(this)) { 780 date.setTime(date.getTime() + 60000); 781 check = LocalDateTime.fromDateFields(date); 782 } 783 // move back in units of one second until date wrong 784 while (check.isBefore(this) == false) { 785 date.setTime(date.getTime() - 1000); 786 check = LocalDateTime.fromDateFields(date); 787 } 788 date.setTime(date.getTime() + 1000); 789 } else if (check.equals(this)) { 790 // check for DST overlap 791 Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings()); 792 check = LocalDateTime.fromDateFields(earlier); 793 if (check.equals(this)) { 794 date = earlier; 795 } 796 } 797 return date; 798 } 799 800 //----------------------------------------------------------------------- 801 /** 802 * Returns a copy of this datetime with different local millis. 803 * <p> 804 * The returned object will be a new instance of the same type. 805 * Only the millis will change, the chronology is kept. 806 * The returned object will be either be a new instance or <code>this</code>. 807 * 808 * @param newMillis the new millis, from 1970-01-01T00:00:00 809 * @return a copy of this datetime with different millis 810 */ 811 LocalDateTime withLocalMillis(long newMillis) { 812 return (newMillis == getLocalMillis() ? this : new LocalDateTime(newMillis, getChronology())); 813 } 814 815 //----------------------------------------------------------------------- 816 /** 817 * Returns a copy of this datetime with the specified date, 818 * retaining the time fields. 819 * <p> 820 * If the date is already the date passed in, then <code>this</code> is returned. 821 * <p> 822 * To set a single field use the properties, for example: 823 * <pre> 824 * DateTime set = dt.monthOfYear().setCopy(6); 825 * </pre> 826 * 827 * @param year the new year value 828 * @param monthOfYear the new monthOfYear value 829 * @param dayOfMonth the new dayOfMonth value 830 * @return a copy of this datetime with a different date 831 * @throws IllegalArgumentException if any value if invalid 832 */ 833 public LocalDateTime withDate(int year, int monthOfYear, int dayOfMonth) { 834 Chronology chrono = getChronology(); 835 long instant = getLocalMillis(); 836 instant = chrono.year().set(instant, year); 837 instant = chrono.monthOfYear().set(instant, monthOfYear); 838 instant = chrono.dayOfMonth().set(instant, dayOfMonth); 839 return withLocalMillis(instant); 840 } 841 842 /** 843 * Returns a copy of this datetime with the specified time, 844 * retaining the date fields. 845 * <p> 846 * If the time is already the time passed in, then <code>this</code> is returned. 847 * <p> 848 * To set a single field use the properties, for example: 849 * <pre> 850 * LocalDateTime set = dt.hourOfDay().setCopy(6); 851 * </pre> 852 * 853 * @param hourOfDay the hour of the day 854 * @param minuteOfHour the minute of the hour 855 * @param secondOfMinute the second of the minute 856 * @param millisOfSecond the millisecond of the second 857 * @return a copy of this datetime with a different time 858 * @throws IllegalArgumentException if any value if invalid 859 */ 860 public LocalDateTime withTime(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) { 861 Chronology chrono = getChronology(); 862 long instant = getLocalMillis(); 863 instant = chrono.hourOfDay().set(instant, hourOfDay); 864 instant = chrono.minuteOfHour().set(instant, minuteOfHour); 865 instant = chrono.secondOfMinute().set(instant, secondOfMinute); 866 instant = chrono.millisOfSecond().set(instant, millisOfSecond); 867 return withLocalMillis(instant); 868 } 869 870 //----------------------------------------------------------------------- 871 /** 872 * Returns a copy of this datetime with the partial set of fields 873 * replacing those from this instance. 874 * <p> 875 * For example, if the partial is a <code>TimeOfDay</code> then the time fields 876 * would be changed in the returned instance. 877 * If the partial is null, then <code>this</code> is returned. 878 * 879 * @param partial the partial set of fields to apply to this datetime, null ignored 880 * @return a copy of this datetime with a different set of fields 881 * @throws IllegalArgumentException if any value is invalid 882 */ 883 public LocalDateTime withFields(ReadablePartial partial) { 884 if (partial == null) { 885 return this; 886 } 887 return withLocalMillis(getChronology().set(partial, getLocalMillis())); 888 } 889 890 /** 891 * Returns a copy of this datetime with the specified field set to a new value. 892 * <p> 893 * For example, if the field type is <code>hourOfDay</code> then the hour of day 894 * field would be changed in the returned instance. 895 * If the field type is null, then <code>this</code> is returned. 896 * <p> 897 * These three lines are equivalent: 898 * <pre> 899 * LocalDateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6); 900 * LocalDateTime updated = dt.dayOfMonth().setCopy(6); 901 * LocalDateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6); 902 * </pre> 903 * 904 * @param fieldType the field type to set, not null 905 * @param value the value to set 906 * @return a copy of this datetime with the field set 907 * @throws IllegalArgumentException if the value is null or invalid 908 */ 909 public LocalDateTime withField(DateTimeFieldType fieldType, int value) { 910 if (fieldType == null) { 911 throw new IllegalArgumentException("Field must not be null"); 912 } 913 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value); 914 return withLocalMillis(instant); 915 } 916 917 /** 918 * Returns a copy of this datetime with the value of the specified 919 * field increased. 920 * <p> 921 * If the addition is zero or the field is null, then <code>this</code> is returned. 922 * <p> 923 * These three lines are equivalent: 924 * <pre> 925 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 926 * LocalDateTime added = dt.plusYears(6); 927 * LocalDateTime added = dt.plus(Period.years(6)); 928 * </pre> 929 * 930 * @param fieldType the field type to add to, not null 931 * @param amount the amount to add 932 * @return a copy of this datetime with the field updated 933 * @throws IllegalArgumentException if the value is null or invalid 934 * @throws ArithmeticException if the result exceeds the internal capacity 935 */ 936 public LocalDateTime withFieldAdded(DurationFieldType fieldType, int amount) { 937 if (fieldType == null) { 938 throw new IllegalArgumentException("Field must not be null"); 939 } 940 if (amount == 0) { 941 return this; 942 } 943 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount); 944 return withLocalMillis(instant); 945 } 946 947 //----------------------------------------------------------------------- 948 /** 949 * Returns a copy of this datetime with the specified duration added. 950 * <p> 951 * If the addition is zero, then <code>this</code> is returned. 952 * 953 * @param durationToAdd the duration to add to this one, null means zero 954 * @param scalar the amount of times to add, such as -1 to subtract once 955 * @return a copy of this datetime with the duration added 956 * @throws ArithmeticException if the result exceeds the internal capacity 957 */ 958 public LocalDateTime withDurationAdded(ReadableDuration durationToAdd, int scalar) { 959 if (durationToAdd == null || scalar == 0) { 960 return this; 961 } 962 long instant = getChronology().add(getLocalMillis(), durationToAdd.getMillis(), scalar); 963 return withLocalMillis(instant); 964 } 965 966 /** 967 * Returns a copy of this datetime with the specified period added. 968 * <p> 969 * If the addition is zero, then <code>this</code> is returned. 970 * <p> 971 * This method is typically used to add multiple copies of complex 972 * period instances. Adding one field is best achieved using methods 973 * like {@link #withFieldAdded(DurationFieldType, int)} 974 * or {@link #plusYears(int)}. 975 * 976 * @param period the period to add to this one, null means zero 977 * @param scalar the amount of times to add, such as -1 to subtract once 978 * @return a copy of this datetime with the period added 979 * @throws ArithmeticException if the result exceeds the internal capacity 980 */ 981 public LocalDateTime withPeriodAdded(ReadablePeriod period, int scalar) { 982 if (period == null || scalar == 0) { 983 return this; 984 } 985 long instant = getChronology().add(period, getLocalMillis(), scalar); 986 return withLocalMillis(instant); 987 } 988 989 //----------------------------------------------------------------------- 990 /** 991 * Returns a copy of this datetime with the specified duration added. 992 * <p> 993 * If the amount is zero or null, then <code>this</code> is returned. 994 * 995 * @param duration the duration to add to this one, null means zero 996 * @return a copy of this datetime with the duration added 997 * @throws ArithmeticException if the result exceeds the internal capacity 998 */ 999 public LocalDateTime plus(ReadableDuration duration) { 1000 return withDurationAdded(duration, 1); 1001 } 1002 1003 /** 1004 * Returns a copy of this datetime with the specified period added. 1005 * <p> 1006 * If the amount is zero or null, then <code>this</code> is returned. 1007 * <p> 1008 * This method is typically used to add complex period instances. 1009 * Adding one field is best achieved using methods 1010 * like {@link #plusYears(int)}. 1011 * 1012 * @param period the period to add to this one, null means zero 1013 * @return a copy of this datetime with the period added 1014 * @throws ArithmeticException if the result exceeds the internal capacity 1015 */ 1016 public LocalDateTime plus(ReadablePeriod period) { 1017 return withPeriodAdded(period, 1); 1018 } 1019 1020 //----------------------------------------------------------------------- 1021 /** 1022 * Returns a copy of this datetime plus the specified number of years. 1023 * <p> 1024 * This LocalDateTime instance is immutable and unaffected by this method call. 1025 * <p> 1026 * The following three lines are identical in effect: 1027 * <pre> 1028 * LocalDateTime added = dt.plusYears(6); 1029 * LocalDateTime added = dt.plus(Period.years(6)); 1030 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 1031 * </pre> 1032 * 1033 * @param years the amount of years to add, may be negative 1034 * @return the new LocalDateTime plus the increased years 1035 */ 1036 public LocalDateTime plusYears(int years) { 1037 if (years == 0) { 1038 return this; 1039 } 1040 long instant = getChronology().years().add(getLocalMillis(), years); 1041 return withLocalMillis(instant); 1042 } 1043 1044 /** 1045 * Returns a copy of this datetime plus the specified number of months. 1046 * <p> 1047 * This LocalDateTime instance is immutable and unaffected by this method call. 1048 * <p> 1049 * The following three lines are identical in effect: 1050 * <pre> 1051 * LocalDateTime added = dt.plusMonths(6); 1052 * LocalDateTime added = dt.plus(Period.months(6)); 1053 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.months(), 6); 1054 * </pre> 1055 * 1056 * @param months the amount of months to add, may be negative 1057 * @return the new LocalDateTime plus the increased months 1058 */ 1059 public LocalDateTime plusMonths(int months) { 1060 if (months == 0) { 1061 return this; 1062 } 1063 long instant = getChronology().months().add(getLocalMillis(), months); 1064 return withLocalMillis(instant); 1065 } 1066 1067 /** 1068 * Returns a copy of this datetime plus the specified number of weeks. 1069 * <p> 1070 * This LocalDateTime instance is immutable and unaffected by this method call. 1071 * <p> 1072 * The following three lines are identical in effect: 1073 * <pre> 1074 * LocalDateTime added = dt.plusWeeks(6); 1075 * LocalDateTime added = dt.plus(Period.weeks(6)); 1076 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.weeks(), 6); 1077 * </pre> 1078 * 1079 * @param weeks the amount of weeks to add, may be negative 1080 * @return the new LocalDateTime plus the increased weeks 1081 */ 1082 public LocalDateTime plusWeeks(int weeks) { 1083 if (weeks == 0) { 1084 return this; 1085 } 1086 long instant = getChronology().weeks().add(getLocalMillis(), weeks); 1087 return withLocalMillis(instant); 1088 } 1089 1090 /** 1091 * Returns a copy of this datetime plus the specified number of days. 1092 * <p> 1093 * This LocalDateTime instance is immutable and unaffected by this method call. 1094 * <p> 1095 * The following three lines are identical in effect: 1096 * <pre> 1097 * LocalDateTime added = dt.plusDays(6); 1098 * LocalDateTime added = dt.plus(Period.days(6)); 1099 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.days(), 6); 1100 * </pre> 1101 * 1102 * @param days the amount of days to add, may be negative 1103 * @return the new LocalDateTime plus the increased days 1104 */ 1105 public LocalDateTime plusDays(int days) { 1106 if (days == 0) { 1107 return this; 1108 } 1109 long instant = getChronology().days().add(getLocalMillis(), days); 1110 return withLocalMillis(instant); 1111 } 1112 1113 //----------------------------------------------------------------------- 1114 /** 1115 * Returns a copy of this datetime plus the specified number of hours. 1116 * <p> 1117 * This LocalDateTime instance is immutable and unaffected by this method call. 1118 * <p> 1119 * The following three lines are identical in effect: 1120 * <pre> 1121 * LocalDateTime added = dt.plusHours(6); 1122 * LocalDateTime added = dt.plus(Period.hours(6)); 1123 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.hours(), 6); 1124 * </pre> 1125 * 1126 * @param hours the amount of hours to add, may be negative 1127 * @return the new LocalDateTime plus the increased hours 1128 */ 1129 public LocalDateTime plusHours(int hours) { 1130 if (hours == 0) { 1131 return this; 1132 } 1133 long instant = getChronology().hours().add(getLocalMillis(), hours); 1134 return withLocalMillis(instant); 1135 } 1136 1137 /** 1138 * Returns a copy of this datetime plus the specified number of minutes. 1139 * <p> 1140 * This LocalDateTime instance is immutable and unaffected by this method call. 1141 * <p> 1142 * The following three lines are identical in effect: 1143 * <pre> 1144 * LocalDateTime added = dt.plusMinutes(6); 1145 * LocalDateTime added = dt.plus(Period.minutes(6)); 1146 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6); 1147 * </pre> 1148 * 1149 * @param minutes the amount of minutes to add, may be negative 1150 * @return the new LocalDateTime plus the increased minutes 1151 */ 1152 public LocalDateTime plusMinutes(int minutes) { 1153 if (minutes == 0) { 1154 return this; 1155 } 1156 long instant = getChronology().minutes().add(getLocalMillis(), minutes); 1157 return withLocalMillis(instant); 1158 } 1159 1160 /** 1161 * Returns a copy of this datetime plus the specified number of seconds. 1162 * <p> 1163 * This LocalDateTime instance is immutable and unaffected by this method call. 1164 * <p> 1165 * The following three lines are identical in effect: 1166 * <pre> 1167 * LocalDateTime added = dt.plusSeconds(6); 1168 * LocalDateTime added = dt.plus(Period.seconds(6)); 1169 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6); 1170 * </pre> 1171 * 1172 * @param seconds the amount of seconds to add, may be negative 1173 * @return the new LocalDateTime plus the increased seconds 1174 */ 1175 public LocalDateTime plusSeconds(int seconds) { 1176 if (seconds == 0) { 1177 return this; 1178 } 1179 long instant = getChronology().seconds().add(getLocalMillis(), seconds); 1180 return withLocalMillis(instant); 1181 } 1182 1183 /** 1184 * Returns a copy of this datetime plus the specified number of millis. 1185 * <p> 1186 * This LocalDateTime instance is immutable and unaffected by this method call. 1187 * <p> 1188 * The following three lines are identical in effect: 1189 * <pre> 1190 * LocalDateTime added = dt.plusMillis(6); 1191 * LocalDateTime added = dt.plus(Period.millis(6)); 1192 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.millis(), 6); 1193 * </pre> 1194 * 1195 * @param millis the amount of millis to add, may be negative 1196 * @return the new LocalDateTime plus the increased millis 1197 */ 1198 public LocalDateTime plusMillis(int millis) { 1199 if (millis == 0) { 1200 return this; 1201 } 1202 long instant = getChronology().millis().add(getLocalMillis(), millis); 1203 return withLocalMillis(instant); 1204 } 1205 1206 //----------------------------------------------------------------------- 1207 /** 1208 * Returns a copy of this datetime with the specified duration taken away. 1209 * <p> 1210 * If the amount is zero or null, then <code>this</code> is returned. 1211 * 1212 * @param duration the duration to reduce this instant by 1213 * @return a copy of this datetime with the duration taken away 1214 * @throws ArithmeticException if the result exceeds the internal capacity 1215 */ 1216 public LocalDateTime minus(ReadableDuration duration) { 1217 return withDurationAdded(duration, -1); 1218 } 1219 1220 /** 1221 * Returns a copy of this datetime with the specified period taken away. 1222 * <p> 1223 * If the amount is zero or null, then <code>this</code> is returned. 1224 * <p> 1225 * This method is typically used to subtract complex period instances. 1226 * Subtracting one field is best achieved using methods 1227 * like {@link #minusYears(int)}. 1228 * 1229 * @param period the period to reduce this instant by 1230 * @return a copy of this datetime with the period taken away 1231 * @throws ArithmeticException if the result exceeds the internal capacity 1232 */ 1233 public LocalDateTime minus(ReadablePeriod period) { 1234 return withPeriodAdded(period, -1); 1235 } 1236 1237 //----------------------------------------------------------------------- 1238 /** 1239 * Returns a copy of this datetime minus the specified number of years. 1240 * <p> 1241 * This LocalDateTime instance is immutable and unaffected by this method call. 1242 * <p> 1243 * The following three lines are identical in effect: 1244 * <pre> 1245 * LocalDateTime subtracted = dt.minusYears(6); 1246 * LocalDateTime subtracted = dt.minus(Period.years(6)); 1247 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6); 1248 * </pre> 1249 * 1250 * @param years the amount of years to subtract, may be negative 1251 * @return the new LocalDateTime minus the increased years 1252 */ 1253 public LocalDateTime minusYears(int years) { 1254 if (years == 0) { 1255 return this; 1256 } 1257 long instant = getChronology().years().subtract(getLocalMillis(), years); 1258 return withLocalMillis(instant); 1259 } 1260 1261 /** 1262 * Returns a copy of this datetime minus the specified number of months. 1263 * <p> 1264 * This LocalDateTime instance is immutable and unaffected by this method call. 1265 * <p> 1266 * The following three lines are identical in effect: 1267 * <pre> 1268 * LocalDateTime subtracted = dt.minusMonths(6); 1269 * LocalDateTime subtracted = dt.minus(Period.months(6)); 1270 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.months(), -6); 1271 * </pre> 1272 * 1273 * @param months the amount of months to subtract, may be negative 1274 * @return the new LocalDateTime minus the increased months 1275 */ 1276 public LocalDateTime minusMonths(int months) { 1277 if (months == 0) { 1278 return this; 1279 } 1280 long instant = getChronology().months().subtract(getLocalMillis(), months); 1281 return withLocalMillis(instant); 1282 } 1283 1284 /** 1285 * Returns a copy of this datetime minus the specified number of weeks. 1286 * <p> 1287 * This LocalDateTime instance is immutable and unaffected by this method call. 1288 * <p> 1289 * The following three lines are identical in effect: 1290 * <pre> 1291 * LocalDateTime subtracted = dt.minusWeeks(6); 1292 * LocalDateTime subtracted = dt.minus(Period.weeks(6)); 1293 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6); 1294 * </pre> 1295 * 1296 * @param weeks the amount of weeks to subtract, may be negative 1297 * @return the new LocalDateTime minus the increased weeks 1298 */ 1299 public LocalDateTime minusWeeks(int weeks) { 1300 if (weeks == 0) { 1301 return this; 1302 } 1303 long instant = getChronology().weeks().subtract(getLocalMillis(), weeks); 1304 return withLocalMillis(instant); 1305 } 1306 1307 /** 1308 * Returns a copy of this datetime minus the specified number of days. 1309 * <p> 1310 * This LocalDateTime instance is immutable and unaffected by this method call. 1311 * <p> 1312 * The following three lines are identical in effect: 1313 * <pre> 1314 * LocalDateTime subtracted = dt.minusDays(6); 1315 * LocalDateTime subtracted = dt.minus(Period.days(6)); 1316 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.days(), -6); 1317 * </pre> 1318 * 1319 * @param days the amount of days to subtract, may be negative 1320 * @return the new LocalDateTime minus the increased days 1321 */ 1322 public LocalDateTime minusDays(int days) { 1323 if (days == 0) { 1324 return this; 1325 } 1326 long instant = getChronology().days().subtract(getLocalMillis(), days); 1327 return withLocalMillis(instant); 1328 } 1329 1330 //----------------------------------------------------------------------- 1331 /** 1332 * Returns a copy of this datetime minus the specified number of hours. 1333 * <p> 1334 * This LocalDateTime instance is immutable and unaffected by this method call. 1335 * <p> 1336 * The following three lines are identical in effect: 1337 * <pre> 1338 * LocalDateTime subtracted = dt.minusHours(6); 1339 * LocalDateTime subtracted = dt.minus(Period.hours(6)); 1340 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6); 1341 * </pre> 1342 * 1343 * @param hours the amount of hours to subtract, may be negative 1344 * @return the new LocalDateTime minus the increased hours 1345 */ 1346 public LocalDateTime minusHours(int hours) { 1347 if (hours == 0) { 1348 return this; 1349 } 1350 long instant = getChronology().hours().subtract(getLocalMillis(), hours); 1351 return withLocalMillis(instant); 1352 } 1353 1354 /** 1355 * Returns a copy of this datetime minus the specified number of minutes. 1356 * <p> 1357 * This LocalDateTime instance is immutable and unaffected by this method call. 1358 * <p> 1359 * The following three lines are identical in effect: 1360 * <pre> 1361 * LocalDateTime subtracted = dt.minusMinutes(6); 1362 * LocalDateTime subtracted = dt.minus(Period.minutes(6)); 1363 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6); 1364 * </pre> 1365 * 1366 * @param minutes the amount of minutes to subtract, may be negative 1367 * @return the new LocalDateTime minus the increased minutes 1368 */ 1369 public LocalDateTime minusMinutes(int minutes) { 1370 if (minutes == 0) { 1371 return this; 1372 } 1373 long instant = getChronology().minutes().subtract(getLocalMillis(), minutes); 1374 return withLocalMillis(instant); 1375 } 1376 1377 /** 1378 * Returns a copy of this datetime minus the specified number of seconds. 1379 * <p> 1380 * This LocalDateTime instance is immutable and unaffected by this method call. 1381 * <p> 1382 * The following three lines are identical in effect: 1383 * <pre> 1384 * LocalDateTime subtracted = dt.minusSeconds(6); 1385 * LocalDateTime subtracted = dt.minus(Period.seconds(6)); 1386 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6); 1387 * </pre> 1388 * 1389 * @param seconds the amount of seconds to subtract, may be negative 1390 * @return the new LocalDateTime minus the increased seconds 1391 */ 1392 public LocalDateTime minusSeconds(int seconds) { 1393 if (seconds == 0) { 1394 return this; 1395 } 1396 long instant = getChronology().seconds().subtract(getLocalMillis(), seconds); 1397 return withLocalMillis(instant); 1398 } 1399 1400 /** 1401 * Returns a copy of this datetime minus the specified number of millis. 1402 * <p> 1403 * This LocalDateTime instance is immutable and unaffected by this method call. 1404 * <p> 1405 * The following three lines are identical in effect: 1406 * <pre> 1407 * LocalDateTime subtracted = dt.minusMillis(6); 1408 * LocalDateTime subtracted = dt.minus(Period.millis(6)); 1409 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6); 1410 * </pre> 1411 * 1412 * @param millis the amount of millis to subtract, may be negative 1413 * @return the new LocalDateTime minus the increased millis 1414 */ 1415 public LocalDateTime minusMillis(int millis) { 1416 if (millis == 0) { 1417 return this; 1418 } 1419 long instant = getChronology().millis().subtract(getLocalMillis(), millis); 1420 return withLocalMillis(instant); 1421 } 1422 1423 //----------------------------------------------------------------------- 1424 /** 1425 * Gets the property object for the specified type, which contains many 1426 * useful methods. 1427 * 1428 * @param fieldType the field type to get the chronology for 1429 * @return the property object 1430 * @throws IllegalArgumentException if the field is null or unsupported 1431 */ 1432 public Property property(DateTimeFieldType fieldType) { 1433 if (fieldType == null) { 1434 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 1435 } 1436 if (isSupported(fieldType) == false) { 1437 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported"); 1438 } 1439 return new Property(this, fieldType.getField(getChronology())); 1440 } 1441 1442 //----------------------------------------------------------------------- 1443 /** 1444 * Get the era field value. 1445 * 1446 * @return the era 1447 */ 1448 public int getEra() { 1449 return getChronology().era().get(getLocalMillis()); 1450 } 1451 1452 /** 1453 * Get the year of era field value. 1454 * 1455 * @return the year of era 1456 */ 1457 public int getCenturyOfEra() { 1458 return getChronology().centuryOfEra().get(getLocalMillis()); 1459 } 1460 1461 /** 1462 * Get the year of era field value. 1463 * 1464 * @return the year of era 1465 */ 1466 public int getYearOfEra() { 1467 return getChronology().yearOfEra().get(getLocalMillis()); 1468 } 1469 1470 /** 1471 * Get the year of century field value. 1472 * 1473 * @return the year of century 1474 */ 1475 public int getYearOfCentury() { 1476 return getChronology().yearOfCentury().get(getLocalMillis()); 1477 } 1478 1479 /** 1480 * Get the year field value. 1481 * 1482 * @return the year 1483 */ 1484 public int getYear() { 1485 return getChronology().year().get(getLocalMillis()); 1486 } 1487 1488 /** 1489 * Get the weekyear field value. 1490 * <p> 1491 * The weekyear is the year that matches with the weekOfWeekyear field. 1492 * In the standard ISO8601 week algorithm, the first week of the year 1493 * is that in which at least 4 days are in the year. As a result of this 1494 * definition, day 1 of the first week may be in the previous year. 1495 * The weekyear allows you to query the effective year for that day. 1496 * 1497 * @return the weekyear 1498 */ 1499 public int getWeekyear() { 1500 return getChronology().weekyear().get(getLocalMillis()); 1501 } 1502 1503 /** 1504 * Get the month of year field value. 1505 * 1506 * @return the month of year 1507 */ 1508 public int getMonthOfYear() { 1509 return getChronology().monthOfYear().get(getLocalMillis()); 1510 } 1511 1512 /** 1513 * Get the week of weekyear field value. 1514 * <p> 1515 * This field is associated with the "weekyear" via {@link #getWeekyear()}. 1516 * In the standard ISO8601 week algorithm, the first week of the year 1517 * is that in which at least 4 days are in the year. As a result of this 1518 * definition, day 1 of the first week may be in the previous year. 1519 * 1520 * @return the week of a week based year 1521 */ 1522 public int getWeekOfWeekyear() { 1523 return getChronology().weekOfWeekyear().get(getLocalMillis()); 1524 } 1525 1526 /** 1527 * Get the day of year field value. 1528 * 1529 * @return the day of year 1530 */ 1531 public int getDayOfYear() { 1532 return getChronology().dayOfYear().get(getLocalMillis()); 1533 } 1534 1535 /** 1536 * Get the day of month field value. 1537 * <p> 1538 * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}. 1539 * 1540 * @return the day of month 1541 */ 1542 public int getDayOfMonth() { 1543 return getChronology().dayOfMonth().get(getLocalMillis()); 1544 } 1545 1546 /** 1547 * Get the day of week field value. 1548 * <p> 1549 * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}. 1550 * 1551 * @return the day of week 1552 */ 1553 public int getDayOfWeek() { 1554 return getChronology().dayOfWeek().get(getLocalMillis()); 1555 } 1556 1557 //----------------------------------------------------------------------- 1558 /** 1559 * Get the hour of day field value. 1560 * 1561 * @return the hour of day 1562 */ 1563 public int getHourOfDay() { 1564 return getChronology().hourOfDay().get(getLocalMillis()); 1565 } 1566 1567 /** 1568 * Get the minute of hour field value. 1569 * 1570 * @return the minute of hour 1571 */ 1572 public int getMinuteOfHour() { 1573 return getChronology().minuteOfHour().get(getLocalMillis()); 1574 } 1575 1576 /** 1577 * Get the second of minute field value. 1578 * 1579 * @return the second of minute 1580 */ 1581 public int getSecondOfMinute() { 1582 return getChronology().secondOfMinute().get(getLocalMillis()); 1583 } 1584 1585 /** 1586 * Get the millis of second field value. 1587 * 1588 * @return the millis of second 1589 */ 1590 public int getMillisOfSecond() { 1591 return getChronology().millisOfSecond().get(getLocalMillis()); 1592 } 1593 1594 /** 1595 * Get the millis of day field value. 1596 * 1597 * @return the millis of day 1598 */ 1599 public int getMillisOfDay() { 1600 return getChronology().millisOfDay().get(getLocalMillis()); 1601 } 1602 1603 //----------------------------------------------------------------------- 1604 /** 1605 * Returns a copy of this datetime with the era field updated. 1606 * <p> 1607 * LocalDateTime is immutable, so there are no set methods. 1608 * Instead, this method returns a new instance with the value of 1609 * era changed. 1610 * 1611 * @param era the era to set 1612 * @return a copy of this object with the field set 1613 * @throws IllegalArgumentException if the value is invalid 1614 */ 1615 public LocalDateTime withEra(int era) { 1616 return withLocalMillis(getChronology().era().set(getLocalMillis(), era)); 1617 } 1618 1619 /** 1620 * Returns a copy of this datetime with the century of era field updated. 1621 * <p> 1622 * LocalDateTime is immutable, so there are no set methods. 1623 * Instead, this method returns a new instance with the value of 1624 * century of era changed. 1625 * 1626 * @param centuryOfEra the centurey of era to set 1627 * @return a copy of this object with the field set 1628 * @throws IllegalArgumentException if the value is invalid 1629 */ 1630 public LocalDateTime withCenturyOfEra(int centuryOfEra) { 1631 return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra)); 1632 } 1633 1634 /** 1635 * Returns a copy of this datetime with the year of era field updated. 1636 * <p> 1637 * LocalDateTime is immutable, so there are no set methods. 1638 * Instead, this method returns a new instance with the value of 1639 * year of era changed. 1640 * 1641 * @param yearOfEra the year of era to set 1642 * @return a copy of this object with the field set 1643 * @throws IllegalArgumentException if the value is invalid 1644 */ 1645 public LocalDateTime withYearOfEra(int yearOfEra) { 1646 return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra)); 1647 } 1648 1649 /** 1650 * Returns a copy of this datetime with the year of century field updated. 1651 * <p> 1652 * LocalDateTime is immutable, so there are no set methods. 1653 * Instead, this method returns a new instance with the value of 1654 * year of century changed. 1655 * 1656 * @param yearOfCentury the year of century to set 1657 * @return a copy of this object with the field set 1658 * @throws IllegalArgumentException if the value is invalid 1659 */ 1660 public LocalDateTime withYearOfCentury(int yearOfCentury) { 1661 return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury)); 1662 } 1663 1664 /** 1665 * Returns a copy of this datetime with the year field updated. 1666 * <p> 1667 * LocalDateTime is immutable, so there are no set methods. 1668 * Instead, this method returns a new instance with the value of 1669 * year changed. 1670 * 1671 * @param year the year to set 1672 * @return a copy of this object with the field set 1673 * @throws IllegalArgumentException if the value is invalid 1674 */ 1675 public LocalDateTime withYear(int year) { 1676 return withLocalMillis(getChronology().year().set(getLocalMillis(), year)); 1677 } 1678 1679 /** 1680 * Returns a copy of this datetime with the weekyear field updated. 1681 * <p> 1682 * The weekyear is the year that matches with the weekOfWeekyear field. 1683 * In the standard ISO8601 week algorithm, the first week of the year 1684 * is that in which at least 4 days are in the year. As a result of this 1685 * definition, day 1 of the first week may be in the previous year. 1686 * The weekyear allows you to query the effective year for that day. 1687 * <p> 1688 * LocalDateTime is immutable, so there are no set methods. 1689 * Instead, this method returns a new instance with the value of 1690 * weekyear changed. 1691 * 1692 * @param weekyear the weekyear to set 1693 * @return a copy of this object with the field set 1694 * @throws IllegalArgumentException if the value is invalid 1695 */ 1696 public LocalDateTime withWeekyear(int weekyear) { 1697 return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear)); 1698 } 1699 1700 /** 1701 * Returns a copy of this datetime with the month of year field updated. 1702 * <p> 1703 * LocalDateTime is immutable, so there are no set methods. 1704 * Instead, this method returns a new instance with the value of 1705 * month of year changed. 1706 * 1707 * @param monthOfYear the month of year to set 1708 * @return a copy of this object with the field set 1709 * @throws IllegalArgumentException if the value is invalid 1710 */ 1711 public LocalDateTime withMonthOfYear(int monthOfYear) { 1712 return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear)); 1713 } 1714 1715 /** 1716 * Returns a copy of this datetime with the week of weekyear field updated. 1717 * <p> 1718 * This field is associated with the "weekyear" via {@link #withWeekyear(int)}. 1719 * In the standard ISO8601 week algorithm, the first week of the year 1720 * is that in which at least 4 days are in the year. As a result of this 1721 * definition, day 1 of the first week may be in the previous year. 1722 * <p> 1723 * LocalDateTime is immutable, so there are no set methods. 1724 * Instead, this method returns a new instance with the value of 1725 * week of weekyear changed. 1726 * 1727 * @param weekOfWeekyear the week of weekyear to set 1728 * @return a copy of this object with the field set 1729 * @throws IllegalArgumentException if the value is invalid 1730 */ 1731 public LocalDateTime withWeekOfWeekyear(int weekOfWeekyear) { 1732 return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear)); 1733 } 1734 1735 /** 1736 * Returns a copy of this datetime with the day of year field updated. 1737 * <p> 1738 * LocalDateTime is immutable, so there are no set methods. 1739 * Instead, this method returns a new instance with the value of 1740 * day of year changed. 1741 * 1742 * @param dayOfYear the day of year to set 1743 * @return a copy of this object with the field set 1744 * @throws IllegalArgumentException if the value is invalid 1745 */ 1746 public LocalDateTime withDayOfYear(int dayOfYear) { 1747 return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear)); 1748 } 1749 1750 /** 1751 * Returns a copy of this datetime with the day of month field updated. 1752 * <p> 1753 * LocalDateTime is immutable, so there are no set methods. 1754 * Instead, this method returns a new instance with the value of 1755 * day of month changed. 1756 * 1757 * @param dayOfMonth the day of month to set 1758 * @return a copy of this object with the field set 1759 * @throws IllegalArgumentException if the value is invalid 1760 */ 1761 public LocalDateTime withDayOfMonth(int dayOfMonth) { 1762 return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth)); 1763 } 1764 1765 /** 1766 * Returns a copy of this datetime with the day of week field updated. 1767 * <p> 1768 * LocalDateTime is immutable, so there are no set methods. 1769 * Instead, this method returns a new instance with the value of 1770 * day of week changed. 1771 * 1772 * @param dayOfWeek the day of week to set 1773 * @return a copy of this object with the field set 1774 * @throws IllegalArgumentException if the value is invalid 1775 */ 1776 public LocalDateTime withDayOfWeek(int dayOfWeek) { 1777 return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek)); 1778 } 1779 1780 //----------------------------------------------------------------------- 1781 /** 1782 * Returns a copy of this datetime with the hour of day field updated. 1783 * <p> 1784 * LocalDateTime is immutable, so there are no set methods. 1785 * Instead, this method returns a new instance with the value of 1786 * hour of day changed. 1787 * 1788 * @param hour the hour of day to set 1789 * @return a copy of this object with the field set 1790 * @throws IllegalArgumentException if the value is invalid 1791 */ 1792 public LocalDateTime withHourOfDay(int hour) { 1793 return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour)); 1794 } 1795 1796 /** 1797 * Returns a copy of this datetime with the minute of hour field updated. 1798 * <p> 1799 * LocalDateTime is immutable, so there are no set methods. 1800 * Instead, this method returns a new instance with the value of 1801 * minute of hour changed. 1802 * 1803 * @param minute the minute of hour to set 1804 * @return a copy of this object with the field set 1805 * @throws IllegalArgumentException if the value is invalid 1806 */ 1807 public LocalDateTime withMinuteOfHour(int minute) { 1808 return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute)); 1809 } 1810 1811 /** 1812 * Returns a copy of this datetime with the second of minute field updated. 1813 * <p> 1814 * LocalDateTime is immutable, so there are no set methods. 1815 * Instead, this method returns a new instance with the value of 1816 * second of minute changed. 1817 * 1818 * @param second the second of minute to set 1819 * @return a copy of this object with the field set 1820 * @throws IllegalArgumentException if the value is invalid 1821 */ 1822 public LocalDateTime withSecondOfMinute(int second) { 1823 return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second)); 1824 } 1825 1826 /** 1827 * Returns a copy of this datetime with the millis of second field updated. 1828 * <p> 1829 * LocalDateTime is immutable, so there are no set methods. 1830 * Instead, this method returns a new instance with the value of 1831 * millis of second changed. 1832 * 1833 * @param millis the millis of second to set 1834 * @return a copy of this object with the field set 1835 * @throws IllegalArgumentException if the value is invalid 1836 */ 1837 public LocalDateTime withMillisOfSecond(int millis) { 1838 return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis)); 1839 } 1840 1841 /** 1842 * Returns a copy of this datetime with the millis of day field updated. 1843 * <p> 1844 * LocalDateTime is immutable, so there are no set methods. 1845 * Instead, this method returns a new instance with the value of 1846 * millis of day changed. 1847 * 1848 * @param millis the millis of day to set 1849 * @return a copy of this object with the field set 1850 * @throws IllegalArgumentException if the value is invalid 1851 */ 1852 public LocalDateTime withMillisOfDay(int millis) { 1853 return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis)); 1854 } 1855 1856 //----------------------------------------------------------------------- 1857 /** 1858 * Get the era property which provides access to advanced functionality. 1859 * 1860 * @return the era property 1861 */ 1862 public Property era() { 1863 return new Property(this, getChronology().era()); 1864 } 1865 1866 /** 1867 * Get the century of era property which provides access to advanced functionality. 1868 * 1869 * @return the year of era property 1870 */ 1871 public Property centuryOfEra() { 1872 return new Property(this, getChronology().centuryOfEra()); 1873 } 1874 1875 /** 1876 * Get the year of century property which provides access to advanced functionality. 1877 * 1878 * @return the year of era property 1879 */ 1880 public Property yearOfCentury() { 1881 return new Property(this, getChronology().yearOfCentury()); 1882 } 1883 1884 /** 1885 * Get the year of era property which provides access to advanced functionality. 1886 * 1887 * @return the year of era property 1888 */ 1889 public Property yearOfEra() { 1890 return new Property(this, getChronology().yearOfEra()); 1891 } 1892 1893 /** 1894 * Get the year property which provides access to advanced functionality. 1895 * 1896 * @return the year property 1897 */ 1898 public Property year() { 1899 return new Property(this, getChronology().year()); 1900 } 1901 1902 /** 1903 * Get the weekyear property which provides access to advanced functionality. 1904 * 1905 * @return the weekyear property 1906 */ 1907 public Property weekyear() { 1908 return new Property(this, getChronology().weekyear()); 1909 } 1910 1911 /** 1912 * Get the month of year property which provides access to advanced functionality. 1913 * 1914 * @return the month of year property 1915 */ 1916 public Property monthOfYear() { 1917 return new Property(this, getChronology().monthOfYear()); 1918 } 1919 1920 /** 1921 * Get the week of a week based year property which provides access to advanced functionality. 1922 * 1923 * @return the week of a week based year property 1924 */ 1925 public Property weekOfWeekyear() { 1926 return new Property(this, getChronology().weekOfWeekyear()); 1927 } 1928 1929 /** 1930 * Get the day of year property which provides access to advanced functionality. 1931 * 1932 * @return the day of year property 1933 */ 1934 public Property dayOfYear() { 1935 return new Property(this, getChronology().dayOfYear()); 1936 } 1937 1938 /** 1939 * Get the day of month property which provides access to advanced functionality. 1940 * 1941 * @return the day of month property 1942 */ 1943 public Property dayOfMonth() { 1944 return new Property(this, getChronology().dayOfMonth()); 1945 } 1946 1947 /** 1948 * Get the day of week property which provides access to advanced functionality. 1949 * 1950 * @return the day of week property 1951 */ 1952 public Property dayOfWeek() { 1953 return new Property(this, getChronology().dayOfWeek()); 1954 } 1955 1956 //----------------------------------------------------------------------- 1957 /** 1958 * Get the hour of day field property which provides access to advanced functionality. 1959 * 1960 * @return the hour of day property 1961 */ 1962 public Property hourOfDay() { 1963 return new Property(this, getChronology().hourOfDay()); 1964 } 1965 1966 /** 1967 * Get the minute of hour field property which provides access to advanced functionality. 1968 * 1969 * @return the minute of hour property 1970 */ 1971 public Property minuteOfHour() { 1972 return new Property(this, getChronology().minuteOfHour()); 1973 } 1974 1975 /** 1976 * Get the second of minute field property which provides access to advanced functionality. 1977 * 1978 * @return the second of minute property 1979 */ 1980 public Property secondOfMinute() { 1981 return new Property(this, getChronology().secondOfMinute()); 1982 } 1983 1984 /** 1985 * Get the millis of second property which provides access to advanced functionality. 1986 * 1987 * @return the millis of second property 1988 */ 1989 public Property millisOfSecond() { 1990 return new Property(this, getChronology().millisOfSecond()); 1991 } 1992 1993 /** 1994 * Get the millis of day property which provides access to advanced functionality. 1995 * 1996 * @return the millis of day property 1997 */ 1998 public Property millisOfDay() { 1999 return new Property(this, getChronology().millisOfDay()); 2000 } 2001 2002 //----------------------------------------------------------------------- 2003 /** 2004 * Output the date time in ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSS). 2005 * 2006 * @return ISO8601 time formatted string. 2007 */ 2008 @ToString 2009 public String toString() { 2010 return ISODateTimeFormat.dateTime().print(this); 2011 } 2012 2013 /** 2014 * Output the date using the specified format pattern. 2015 * 2016 * @param pattern the pattern specification, null means use <code>toString</code> 2017 * @see org.joda.time.format.DateTimeFormat 2018 */ 2019 public String toString(String pattern) { 2020 if (pattern == null) { 2021 return toString(); 2022 } 2023 return DateTimeFormat.forPattern(pattern).print(this); 2024 } 2025 2026 /** 2027 * Output the date using the specified format pattern. 2028 * 2029 * @param pattern the pattern specification, null means use <code>toString</code> 2030 * @param locale Locale to use, null means default 2031 * @see org.joda.time.format.DateTimeFormat 2032 */ 2033 public String toString(String pattern, Locale locale) throws IllegalArgumentException { 2034 if (pattern == null) { 2035 return toString(); 2036 } 2037 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this); 2038 } 2039 2040 //----------------------------------------------------------------------- 2041 /** 2042 * LocalDateTime.Property binds a LocalDateTime to a DateTimeField allowing 2043 * powerful datetime functionality to be easily accessed. 2044 * <p> 2045 * The simplest use of this class is as an alternative get method, here used to 2046 * get the year '1972' (as an int) and the month 'December' (as a String). 2047 * <pre> 2048 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2049 * int year = dt.year().get(); 2050 * String monthStr = dt.month().getAsText(); 2051 * </pre> 2052 * <p> 2053 * Methods are also provided that allow date modification. These return 2054 * new instances of LocalDateTime - they do not modify the original. 2055 * The example below yields two independent immutable date objects 2056 * 20 years apart. 2057 * <pre> 2058 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2059 * LocalDateTime dt1920 = dt.year().setCopy(1920); 2060 * </pre> 2061 * <p> 2062 * LocalDateTime.Property itself is thread-safe and immutable, as well as the 2063 * LocalDateTime being operated on. 2064 * 2065 * @author Stephen Colebourne 2066 * @author Brian S O'Neill 2067 * @since 1.3 2068 */ 2069 public static final class Property extends AbstractReadableInstantFieldProperty { 2070 2071 /** Serialization version */ 2072 private static final long serialVersionUID = -358138762846288L; 2073 2074 /** The instant this property is working against */ 2075 private transient LocalDateTime iInstant; 2076 /** The field this property is working against */ 2077 private transient DateTimeField iField; 2078 2079 /** 2080 * Constructor. 2081 * 2082 * @param instant the instant to set 2083 * @param field the field to use 2084 */ 2085 Property(LocalDateTime instant, DateTimeField field) { 2086 super(); 2087 iInstant = instant; 2088 iField = field; 2089 } 2090 2091 /** 2092 * Writes the property in a safe serialization format. 2093 */ 2094 private void writeObject(ObjectOutputStream oos) throws IOException { 2095 oos.writeObject(iInstant); 2096 oos.writeObject(iField.getType()); 2097 } 2098 2099 /** 2100 * Reads the property from a safe serialization format. 2101 */ 2102 private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException { 2103 iInstant = (LocalDateTime) oos.readObject(); 2104 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 2105 iField = type.getField(iInstant.getChronology()); 2106 } 2107 2108 //----------------------------------------------------------------------- 2109 /** 2110 * Gets the field being used. 2111 * 2112 * @return the field 2113 */ 2114 public DateTimeField getField() { 2115 return iField; 2116 } 2117 2118 /** 2119 * Gets the milliseconds of the datetime that this property is linked to. 2120 * 2121 * @return the milliseconds 2122 */ 2123 protected long getMillis() { 2124 return iInstant.getLocalMillis(); 2125 } 2126 2127 /** 2128 * Gets the chronology of the datetime that this property is linked to. 2129 * 2130 * @return the chronology 2131 * @since 1.4 2132 */ 2133 protected Chronology getChronology() { 2134 return iInstant.getChronology(); 2135 } 2136 2137 /** 2138 * Gets the LocalDateTime object linked to this property. 2139 * 2140 * @return the linked LocalDateTime 2141 */ 2142 public LocalDateTime getLocalDateTime() { 2143 return iInstant; 2144 } 2145 2146 //----------------------------------------------------------------------- 2147 /** 2148 * Adds to this field in a copy of this LocalDateTime. 2149 * <p> 2150 * The LocalDateTime attached to this property is unchanged by this call. 2151 * 2152 * @param value the value to add to the field in the copy 2153 * @return a copy of the LocalDateTime with the field value changed 2154 * @throws IllegalArgumentException if the value isn't valid 2155 */ 2156 public LocalDateTime addToCopy(int value) { 2157 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2158 } 2159 2160 /** 2161 * Adds to this field in a copy of this LocalDateTime. 2162 * <p> 2163 * The LocalDateTime attached to this property is unchanged by this call. 2164 * 2165 * @param value the value to add to the field in the copy 2166 * @return a copy of the LocalDateTime with the field value changed 2167 * @throws IllegalArgumentException if the value isn't valid 2168 */ 2169 public LocalDateTime addToCopy(long value) { 2170 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2171 } 2172 2173 /** 2174 * Adds to this field, possibly wrapped, in a copy of this LocalDateTime. 2175 * A field wrapped operation only changes this field. 2176 * Thus 31st January addWrapField one day goes to the 1st January. 2177 * <p> 2178 * The LocalDateTime attached to this property is unchanged by this call. 2179 * 2180 * @param value the value to add to the field in the copy 2181 * @return a copy of the LocalDateTime with the field value changed 2182 * @throws IllegalArgumentException if the value isn't valid 2183 */ 2184 public LocalDateTime addWrapFieldToCopy(int value) { 2185 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value)); 2186 } 2187 2188 //----------------------------------------------------------------------- 2189 /** 2190 * Sets this field in a copy of the LocalDateTime. 2191 * <p> 2192 * The LocalDateTime attached to this property is unchanged by this call. 2193 * 2194 * @param value the value to set the field in the copy to 2195 * @return a copy of the LocalDateTime with the field value changed 2196 * @throws IllegalArgumentException if the value isn't valid 2197 */ 2198 public LocalDateTime setCopy(int value) { 2199 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value)); 2200 } 2201 2202 /** 2203 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2204 * <p> 2205 * The LocalDateTime attached to this property is unchanged by this call. 2206 * 2207 * @param text the text value to set 2208 * @param locale optional locale to use for selecting a text symbol 2209 * @return a copy of the LocalDateTime with the field value changed 2210 * @throws IllegalArgumentException if the text value isn't valid 2211 */ 2212 public LocalDateTime setCopy(String text, Locale locale) { 2213 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale)); 2214 } 2215 2216 /** 2217 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2218 * <p> 2219 * The LocalDateTime attached to this property is unchanged by this call. 2220 * 2221 * @param text the text value to set 2222 * @return a copy of the LocalDateTime with the field value changed 2223 * @throws IllegalArgumentException if the text value isn't valid 2224 */ 2225 public LocalDateTime setCopy(String text) { 2226 return setCopy(text, null); 2227 } 2228 2229 //----------------------------------------------------------------------- 2230 /** 2231 * Returns a new LocalDateTime with this field set to the maximum value 2232 * for this field. 2233 * <p> 2234 * This operation is useful for obtaining a LocalDateTime on the last day 2235 * of the month, as month lengths vary. 2236 * <pre> 2237 * LocalDateTime lastDayOfMonth = dt.dayOfMonth().withMaximumValue(); 2238 * </pre> 2239 * <p> 2240 * The LocalDateTime attached to this property is unchanged by this call. 2241 * 2242 * @return a copy of the LocalDateTime with this field set to its maximum 2243 */ 2244 public LocalDateTime withMaximumValue() { 2245 return setCopy(getMaximumValue()); 2246 } 2247 2248 /** 2249 * Returns a new LocalDateTime with this field set to the minimum value 2250 * for this field. 2251 * <p> 2252 * The LocalDateTime attached to this property is unchanged by this call. 2253 * 2254 * @return a copy of the LocalDateTime with this field set to its minimum 2255 */ 2256 public LocalDateTime withMinimumValue() { 2257 return setCopy(getMinimumValue()); 2258 } 2259 2260 //----------------------------------------------------------------------- 2261 /** 2262 * Rounds to the lowest whole unit of this field on a copy of this 2263 * LocalDateTime. 2264 * <p> 2265 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2266 * where the time is 10:30 would result in new LocalDateTime with the 2267 * time of 10:00. 2268 * 2269 * @return a copy of the LocalDateTime with the field value changed 2270 */ 2271 public LocalDateTime roundFloorCopy() { 2272 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis())); 2273 } 2274 2275 /** 2276 * Rounds to the highest whole unit of this field on a copy of this 2277 * LocalDateTime. 2278 * <p> 2279 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2280 * where the time is 10:30 would result in new LocalDateTime with the 2281 * time of 11:00. 2282 * 2283 * @return a copy of the LocalDateTime with the field value changed 2284 */ 2285 public LocalDateTime roundCeilingCopy() { 2286 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis())); 2287 } 2288 2289 /** 2290 * Rounds to the nearest whole unit of this field on a copy of this 2291 * LocalDateTime, favoring the floor if halfway. 2292 * 2293 * @return a copy of the LocalDateTime with the field value changed 2294 */ 2295 public LocalDateTime roundHalfFloorCopy() { 2296 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis())); 2297 } 2298 2299 /** 2300 * Rounds to the nearest whole unit of this field on a copy of this 2301 * LocalDateTime, favoring the ceiling if halfway. 2302 * 2303 * @return a copy of the LocalDateTime with the field value changed 2304 */ 2305 public LocalDateTime roundHalfCeilingCopy() { 2306 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis())); 2307 } 2308 2309 /** 2310 * Rounds to the nearest whole unit of this field on a copy of this 2311 * LocalDateTime. If halfway, the ceiling is favored over the floor 2312 * only if it makes this field's value even. 2313 * 2314 * @return a copy of the LocalDateTime with the field value changed 2315 */ 2316 public LocalDateTime roundHalfEvenCopy() { 2317 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis())); 2318 } 2319 } 2320 2321 }