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 (iChronology == null) { 510 return new LocalDateTime(iLocalMillis, ISOChronology.getInstanceUTC()); 511 } 512 if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) { 513 return new LocalDateTime(iLocalMillis, iChronology.withUTC()); 514 } 515 return this; 516 } 517 518 //----------------------------------------------------------------------- 519 /** 520 * Gets the number of fields in this partial, which is four. 521 * The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 522 * 523 * @return the field count, four 524 */ 525 public int size() { 526 return 4; 527 } 528 529 /** 530 * Gets the field for a specific index in the chronology specified. 531 * <p> 532 * This method must not use any instance variables. 533 * 534 * @param index the index to retrieve 535 * @param chrono the chronology to use 536 * @return the field 537 */ 538 protected DateTimeField getField(int index, Chronology chrono) { 539 switch (index) { 540 case YEAR: 541 return chrono.year(); 542 case MONTH_OF_YEAR: 543 return chrono.monthOfYear(); 544 case DAY_OF_MONTH: 545 return chrono.dayOfMonth(); 546 case MILLIS_OF_DAY: 547 return chrono.millisOfDay(); 548 default: 549 throw new IndexOutOfBoundsException("Invalid index: " + index); 550 } 551 } 552 553 /** 554 * Gets the value of the field at the specifed index. 555 * <p> 556 * This method is required to support the <code>ReadablePartial</code> 557 * interface. The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 558 * 559 * @param index the index, zero to two 560 * @return the value 561 * @throws IndexOutOfBoundsException if the index is invalid 562 */ 563 public int getValue(int index) { 564 switch (index) { 565 case YEAR: 566 return getChronology().year().get(getLocalMillis()); 567 case MONTH_OF_YEAR: 568 return getChronology().monthOfYear().get(getLocalMillis()); 569 case DAY_OF_MONTH: 570 return getChronology().dayOfMonth().get(getLocalMillis()); 571 case MILLIS_OF_DAY: 572 return getChronology().millisOfDay().get(getLocalMillis()); 573 default: 574 throw new IndexOutOfBoundsException("Invalid index: " + index); 575 } 576 } 577 578 //----------------------------------------------------------------------- 579 /** 580 * Get the value of one of the fields of a datetime. 581 * <p> 582 * This method gets the value of the specified field. 583 * For example: 584 * <pre> 585 * DateTime dt = new DateTime(); 586 * int year = dt.get(DateTimeFieldType.year()); 587 * </pre> 588 * 589 * @param type a field type, usually obtained from DateTimeFieldType, not null 590 * @return the value of that field 591 * @throws IllegalArgumentException if the field type is null 592 */ 593 public int get(DateTimeFieldType type) { 594 if (type == null) { 595 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 596 } 597 return type.getField(getChronology()).get(getLocalMillis()); 598 } 599 600 /** 601 * Checks if the field type specified is supported by this 602 * local datetime and chronology. 603 * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}. 604 * 605 * @param type a field type, usually obtained from DateTimeFieldType 606 * @return true if the field type is supported 607 */ 608 public boolean isSupported(DateTimeFieldType type) { 609 if (type == null) { 610 return false; 611 } 612 return type.getField(getChronology()).isSupported(); 613 } 614 615 /** 616 * Checks if the duration type specified is supported by this 617 * local datetime and chronology. 618 * 619 * @param type a duration type, usually obtained from DurationFieldType 620 * @return true if the field type is supported 621 */ 622 public boolean isSupported(DurationFieldType type) { 623 if (type == null) { 624 return false; 625 } 626 return type.getField(getChronology()).isSupported(); 627 } 628 629 //----------------------------------------------------------------------- 630 /** 631 * Gets the milliseconds of the datetime instant from the Java epoch 632 * of 1970-01-01T00:00:00 (not fixed to any specific time zone). 633 * 634 * @return the number of milliseconds since 1970-01-01T00:00:00 635 * @since 1.5 (previously private) 636 */ 637 protected long getLocalMillis() { 638 return iLocalMillis; 639 } 640 641 /** 642 * Gets the chronology of the datetime. 643 * 644 * @return the Chronology that the datetime is using 645 */ 646 public Chronology getChronology() { 647 return iChronology; 648 } 649 650 //----------------------------------------------------------------------- 651 /** 652 * Compares this ReadablePartial with another returning true if the chronology, 653 * field types and values are equal. 654 * 655 * @param partial an object to check against 656 * @return true if fields and values are equal 657 */ 658 public boolean equals(Object partial) { 659 // override to perform faster 660 if (this == partial) { 661 return true; 662 } 663 if (partial instanceof LocalDateTime) { 664 LocalDateTime other = (LocalDateTime) partial; 665 if (iChronology.equals(other.iChronology)) { 666 return iLocalMillis == other.iLocalMillis; 667 } 668 } 669 return super.equals(partial); 670 } 671 672 /** 673 * Compares this partial with another returning an integer 674 * indicating the order. 675 * <p> 676 * The fields are compared in order, from largest to smallest. 677 * The first field that is non-equal is used to determine the result. 678 * <p> 679 * The specified object must be a partial instance whose field types 680 * match those of this partial. 681 * 682 * @param partial an object to check against 683 * @return negative if this is less, zero if equal, positive if greater 684 * @throws ClassCastException if the partial is the wrong class 685 * or if it has field types that don't match 686 * @throws NullPointerException if the partial is null 687 */ 688 public int compareTo(ReadablePartial partial) { 689 // override to perform faster 690 if (this == partial) { 691 return 0; 692 } 693 if (partial instanceof LocalDateTime) { 694 LocalDateTime other = (LocalDateTime) partial; 695 if (iChronology.equals(other.iChronology)) { 696 return (iLocalMillis < other.iLocalMillis ? -1 : 697 (iLocalMillis == other.iLocalMillis ? 0 : 1)); 698 699 } 700 } 701 return super.compareTo(partial); 702 } 703 704 //----------------------------------------------------------------------- 705 /** 706 * Converts this object to a DateTime using the default zone. 707 * <p> 708 * This method will throw an exception if the datetime that would be 709 * created does not exist when the time zone is taken into account. 710 * 711 * @return <code>this</code> 712 */ 713 public DateTime toDateTime() { 714 return toDateTime((DateTimeZone) null); 715 } 716 717 /** 718 * Converts this object to a DateTime using the specified zone. 719 * <p> 720 * This method will throw an exception if the datetime that would be 721 * created does not exist when the time zone is taken into account. 722 * 723 * @param zone time zone to apply, or default if null 724 * @return a DateTime using the same millis 725 */ 726 public DateTime toDateTime(DateTimeZone zone) { 727 zone = DateTimeUtils.getZone(zone); 728 Chronology chrono = iChronology.withZone(zone); 729 return new DateTime( 730 getYear(), getMonthOfYear(), getDayOfMonth(), 731 getHourOfDay(), getMinuteOfHour(), 732 getSecondOfMinute(), getMillisOfSecond(), chrono); 733 } 734 735 //----------------------------------------------------------------------- 736 /** 737 * Converts this object to a LocalDate with the same date and chronology. 738 * 739 * @return a LocalDate with the same date and chronology 740 */ 741 public LocalDate toLocalDate() { 742 return new LocalDate(getLocalMillis(), getChronology()); 743 } 744 745 /** 746 * Converts this object to a LocalTime with the same time and chronology. 747 * 748 * @return a LocalTime with the same time and chronology 749 */ 750 public LocalTime toLocalTime() { 751 return new LocalTime(getLocalMillis(), getChronology()); 752 } 753 754 //----------------------------------------------------------------------- 755 /** 756 * Get the date time as a <code>java.util.Date</code>. 757 * <p> 758 * The <code>Date</code> object created has exactly the same fields as this 759 * date-time, except when the time would be invalid due to a daylight savings 760 * gap. In that case, the time will be set to the earliest valid time after the gap. 761 * <p> 762 * In the case of a daylight savings overlap, the earlier instant is selected. 763 * <p> 764 * Converting to a JDK Date is full of complications as the JDK Date constructor 765 * doesn't behave as you might expect around DST transitions. This method works 766 * by taking a first guess and then adjusting. This also handles the situation 767 * where the JDK time zone data differs from the Joda-Time time zone data. 768 * 769 * @return a Date initialised with this date-time, never null 770 * @since 2.0 771 */ 772 @SuppressWarnings("deprecation") 773 public Date toDate() { 774 int dom = getDayOfMonth(); 775 Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom, 776 getHourOfDay(), getMinuteOfHour(), getSecondOfMinute()); 777 date.setTime(date.getTime() + getMillisOfSecond()); 778 LocalDateTime check = LocalDateTime.fromDateFields(date); 779 if (check.isBefore(this)) { 780 // DST gap 781 // move forward in units of one minute until equal/after 782 while (check.isBefore(this)) { 783 date.setTime(date.getTime() + 60000); 784 check = LocalDateTime.fromDateFields(date); 785 } 786 // move back in units of one second until date wrong 787 while (check.isBefore(this) == false) { 788 date.setTime(date.getTime() - 1000); 789 check = LocalDateTime.fromDateFields(date); 790 } 791 date.setTime(date.getTime() + 1000); 792 } else if (check.equals(this)) { 793 // check for DST overlap 794 Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings()); 795 check = LocalDateTime.fromDateFields(earlier); 796 if (check.equals(this)) { 797 date = earlier; 798 } 799 } 800 return date; 801 } 802 803 //----------------------------------------------------------------------- 804 /** 805 * Returns a copy of this datetime with different local millis. 806 * <p> 807 * The returned object will be a new instance of the same type. 808 * Only the millis will change, the chronology is kept. 809 * The returned object will be either be a new instance or <code>this</code>. 810 * 811 * @param newMillis the new millis, from 1970-01-01T00:00:00 812 * @return a copy of this datetime with different millis 813 */ 814 LocalDateTime withLocalMillis(long newMillis) { 815 return (newMillis == getLocalMillis() ? this : new LocalDateTime(newMillis, getChronology())); 816 } 817 818 //----------------------------------------------------------------------- 819 /** 820 * Returns a copy of this datetime with the specified date, 821 * retaining the time fields. 822 * <p> 823 * If the date is already the date passed in, then <code>this</code> is returned. 824 * <p> 825 * To set a single field use the properties, for example: 826 * <pre> 827 * DateTime set = dt.monthOfYear().setCopy(6); 828 * </pre> 829 * 830 * @param year the new year value 831 * @param monthOfYear the new monthOfYear value 832 * @param dayOfMonth the new dayOfMonth value 833 * @return a copy of this datetime with a different date 834 * @throws IllegalArgumentException if any value if invalid 835 */ 836 public LocalDateTime withDate(int year, int monthOfYear, int dayOfMonth) { 837 Chronology chrono = getChronology(); 838 long instant = getLocalMillis(); 839 instant = chrono.year().set(instant, year); 840 instant = chrono.monthOfYear().set(instant, monthOfYear); 841 instant = chrono.dayOfMonth().set(instant, dayOfMonth); 842 return withLocalMillis(instant); 843 } 844 845 /** 846 * Returns a copy of this datetime with the specified time, 847 * retaining the date fields. 848 * <p> 849 * If the time is already the time passed in, then <code>this</code> is returned. 850 * <p> 851 * To set a single field use the properties, for example: 852 * <pre> 853 * LocalDateTime set = dt.hourOfDay().setCopy(6); 854 * </pre> 855 * 856 * @param hourOfDay the hour of the day 857 * @param minuteOfHour the minute of the hour 858 * @param secondOfMinute the second of the minute 859 * @param millisOfSecond the millisecond of the second 860 * @return a copy of this datetime with a different time 861 * @throws IllegalArgumentException if any value if invalid 862 */ 863 public LocalDateTime withTime(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) { 864 Chronology chrono = getChronology(); 865 long instant = getLocalMillis(); 866 instant = chrono.hourOfDay().set(instant, hourOfDay); 867 instant = chrono.minuteOfHour().set(instant, minuteOfHour); 868 instant = chrono.secondOfMinute().set(instant, secondOfMinute); 869 instant = chrono.millisOfSecond().set(instant, millisOfSecond); 870 return withLocalMillis(instant); 871 } 872 873 //----------------------------------------------------------------------- 874 /** 875 * Returns a copy of this datetime with the partial set of fields 876 * replacing those from this instance. 877 * <p> 878 * For example, if the partial is a <code>TimeOfDay</code> then the time fields 879 * would be changed in the returned instance. 880 * If the partial is null, then <code>this</code> is returned. 881 * 882 * @param partial the partial set of fields to apply to this datetime, null ignored 883 * @return a copy of this datetime with a different set of fields 884 * @throws IllegalArgumentException if any value is invalid 885 */ 886 public LocalDateTime withFields(ReadablePartial partial) { 887 if (partial == null) { 888 return this; 889 } 890 return withLocalMillis(getChronology().set(partial, getLocalMillis())); 891 } 892 893 /** 894 * Returns a copy of this datetime with the specified field set to a new value. 895 * <p> 896 * For example, if the field type is <code>hourOfDay</code> then the hour of day 897 * field would be changed in the returned instance. 898 * If the field type is null, then <code>this</code> is returned. 899 * <p> 900 * These three lines are equivalent: 901 * <pre> 902 * LocalDateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6); 903 * LocalDateTime updated = dt.dayOfMonth().setCopy(6); 904 * LocalDateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6); 905 * </pre> 906 * 907 * @param fieldType the field type to set, not null 908 * @param value the value to set 909 * @return a copy of this datetime with the field set 910 * @throws IllegalArgumentException if the value is null or invalid 911 */ 912 public LocalDateTime withField(DateTimeFieldType fieldType, int value) { 913 if (fieldType == null) { 914 throw new IllegalArgumentException("Field must not be null"); 915 } 916 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value); 917 return withLocalMillis(instant); 918 } 919 920 /** 921 * Returns a copy of this datetime with the value of the specified 922 * field increased. 923 * <p> 924 * If the addition is zero or the field is null, then <code>this</code> is returned. 925 * <p> 926 * These three lines are equivalent: 927 * <pre> 928 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 929 * LocalDateTime added = dt.plusYears(6); 930 * LocalDateTime added = dt.plus(Period.years(6)); 931 * </pre> 932 * 933 * @param fieldType the field type to add to, not null 934 * @param amount the amount to add 935 * @return a copy of this datetime with the field updated 936 * @throws IllegalArgumentException if the value is null or invalid 937 * @throws ArithmeticException if the result exceeds the internal capacity 938 */ 939 public LocalDateTime withFieldAdded(DurationFieldType fieldType, int amount) { 940 if (fieldType == null) { 941 throw new IllegalArgumentException("Field must not be null"); 942 } 943 if (amount == 0) { 944 return this; 945 } 946 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount); 947 return withLocalMillis(instant); 948 } 949 950 //----------------------------------------------------------------------- 951 /** 952 * Returns a copy of this datetime with the specified duration added. 953 * <p> 954 * If the addition is zero, then <code>this</code> is returned. 955 * 956 * @param durationToAdd the duration to add to this one, null means zero 957 * @param scalar the amount of times to add, such as -1 to subtract once 958 * @return a copy of this datetime with the duration added 959 * @throws ArithmeticException if the result exceeds the internal capacity 960 */ 961 public LocalDateTime withDurationAdded(ReadableDuration durationToAdd, int scalar) { 962 if (durationToAdd == null || scalar == 0) { 963 return this; 964 } 965 long instant = getChronology().add(getLocalMillis(), durationToAdd.getMillis(), scalar); 966 return withLocalMillis(instant); 967 } 968 969 /** 970 * Returns a copy of this datetime with the specified period added. 971 * <p> 972 * If the addition is zero, then <code>this</code> is returned. 973 * <p> 974 * This method is typically used to add multiple copies of complex 975 * period instances. Adding one field is best achieved using methods 976 * like {@link #withFieldAdded(DurationFieldType, int)} 977 * or {@link #plusYears(int)}. 978 * 979 * @param period the period to add to this one, null means zero 980 * @param scalar the amount of times to add, such as -1 to subtract once 981 * @return a copy of this datetime with the period added 982 * @throws ArithmeticException if the result exceeds the internal capacity 983 */ 984 public LocalDateTime withPeriodAdded(ReadablePeriod period, int scalar) { 985 if (period == null || scalar == 0) { 986 return this; 987 } 988 long instant = getChronology().add(period, getLocalMillis(), scalar); 989 return withLocalMillis(instant); 990 } 991 992 //----------------------------------------------------------------------- 993 /** 994 * Returns a copy of this datetime with the specified duration added. 995 * <p> 996 * If the amount is zero or null, then <code>this</code> is returned. 997 * 998 * @param duration the duration to add to this one, null means zero 999 * @return a copy of this datetime with the duration added 1000 * @throws ArithmeticException if the result exceeds the internal capacity 1001 */ 1002 public LocalDateTime plus(ReadableDuration duration) { 1003 return withDurationAdded(duration, 1); 1004 } 1005 1006 /** 1007 * Returns a copy of this datetime with the specified period added. 1008 * <p> 1009 * If the amount is zero or null, then <code>this</code> is returned. 1010 * <p> 1011 * This method is typically used to add complex period instances. 1012 * Adding one field is best achieved using methods 1013 * like {@link #plusYears(int)}. 1014 * 1015 * @param period the period to add to this one, null means zero 1016 * @return a copy of this datetime with the period added 1017 * @throws ArithmeticException if the result exceeds the internal capacity 1018 */ 1019 public LocalDateTime plus(ReadablePeriod period) { 1020 return withPeriodAdded(period, 1); 1021 } 1022 1023 //----------------------------------------------------------------------- 1024 /** 1025 * Returns a copy of this datetime plus the specified number of years. 1026 * <p> 1027 * This LocalDateTime instance is immutable and unaffected by this method call. 1028 * <p> 1029 * The following three lines are identical in effect: 1030 * <pre> 1031 * LocalDateTime added = dt.plusYears(6); 1032 * LocalDateTime added = dt.plus(Period.years(6)); 1033 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 1034 * </pre> 1035 * 1036 * @param years the amount of years to add, may be negative 1037 * @return the new LocalDateTime plus the increased years 1038 */ 1039 public LocalDateTime plusYears(int years) { 1040 if (years == 0) { 1041 return this; 1042 } 1043 long instant = getChronology().years().add(getLocalMillis(), years); 1044 return withLocalMillis(instant); 1045 } 1046 1047 /** 1048 * Returns a copy of this datetime plus the specified number of months. 1049 * <p> 1050 * This LocalDateTime instance is immutable and unaffected by this method call. 1051 * <p> 1052 * The following three lines are identical in effect: 1053 * <pre> 1054 * LocalDateTime added = dt.plusMonths(6); 1055 * LocalDateTime added = dt.plus(Period.months(6)); 1056 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.months(), 6); 1057 * </pre> 1058 * 1059 * @param months the amount of months to add, may be negative 1060 * @return the new LocalDateTime plus the increased months 1061 */ 1062 public LocalDateTime plusMonths(int months) { 1063 if (months == 0) { 1064 return this; 1065 } 1066 long instant = getChronology().months().add(getLocalMillis(), months); 1067 return withLocalMillis(instant); 1068 } 1069 1070 /** 1071 * Returns a copy of this datetime plus the specified number of weeks. 1072 * <p> 1073 * This LocalDateTime instance is immutable and unaffected by this method call. 1074 * <p> 1075 * The following three lines are identical in effect: 1076 * <pre> 1077 * LocalDateTime added = dt.plusWeeks(6); 1078 * LocalDateTime added = dt.plus(Period.weeks(6)); 1079 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.weeks(), 6); 1080 * </pre> 1081 * 1082 * @param weeks the amount of weeks to add, may be negative 1083 * @return the new LocalDateTime plus the increased weeks 1084 */ 1085 public LocalDateTime plusWeeks(int weeks) { 1086 if (weeks == 0) { 1087 return this; 1088 } 1089 long instant = getChronology().weeks().add(getLocalMillis(), weeks); 1090 return withLocalMillis(instant); 1091 } 1092 1093 /** 1094 * Returns a copy of this datetime plus the specified number of days. 1095 * <p> 1096 * This LocalDateTime instance is immutable and unaffected by this method call. 1097 * <p> 1098 * The following three lines are identical in effect: 1099 * <pre> 1100 * LocalDateTime added = dt.plusDays(6); 1101 * LocalDateTime added = dt.plus(Period.days(6)); 1102 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.days(), 6); 1103 * </pre> 1104 * 1105 * @param days the amount of days to add, may be negative 1106 * @return the new LocalDateTime plus the increased days 1107 */ 1108 public LocalDateTime plusDays(int days) { 1109 if (days == 0) { 1110 return this; 1111 } 1112 long instant = getChronology().days().add(getLocalMillis(), days); 1113 return withLocalMillis(instant); 1114 } 1115 1116 //----------------------------------------------------------------------- 1117 /** 1118 * Returns a copy of this datetime plus the specified number of hours. 1119 * <p> 1120 * This LocalDateTime instance is immutable and unaffected by this method call. 1121 * <p> 1122 * The following three lines are identical in effect: 1123 * <pre> 1124 * LocalDateTime added = dt.plusHours(6); 1125 * LocalDateTime added = dt.plus(Period.hours(6)); 1126 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.hours(), 6); 1127 * </pre> 1128 * 1129 * @param hours the amount of hours to add, may be negative 1130 * @return the new LocalDateTime plus the increased hours 1131 */ 1132 public LocalDateTime plusHours(int hours) { 1133 if (hours == 0) { 1134 return this; 1135 } 1136 long instant = getChronology().hours().add(getLocalMillis(), hours); 1137 return withLocalMillis(instant); 1138 } 1139 1140 /** 1141 * Returns a copy of this datetime plus the specified number of minutes. 1142 * <p> 1143 * This LocalDateTime instance is immutable and unaffected by this method call. 1144 * <p> 1145 * The following three lines are identical in effect: 1146 * <pre> 1147 * LocalDateTime added = dt.plusMinutes(6); 1148 * LocalDateTime added = dt.plus(Period.minutes(6)); 1149 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6); 1150 * </pre> 1151 * 1152 * @param minutes the amount of minutes to add, may be negative 1153 * @return the new LocalDateTime plus the increased minutes 1154 */ 1155 public LocalDateTime plusMinutes(int minutes) { 1156 if (minutes == 0) { 1157 return this; 1158 } 1159 long instant = getChronology().minutes().add(getLocalMillis(), minutes); 1160 return withLocalMillis(instant); 1161 } 1162 1163 /** 1164 * Returns a copy of this datetime plus the specified number of seconds. 1165 * <p> 1166 * This LocalDateTime instance is immutable and unaffected by this method call. 1167 * <p> 1168 * The following three lines are identical in effect: 1169 * <pre> 1170 * LocalDateTime added = dt.plusSeconds(6); 1171 * LocalDateTime added = dt.plus(Period.seconds(6)); 1172 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6); 1173 * </pre> 1174 * 1175 * @param seconds the amount of seconds to add, may be negative 1176 * @return the new LocalDateTime plus the increased seconds 1177 */ 1178 public LocalDateTime plusSeconds(int seconds) { 1179 if (seconds == 0) { 1180 return this; 1181 } 1182 long instant = getChronology().seconds().add(getLocalMillis(), seconds); 1183 return withLocalMillis(instant); 1184 } 1185 1186 /** 1187 * Returns a copy of this datetime plus the specified number of millis. 1188 * <p> 1189 * This LocalDateTime instance is immutable and unaffected by this method call. 1190 * <p> 1191 * The following three lines are identical in effect: 1192 * <pre> 1193 * LocalDateTime added = dt.plusMillis(6); 1194 * LocalDateTime added = dt.plus(Period.millis(6)); 1195 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.millis(), 6); 1196 * </pre> 1197 * 1198 * @param millis the amount of millis to add, may be negative 1199 * @return the new LocalDateTime plus the increased millis 1200 */ 1201 public LocalDateTime plusMillis(int millis) { 1202 if (millis == 0) { 1203 return this; 1204 } 1205 long instant = getChronology().millis().add(getLocalMillis(), millis); 1206 return withLocalMillis(instant); 1207 } 1208 1209 //----------------------------------------------------------------------- 1210 /** 1211 * Returns a copy of this datetime with the specified duration taken away. 1212 * <p> 1213 * If the amount is zero or null, then <code>this</code> is returned. 1214 * 1215 * @param duration the duration to reduce this instant by 1216 * @return a copy of this datetime with the duration taken away 1217 * @throws ArithmeticException if the result exceeds the internal capacity 1218 */ 1219 public LocalDateTime minus(ReadableDuration duration) { 1220 return withDurationAdded(duration, -1); 1221 } 1222 1223 /** 1224 * Returns a copy of this datetime with the specified period taken away. 1225 * <p> 1226 * If the amount is zero or null, then <code>this</code> is returned. 1227 * <p> 1228 * This method is typically used to subtract complex period instances. 1229 * Subtracting one field is best achieved using methods 1230 * like {@link #minusYears(int)}. 1231 * 1232 * @param period the period to reduce this instant by 1233 * @return a copy of this datetime with the period taken away 1234 * @throws ArithmeticException if the result exceeds the internal capacity 1235 */ 1236 public LocalDateTime minus(ReadablePeriod period) { 1237 return withPeriodAdded(period, -1); 1238 } 1239 1240 //----------------------------------------------------------------------- 1241 /** 1242 * Returns a copy of this datetime minus the specified number of years. 1243 * <p> 1244 * This LocalDateTime instance is immutable and unaffected by this method call. 1245 * <p> 1246 * The following three lines are identical in effect: 1247 * <pre> 1248 * LocalDateTime subtracted = dt.minusYears(6); 1249 * LocalDateTime subtracted = dt.minus(Period.years(6)); 1250 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6); 1251 * </pre> 1252 * 1253 * @param years the amount of years to subtract, may be negative 1254 * @return the new LocalDateTime minus the increased years 1255 */ 1256 public LocalDateTime minusYears(int years) { 1257 if (years == 0) { 1258 return this; 1259 } 1260 long instant = getChronology().years().subtract(getLocalMillis(), years); 1261 return withLocalMillis(instant); 1262 } 1263 1264 /** 1265 * Returns a copy of this datetime minus the specified number of months. 1266 * <p> 1267 * This LocalDateTime instance is immutable and unaffected by this method call. 1268 * <p> 1269 * The following three lines are identical in effect: 1270 * <pre> 1271 * LocalDateTime subtracted = dt.minusMonths(6); 1272 * LocalDateTime subtracted = dt.minus(Period.months(6)); 1273 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.months(), -6); 1274 * </pre> 1275 * 1276 * @param months the amount of months to subtract, may be negative 1277 * @return the new LocalDateTime minus the increased months 1278 */ 1279 public LocalDateTime minusMonths(int months) { 1280 if (months == 0) { 1281 return this; 1282 } 1283 long instant = getChronology().months().subtract(getLocalMillis(), months); 1284 return withLocalMillis(instant); 1285 } 1286 1287 /** 1288 * Returns a copy of this datetime minus the specified number of weeks. 1289 * <p> 1290 * This LocalDateTime instance is immutable and unaffected by this method call. 1291 * <p> 1292 * The following three lines are identical in effect: 1293 * <pre> 1294 * LocalDateTime subtracted = dt.minusWeeks(6); 1295 * LocalDateTime subtracted = dt.minus(Period.weeks(6)); 1296 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6); 1297 * </pre> 1298 * 1299 * @param weeks the amount of weeks to subtract, may be negative 1300 * @return the new LocalDateTime minus the increased weeks 1301 */ 1302 public LocalDateTime minusWeeks(int weeks) { 1303 if (weeks == 0) { 1304 return this; 1305 } 1306 long instant = getChronology().weeks().subtract(getLocalMillis(), weeks); 1307 return withLocalMillis(instant); 1308 } 1309 1310 /** 1311 * Returns a copy of this datetime minus the specified number of days. 1312 * <p> 1313 * This LocalDateTime instance is immutable and unaffected by this method call. 1314 * <p> 1315 * The following three lines are identical in effect: 1316 * <pre> 1317 * LocalDateTime subtracted = dt.minusDays(6); 1318 * LocalDateTime subtracted = dt.minus(Period.days(6)); 1319 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.days(), -6); 1320 * </pre> 1321 * 1322 * @param days the amount of days to subtract, may be negative 1323 * @return the new LocalDateTime minus the increased days 1324 */ 1325 public LocalDateTime minusDays(int days) { 1326 if (days == 0) { 1327 return this; 1328 } 1329 long instant = getChronology().days().subtract(getLocalMillis(), days); 1330 return withLocalMillis(instant); 1331 } 1332 1333 //----------------------------------------------------------------------- 1334 /** 1335 * Returns a copy of this datetime minus the specified number of hours. 1336 * <p> 1337 * This LocalDateTime instance is immutable and unaffected by this method call. 1338 * <p> 1339 * The following three lines are identical in effect: 1340 * <pre> 1341 * LocalDateTime subtracted = dt.minusHours(6); 1342 * LocalDateTime subtracted = dt.minus(Period.hours(6)); 1343 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6); 1344 * </pre> 1345 * 1346 * @param hours the amount of hours to subtract, may be negative 1347 * @return the new LocalDateTime minus the increased hours 1348 */ 1349 public LocalDateTime minusHours(int hours) { 1350 if (hours == 0) { 1351 return this; 1352 } 1353 long instant = getChronology().hours().subtract(getLocalMillis(), hours); 1354 return withLocalMillis(instant); 1355 } 1356 1357 /** 1358 * Returns a copy of this datetime minus the specified number of minutes. 1359 * <p> 1360 * This LocalDateTime instance is immutable and unaffected by this method call. 1361 * <p> 1362 * The following three lines are identical in effect: 1363 * <pre> 1364 * LocalDateTime subtracted = dt.minusMinutes(6); 1365 * LocalDateTime subtracted = dt.minus(Period.minutes(6)); 1366 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6); 1367 * </pre> 1368 * 1369 * @param minutes the amount of minutes to subtract, may be negative 1370 * @return the new LocalDateTime minus the increased minutes 1371 */ 1372 public LocalDateTime minusMinutes(int minutes) { 1373 if (minutes == 0) { 1374 return this; 1375 } 1376 long instant = getChronology().minutes().subtract(getLocalMillis(), minutes); 1377 return withLocalMillis(instant); 1378 } 1379 1380 /** 1381 * Returns a copy of this datetime minus the specified number of seconds. 1382 * <p> 1383 * This LocalDateTime instance is immutable and unaffected by this method call. 1384 * <p> 1385 * The following three lines are identical in effect: 1386 * <pre> 1387 * LocalDateTime subtracted = dt.minusSeconds(6); 1388 * LocalDateTime subtracted = dt.minus(Period.seconds(6)); 1389 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6); 1390 * </pre> 1391 * 1392 * @param seconds the amount of seconds to subtract, may be negative 1393 * @return the new LocalDateTime minus the increased seconds 1394 */ 1395 public LocalDateTime minusSeconds(int seconds) { 1396 if (seconds == 0) { 1397 return this; 1398 } 1399 long instant = getChronology().seconds().subtract(getLocalMillis(), seconds); 1400 return withLocalMillis(instant); 1401 } 1402 1403 /** 1404 * Returns a copy of this datetime minus the specified number of millis. 1405 * <p> 1406 * This LocalDateTime instance is immutable and unaffected by this method call. 1407 * <p> 1408 * The following three lines are identical in effect: 1409 * <pre> 1410 * LocalDateTime subtracted = dt.minusMillis(6); 1411 * LocalDateTime subtracted = dt.minus(Period.millis(6)); 1412 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6); 1413 * </pre> 1414 * 1415 * @param millis the amount of millis to subtract, may be negative 1416 * @return the new LocalDateTime minus the increased millis 1417 */ 1418 public LocalDateTime minusMillis(int millis) { 1419 if (millis == 0) { 1420 return this; 1421 } 1422 long instant = getChronology().millis().subtract(getLocalMillis(), millis); 1423 return withLocalMillis(instant); 1424 } 1425 1426 //----------------------------------------------------------------------- 1427 /** 1428 * Gets the property object for the specified type, which contains many 1429 * useful methods. 1430 * 1431 * @param fieldType the field type to get the chronology for 1432 * @return the property object 1433 * @throws IllegalArgumentException if the field is null or unsupported 1434 */ 1435 public Property property(DateTimeFieldType fieldType) { 1436 if (fieldType == null) { 1437 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 1438 } 1439 if (isSupported(fieldType) == false) { 1440 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported"); 1441 } 1442 return new Property(this, fieldType.getField(getChronology())); 1443 } 1444 1445 //----------------------------------------------------------------------- 1446 /** 1447 * Get the era field value. 1448 * 1449 * @return the era 1450 */ 1451 public int getEra() { 1452 return getChronology().era().get(getLocalMillis()); 1453 } 1454 1455 /** 1456 * Get the year of era field value. 1457 * 1458 * @return the year of era 1459 */ 1460 public int getCenturyOfEra() { 1461 return getChronology().centuryOfEra().get(getLocalMillis()); 1462 } 1463 1464 /** 1465 * Get the year of era field value. 1466 * 1467 * @return the year of era 1468 */ 1469 public int getYearOfEra() { 1470 return getChronology().yearOfEra().get(getLocalMillis()); 1471 } 1472 1473 /** 1474 * Get the year of century field value. 1475 * 1476 * @return the year of century 1477 */ 1478 public int getYearOfCentury() { 1479 return getChronology().yearOfCentury().get(getLocalMillis()); 1480 } 1481 1482 /** 1483 * Get the year field value. 1484 * 1485 * @return the year 1486 */ 1487 public int getYear() { 1488 return getChronology().year().get(getLocalMillis()); 1489 } 1490 1491 /** 1492 * Get the weekyear field value. 1493 * <p> 1494 * The weekyear is the year that matches with the weekOfWeekyear field. 1495 * In the standard ISO8601 week algorithm, the first week of the year 1496 * is that in which at least 4 days are in the year. As a result of this 1497 * definition, day 1 of the first week may be in the previous year. 1498 * The weekyear allows you to query the effective year for that day. 1499 * 1500 * @return the weekyear 1501 */ 1502 public int getWeekyear() { 1503 return getChronology().weekyear().get(getLocalMillis()); 1504 } 1505 1506 /** 1507 * Get the month of year field value. 1508 * 1509 * @return the month of year 1510 */ 1511 public int getMonthOfYear() { 1512 return getChronology().monthOfYear().get(getLocalMillis()); 1513 } 1514 1515 /** 1516 * Get the week of weekyear field value. 1517 * <p> 1518 * This field is associated with the "weekyear" via {@link #getWeekyear()}. 1519 * In the standard ISO8601 week algorithm, the first week of the year 1520 * is that in which at least 4 days are in the year. As a result of this 1521 * definition, day 1 of the first week may be in the previous year. 1522 * 1523 * @return the week of a week based year 1524 */ 1525 public int getWeekOfWeekyear() { 1526 return getChronology().weekOfWeekyear().get(getLocalMillis()); 1527 } 1528 1529 /** 1530 * Get the day of year field value. 1531 * 1532 * @return the day of year 1533 */ 1534 public int getDayOfYear() { 1535 return getChronology().dayOfYear().get(getLocalMillis()); 1536 } 1537 1538 /** 1539 * Get the day of month field value. 1540 * <p> 1541 * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}. 1542 * 1543 * @return the day of month 1544 */ 1545 public int getDayOfMonth() { 1546 return getChronology().dayOfMonth().get(getLocalMillis()); 1547 } 1548 1549 /** 1550 * Get the day of week field value. 1551 * <p> 1552 * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}. 1553 * 1554 * @return the day of week 1555 */ 1556 public int getDayOfWeek() { 1557 return getChronology().dayOfWeek().get(getLocalMillis()); 1558 } 1559 1560 //----------------------------------------------------------------------- 1561 /** 1562 * Get the hour of day field value. 1563 * 1564 * @return the hour of day 1565 */ 1566 public int getHourOfDay() { 1567 return getChronology().hourOfDay().get(getLocalMillis()); 1568 } 1569 1570 /** 1571 * Get the minute of hour field value. 1572 * 1573 * @return the minute of hour 1574 */ 1575 public int getMinuteOfHour() { 1576 return getChronology().minuteOfHour().get(getLocalMillis()); 1577 } 1578 1579 /** 1580 * Get the second of minute field value. 1581 * 1582 * @return the second of minute 1583 */ 1584 public int getSecondOfMinute() { 1585 return getChronology().secondOfMinute().get(getLocalMillis()); 1586 } 1587 1588 /** 1589 * Get the millis of second field value. 1590 * 1591 * @return the millis of second 1592 */ 1593 public int getMillisOfSecond() { 1594 return getChronology().millisOfSecond().get(getLocalMillis()); 1595 } 1596 1597 /** 1598 * Get the millis of day field value. 1599 * 1600 * @return the millis of day 1601 */ 1602 public int getMillisOfDay() { 1603 return getChronology().millisOfDay().get(getLocalMillis()); 1604 } 1605 1606 //----------------------------------------------------------------------- 1607 /** 1608 * Returns a copy of this datetime with the era field updated. 1609 * <p> 1610 * LocalDateTime is immutable, so there are no set methods. 1611 * Instead, this method returns a new instance with the value of 1612 * era changed. 1613 * 1614 * @param era the era to set 1615 * @return a copy of this object with the field set 1616 * @throws IllegalArgumentException if the value is invalid 1617 */ 1618 public LocalDateTime withEra(int era) { 1619 return withLocalMillis(getChronology().era().set(getLocalMillis(), era)); 1620 } 1621 1622 /** 1623 * Returns a copy of this datetime with the century of era field updated. 1624 * <p> 1625 * LocalDateTime is immutable, so there are no set methods. 1626 * Instead, this method returns a new instance with the value of 1627 * century of era changed. 1628 * 1629 * @param centuryOfEra the centurey of era to set 1630 * @return a copy of this object with the field set 1631 * @throws IllegalArgumentException if the value is invalid 1632 */ 1633 public LocalDateTime withCenturyOfEra(int centuryOfEra) { 1634 return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra)); 1635 } 1636 1637 /** 1638 * Returns a copy of this datetime with the year of era field updated. 1639 * <p> 1640 * LocalDateTime is immutable, so there are no set methods. 1641 * Instead, this method returns a new instance with the value of 1642 * year of era changed. 1643 * 1644 * @param yearOfEra the year of era to set 1645 * @return a copy of this object with the field set 1646 * @throws IllegalArgumentException if the value is invalid 1647 */ 1648 public LocalDateTime withYearOfEra(int yearOfEra) { 1649 return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra)); 1650 } 1651 1652 /** 1653 * Returns a copy of this datetime with the year of century field updated. 1654 * <p> 1655 * LocalDateTime is immutable, so there are no set methods. 1656 * Instead, this method returns a new instance with the value of 1657 * year of century changed. 1658 * 1659 * @param yearOfCentury the year of century to set 1660 * @return a copy of this object with the field set 1661 * @throws IllegalArgumentException if the value is invalid 1662 */ 1663 public LocalDateTime withYearOfCentury(int yearOfCentury) { 1664 return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury)); 1665 } 1666 1667 /** 1668 * Returns a copy of this datetime with the year field updated. 1669 * <p> 1670 * LocalDateTime is immutable, so there are no set methods. 1671 * Instead, this method returns a new instance with the value of 1672 * year changed. 1673 * 1674 * @param year the year to set 1675 * @return a copy of this object with the field set 1676 * @throws IllegalArgumentException if the value is invalid 1677 */ 1678 public LocalDateTime withYear(int year) { 1679 return withLocalMillis(getChronology().year().set(getLocalMillis(), year)); 1680 } 1681 1682 /** 1683 * Returns a copy of this datetime with the weekyear field updated. 1684 * <p> 1685 * The weekyear is the year that matches with the weekOfWeekyear field. 1686 * In the standard ISO8601 week algorithm, the first week of the year 1687 * is that in which at least 4 days are in the year. As a result of this 1688 * definition, day 1 of the first week may be in the previous year. 1689 * The weekyear allows you to query the effective year for that day. 1690 * <p> 1691 * LocalDateTime is immutable, so there are no set methods. 1692 * Instead, this method returns a new instance with the value of 1693 * weekyear changed. 1694 * 1695 * @param weekyear the weekyear to set 1696 * @return a copy of this object with the field set 1697 * @throws IllegalArgumentException if the value is invalid 1698 */ 1699 public LocalDateTime withWeekyear(int weekyear) { 1700 return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear)); 1701 } 1702 1703 /** 1704 * Returns a copy of this datetime with the month of year field updated. 1705 * <p> 1706 * LocalDateTime is immutable, so there are no set methods. 1707 * Instead, this method returns a new instance with the value of 1708 * month of year changed. 1709 * 1710 * @param monthOfYear the month of year to set 1711 * @return a copy of this object with the field set 1712 * @throws IllegalArgumentException if the value is invalid 1713 */ 1714 public LocalDateTime withMonthOfYear(int monthOfYear) { 1715 return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear)); 1716 } 1717 1718 /** 1719 * Returns a copy of this datetime with the week of weekyear field updated. 1720 * <p> 1721 * This field is associated with the "weekyear" via {@link #withWeekyear(int)}. 1722 * In the standard ISO8601 week algorithm, the first week of the year 1723 * is that in which at least 4 days are in the year. As a result of this 1724 * definition, day 1 of the first week may be in the previous year. 1725 * <p> 1726 * LocalDateTime is immutable, so there are no set methods. 1727 * Instead, this method returns a new instance with the value of 1728 * week of weekyear changed. 1729 * 1730 * @param weekOfWeekyear the week of weekyear to set 1731 * @return a copy of this object with the field set 1732 * @throws IllegalArgumentException if the value is invalid 1733 */ 1734 public LocalDateTime withWeekOfWeekyear(int weekOfWeekyear) { 1735 return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear)); 1736 } 1737 1738 /** 1739 * Returns a copy of this datetime with the day of year field updated. 1740 * <p> 1741 * LocalDateTime is immutable, so there are no set methods. 1742 * Instead, this method returns a new instance with the value of 1743 * day of year changed. 1744 * 1745 * @param dayOfYear the day of year to set 1746 * @return a copy of this object with the field set 1747 * @throws IllegalArgumentException if the value is invalid 1748 */ 1749 public LocalDateTime withDayOfYear(int dayOfYear) { 1750 return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear)); 1751 } 1752 1753 /** 1754 * Returns a copy of this datetime with the day of month field updated. 1755 * <p> 1756 * LocalDateTime is immutable, so there are no set methods. 1757 * Instead, this method returns a new instance with the value of 1758 * day of month changed. 1759 * 1760 * @param dayOfMonth the day of month to set 1761 * @return a copy of this object with the field set 1762 * @throws IllegalArgumentException if the value is invalid 1763 */ 1764 public LocalDateTime withDayOfMonth(int dayOfMonth) { 1765 return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth)); 1766 } 1767 1768 /** 1769 * Returns a copy of this datetime with the day of week field updated. 1770 * <p> 1771 * LocalDateTime is immutable, so there are no set methods. 1772 * Instead, this method returns a new instance with the value of 1773 * day of week changed. 1774 * 1775 * @param dayOfWeek the day of week to set 1776 * @return a copy of this object with the field set 1777 * @throws IllegalArgumentException if the value is invalid 1778 */ 1779 public LocalDateTime withDayOfWeek(int dayOfWeek) { 1780 return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek)); 1781 } 1782 1783 //----------------------------------------------------------------------- 1784 /** 1785 * Returns a copy of this datetime with the hour of day field updated. 1786 * <p> 1787 * LocalDateTime is immutable, so there are no set methods. 1788 * Instead, this method returns a new instance with the value of 1789 * hour of day changed. 1790 * 1791 * @param hour the hour of day to set 1792 * @return a copy of this object with the field set 1793 * @throws IllegalArgumentException if the value is invalid 1794 */ 1795 public LocalDateTime withHourOfDay(int hour) { 1796 return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour)); 1797 } 1798 1799 /** 1800 * Returns a copy of this datetime with the minute of hour field updated. 1801 * <p> 1802 * LocalDateTime is immutable, so there are no set methods. 1803 * Instead, this method returns a new instance with the value of 1804 * minute of hour changed. 1805 * 1806 * @param minute the minute of hour to set 1807 * @return a copy of this object with the field set 1808 * @throws IllegalArgumentException if the value is invalid 1809 */ 1810 public LocalDateTime withMinuteOfHour(int minute) { 1811 return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute)); 1812 } 1813 1814 /** 1815 * Returns a copy of this datetime with the second of minute field updated. 1816 * <p> 1817 * LocalDateTime is immutable, so there are no set methods. 1818 * Instead, this method returns a new instance with the value of 1819 * second of minute changed. 1820 * 1821 * @param second the second of minute to set 1822 * @return a copy of this object with the field set 1823 * @throws IllegalArgumentException if the value is invalid 1824 */ 1825 public LocalDateTime withSecondOfMinute(int second) { 1826 return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second)); 1827 } 1828 1829 /** 1830 * Returns a copy of this datetime with the millis of second field updated. 1831 * <p> 1832 * LocalDateTime is immutable, so there are no set methods. 1833 * Instead, this method returns a new instance with the value of 1834 * millis of second changed. 1835 * 1836 * @param millis the millis of second to set 1837 * @return a copy of this object with the field set 1838 * @throws IllegalArgumentException if the value is invalid 1839 */ 1840 public LocalDateTime withMillisOfSecond(int millis) { 1841 return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis)); 1842 } 1843 1844 /** 1845 * Returns a copy of this datetime with the millis of day field updated. 1846 * <p> 1847 * LocalDateTime is immutable, so there are no set methods. 1848 * Instead, this method returns a new instance with the value of 1849 * millis of day changed. 1850 * 1851 * @param millis the millis of day to set 1852 * @return a copy of this object with the field set 1853 * @throws IllegalArgumentException if the value is invalid 1854 */ 1855 public LocalDateTime withMillisOfDay(int millis) { 1856 return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis)); 1857 } 1858 1859 //----------------------------------------------------------------------- 1860 /** 1861 * Get the era property which provides access to advanced functionality. 1862 * 1863 * @return the era property 1864 */ 1865 public Property era() { 1866 return new Property(this, getChronology().era()); 1867 } 1868 1869 /** 1870 * Get the century of era property which provides access to advanced functionality. 1871 * 1872 * @return the year of era property 1873 */ 1874 public Property centuryOfEra() { 1875 return new Property(this, getChronology().centuryOfEra()); 1876 } 1877 1878 /** 1879 * Get the year of century property which provides access to advanced functionality. 1880 * 1881 * @return the year of era property 1882 */ 1883 public Property yearOfCentury() { 1884 return new Property(this, getChronology().yearOfCentury()); 1885 } 1886 1887 /** 1888 * Get the year of era property which provides access to advanced functionality. 1889 * 1890 * @return the year of era property 1891 */ 1892 public Property yearOfEra() { 1893 return new Property(this, getChronology().yearOfEra()); 1894 } 1895 1896 /** 1897 * Get the year property which provides access to advanced functionality. 1898 * 1899 * @return the year property 1900 */ 1901 public Property year() { 1902 return new Property(this, getChronology().year()); 1903 } 1904 1905 /** 1906 * Get the weekyear property which provides access to advanced functionality. 1907 * 1908 * @return the weekyear property 1909 */ 1910 public Property weekyear() { 1911 return new Property(this, getChronology().weekyear()); 1912 } 1913 1914 /** 1915 * Get the month of year property which provides access to advanced functionality. 1916 * 1917 * @return the month of year property 1918 */ 1919 public Property monthOfYear() { 1920 return new Property(this, getChronology().monthOfYear()); 1921 } 1922 1923 /** 1924 * Get the week of a week based year property which provides access to advanced functionality. 1925 * 1926 * @return the week of a week based year property 1927 */ 1928 public Property weekOfWeekyear() { 1929 return new Property(this, getChronology().weekOfWeekyear()); 1930 } 1931 1932 /** 1933 * Get the day of year property which provides access to advanced functionality. 1934 * 1935 * @return the day of year property 1936 */ 1937 public Property dayOfYear() { 1938 return new Property(this, getChronology().dayOfYear()); 1939 } 1940 1941 /** 1942 * Get the day of month property which provides access to advanced functionality. 1943 * 1944 * @return the day of month property 1945 */ 1946 public Property dayOfMonth() { 1947 return new Property(this, getChronology().dayOfMonth()); 1948 } 1949 1950 /** 1951 * Get the day of week property which provides access to advanced functionality. 1952 * 1953 * @return the day of week property 1954 */ 1955 public Property dayOfWeek() { 1956 return new Property(this, getChronology().dayOfWeek()); 1957 } 1958 1959 //----------------------------------------------------------------------- 1960 /** 1961 * Get the hour of day field property which provides access to advanced functionality. 1962 * 1963 * @return the hour of day property 1964 */ 1965 public Property hourOfDay() { 1966 return new Property(this, getChronology().hourOfDay()); 1967 } 1968 1969 /** 1970 * Get the minute of hour field property which provides access to advanced functionality. 1971 * 1972 * @return the minute of hour property 1973 */ 1974 public Property minuteOfHour() { 1975 return new Property(this, getChronology().minuteOfHour()); 1976 } 1977 1978 /** 1979 * Get the second of minute field property which provides access to advanced functionality. 1980 * 1981 * @return the second of minute property 1982 */ 1983 public Property secondOfMinute() { 1984 return new Property(this, getChronology().secondOfMinute()); 1985 } 1986 1987 /** 1988 * Get the millis of second property which provides access to advanced functionality. 1989 * 1990 * @return the millis of second property 1991 */ 1992 public Property millisOfSecond() { 1993 return new Property(this, getChronology().millisOfSecond()); 1994 } 1995 1996 /** 1997 * Get the millis of day property which provides access to advanced functionality. 1998 * 1999 * @return the millis of day property 2000 */ 2001 public Property millisOfDay() { 2002 return new Property(this, getChronology().millisOfDay()); 2003 } 2004 2005 //----------------------------------------------------------------------- 2006 /** 2007 * Output the date time in ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSS). 2008 * 2009 * @return ISO8601 time formatted string. 2010 */ 2011 @ToString 2012 public String toString() { 2013 return ISODateTimeFormat.dateTime().print(this); 2014 } 2015 2016 /** 2017 * Output the date using the specified format pattern. 2018 * 2019 * @param pattern the pattern specification, null means use <code>toString</code> 2020 * @see org.joda.time.format.DateTimeFormat 2021 */ 2022 public String toString(String pattern) { 2023 if (pattern == null) { 2024 return toString(); 2025 } 2026 return DateTimeFormat.forPattern(pattern).print(this); 2027 } 2028 2029 /** 2030 * Output the date using the specified format pattern. 2031 * 2032 * @param pattern the pattern specification, null means use <code>toString</code> 2033 * @param locale Locale to use, null means default 2034 * @see org.joda.time.format.DateTimeFormat 2035 */ 2036 public String toString(String pattern, Locale locale) throws IllegalArgumentException { 2037 if (pattern == null) { 2038 return toString(); 2039 } 2040 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this); 2041 } 2042 2043 //----------------------------------------------------------------------- 2044 /** 2045 * LocalDateTime.Property binds a LocalDateTime to a DateTimeField allowing 2046 * powerful datetime functionality to be easily accessed. 2047 * <p> 2048 * The simplest use of this class is as an alternative get method, here used to 2049 * get the year '1972' (as an int) and the month 'December' (as a String). 2050 * <pre> 2051 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2052 * int year = dt.year().get(); 2053 * String monthStr = dt.month().getAsText(); 2054 * </pre> 2055 * <p> 2056 * Methods are also provided that allow date modification. These return 2057 * new instances of LocalDateTime - they do not modify the original. 2058 * The example below yields two independent immutable date objects 2059 * 20 years apart. 2060 * <pre> 2061 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2062 * LocalDateTime dt1920 = dt.year().setCopy(1920); 2063 * </pre> 2064 * <p> 2065 * LocalDateTime.Property itself is thread-safe and immutable, as well as the 2066 * LocalDateTime being operated on. 2067 * 2068 * @author Stephen Colebourne 2069 * @author Brian S O'Neill 2070 * @since 1.3 2071 */ 2072 public static final class Property extends AbstractReadableInstantFieldProperty { 2073 2074 /** Serialization version */ 2075 private static final long serialVersionUID = -358138762846288L; 2076 2077 /** The instant this property is working against */ 2078 private transient LocalDateTime iInstant; 2079 /** The field this property is working against */ 2080 private transient DateTimeField iField; 2081 2082 /** 2083 * Constructor. 2084 * 2085 * @param instant the instant to set 2086 * @param field the field to use 2087 */ 2088 Property(LocalDateTime instant, DateTimeField field) { 2089 super(); 2090 iInstant = instant; 2091 iField = field; 2092 } 2093 2094 /** 2095 * Writes the property in a safe serialization format. 2096 */ 2097 private void writeObject(ObjectOutputStream oos) throws IOException { 2098 oos.writeObject(iInstant); 2099 oos.writeObject(iField.getType()); 2100 } 2101 2102 /** 2103 * Reads the property from a safe serialization format. 2104 */ 2105 private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException { 2106 iInstant = (LocalDateTime) oos.readObject(); 2107 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 2108 iField = type.getField(iInstant.getChronology()); 2109 } 2110 2111 //----------------------------------------------------------------------- 2112 /** 2113 * Gets the field being used. 2114 * 2115 * @return the field 2116 */ 2117 public DateTimeField getField() { 2118 return iField; 2119 } 2120 2121 /** 2122 * Gets the milliseconds of the datetime that this property is linked to. 2123 * 2124 * @return the milliseconds 2125 */ 2126 protected long getMillis() { 2127 return iInstant.getLocalMillis(); 2128 } 2129 2130 /** 2131 * Gets the chronology of the datetime that this property is linked to. 2132 * 2133 * @return the chronology 2134 * @since 1.4 2135 */ 2136 protected Chronology getChronology() { 2137 return iInstant.getChronology(); 2138 } 2139 2140 /** 2141 * Gets the LocalDateTime object linked to this property. 2142 * 2143 * @return the linked LocalDateTime 2144 */ 2145 public LocalDateTime getLocalDateTime() { 2146 return iInstant; 2147 } 2148 2149 //----------------------------------------------------------------------- 2150 /** 2151 * Adds to this field in a copy of this LocalDateTime. 2152 * <p> 2153 * The LocalDateTime attached to this property is unchanged by this call. 2154 * 2155 * @param value the value to add to the field in the copy 2156 * @return a copy of the LocalDateTime with the field value changed 2157 * @throws IllegalArgumentException if the value isn't valid 2158 */ 2159 public LocalDateTime addToCopy(int value) { 2160 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2161 } 2162 2163 /** 2164 * Adds to this field in a copy of this LocalDateTime. 2165 * <p> 2166 * The LocalDateTime attached to this property is unchanged by this call. 2167 * 2168 * @param value the value to add to the field in the copy 2169 * @return a copy of the LocalDateTime with the field value changed 2170 * @throws IllegalArgumentException if the value isn't valid 2171 */ 2172 public LocalDateTime addToCopy(long value) { 2173 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2174 } 2175 2176 /** 2177 * Adds to this field, possibly wrapped, in a copy of this LocalDateTime. 2178 * A field wrapped operation only changes this field. 2179 * Thus 31st January addWrapField one day goes to the 1st January. 2180 * <p> 2181 * The LocalDateTime attached to this property is unchanged by this call. 2182 * 2183 * @param value the value to add to the field in the copy 2184 * @return a copy of the LocalDateTime with the field value changed 2185 * @throws IllegalArgumentException if the value isn't valid 2186 */ 2187 public LocalDateTime addWrapFieldToCopy(int value) { 2188 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value)); 2189 } 2190 2191 //----------------------------------------------------------------------- 2192 /** 2193 * Sets this field in a copy of the LocalDateTime. 2194 * <p> 2195 * The LocalDateTime attached to this property is unchanged by this call. 2196 * 2197 * @param value the value to set the field in the copy to 2198 * @return a copy of the LocalDateTime with the field value changed 2199 * @throws IllegalArgumentException if the value isn't valid 2200 */ 2201 public LocalDateTime setCopy(int value) { 2202 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value)); 2203 } 2204 2205 /** 2206 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2207 * <p> 2208 * The LocalDateTime attached to this property is unchanged by this call. 2209 * 2210 * @param text the text value to set 2211 * @param locale optional locale to use for selecting a text symbol 2212 * @return a copy of the LocalDateTime with the field value changed 2213 * @throws IllegalArgumentException if the text value isn't valid 2214 */ 2215 public LocalDateTime setCopy(String text, Locale locale) { 2216 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale)); 2217 } 2218 2219 /** 2220 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2221 * <p> 2222 * The LocalDateTime attached to this property is unchanged by this call. 2223 * 2224 * @param text the text value to set 2225 * @return a copy of the LocalDateTime with the field value changed 2226 * @throws IllegalArgumentException if the text value isn't valid 2227 */ 2228 public LocalDateTime setCopy(String text) { 2229 return setCopy(text, null); 2230 } 2231 2232 //----------------------------------------------------------------------- 2233 /** 2234 * Returns a new LocalDateTime with this field set to the maximum value 2235 * for this field. 2236 * <p> 2237 * This operation is useful for obtaining a LocalDateTime on the last day 2238 * of the month, as month lengths vary. 2239 * <pre> 2240 * LocalDateTime lastDayOfMonth = dt.dayOfMonth().withMaximumValue(); 2241 * </pre> 2242 * <p> 2243 * The LocalDateTime attached to this property is unchanged by this call. 2244 * 2245 * @return a copy of the LocalDateTime with this field set to its maximum 2246 */ 2247 public LocalDateTime withMaximumValue() { 2248 return setCopy(getMaximumValue()); 2249 } 2250 2251 /** 2252 * Returns a new LocalDateTime with this field set to the minimum value 2253 * for this field. 2254 * <p> 2255 * The LocalDateTime attached to this property is unchanged by this call. 2256 * 2257 * @return a copy of the LocalDateTime with this field set to its minimum 2258 */ 2259 public LocalDateTime withMinimumValue() { 2260 return setCopy(getMinimumValue()); 2261 } 2262 2263 //----------------------------------------------------------------------- 2264 /** 2265 * Rounds to the lowest whole unit of this field on a copy of this 2266 * LocalDateTime. 2267 * <p> 2268 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2269 * where the time is 10:30 would result in new LocalDateTime with the 2270 * time of 10:00. 2271 * 2272 * @return a copy of the LocalDateTime with the field value changed 2273 */ 2274 public LocalDateTime roundFloorCopy() { 2275 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis())); 2276 } 2277 2278 /** 2279 * Rounds to the highest whole unit of this field on a copy of this 2280 * LocalDateTime. 2281 * <p> 2282 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2283 * where the time is 10:30 would result in new LocalDateTime with the 2284 * time of 11:00. 2285 * 2286 * @return a copy of the LocalDateTime with the field value changed 2287 */ 2288 public LocalDateTime roundCeilingCopy() { 2289 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis())); 2290 } 2291 2292 /** 2293 * Rounds to the nearest whole unit of this field on a copy of this 2294 * LocalDateTime, favoring the floor if halfway. 2295 * 2296 * @return a copy of the LocalDateTime with the field value changed 2297 */ 2298 public LocalDateTime roundHalfFloorCopy() { 2299 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis())); 2300 } 2301 2302 /** 2303 * Rounds to the nearest whole unit of this field on a copy of this 2304 * LocalDateTime, favoring the ceiling if halfway. 2305 * 2306 * @return a copy of the LocalDateTime with the field value changed 2307 */ 2308 public LocalDateTime roundHalfCeilingCopy() { 2309 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis())); 2310 } 2311 2312 /** 2313 * Rounds to the nearest whole unit of this field on a copy of this 2314 * LocalDateTime. If halfway, the ceiling is favored over the floor 2315 * only if it makes this field's value even. 2316 * 2317 * @return a copy of the LocalDateTime with the field value changed 2318 */ 2319 public LocalDateTime roundHalfEvenCopy() { 2320 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis())); 2321 } 2322 } 2323 2324 }