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.Serializable; 019 020 import org.joda.convert.FromString; 021 import org.joda.time.base.BasePeriod; 022 import org.joda.time.field.FieldUtils; 023 import org.joda.time.format.ISOPeriodFormat; 024 import org.joda.time.format.PeriodFormatter; 025 026 /** 027 * Standard mutable time period implementation. 028 * <p> 029 * A time period is divided into a number of fields, such as hours and seconds. 030 * Which fields are supported is defined by the PeriodType class. 031 * The default is the standard period type, which supports years, months, weeks, days, 032 * hours, minutes, seconds and millis. 033 * <p> 034 * When this time period is added to an instant, the effect is of adding each field in turn. 035 * As a result, this takes into account daylight savings time. 036 * Adding a time period of 1 day to the day before daylight savings starts will only add 037 * 23 hours rather than 24 to ensure that the time remains the same. 038 * If this is not the behaviour you want, then see {@link Duration}. 039 * <p> 040 * The definition of a period also affects the equals method. A period of 1 041 * day is not equal to a period of 24 hours, nor 1 hour equal to 60 minutes. 042 * This is because periods represent an abstracted definition of a time period 043 * (eg. a day may not actually be 24 hours, it might be 23 or 25 at daylight 044 * savings boundary). To compare the actual duration of two periods, convert 045 * both to durations using toDuration, an operation that emphasises that the 046 * result may differ according to the date you choose. 047 * <p> 048 * MutablePeriod is mutable and not thread-safe, unless concurrent threads 049 * are not invoking mutator methods. 050 * 051 * @author Brian S O'Neill 052 * @author Stephen Colebourne 053 * @since 1.0 054 * @see Period 055 */ 056 public class MutablePeriod 057 extends BasePeriod 058 implements ReadWritablePeriod, Cloneable, Serializable { 059 060 /** Serialization version */ 061 private static final long serialVersionUID = 3436451121567212165L; 062 063 //----------------------------------------------------------------------- 064 /** 065 * Parses a {@code MutablePeriod} from the specified string. 066 * <p> 067 * This uses {@link ISOPeriodFormat#standard()}. 068 * 069 * @param str the string to parse, not null 070 * @since 2.0 071 */ 072 @FromString 073 public static MutablePeriod parse(String str) { 074 return parse(str, ISOPeriodFormat.standard()); 075 } 076 077 /** 078 * Parses a {@code MutablePeriod} from the specified string using a formatter. 079 * 080 * @param str the string to parse, not null 081 * @param formatter the formatter to use, not null 082 * @since 2.0 083 */ 084 public static MutablePeriod parse(String str, PeriodFormatter formatter) { 085 return formatter.parsePeriod(str).toMutablePeriod(); 086 } 087 088 //----------------------------------------------------------------------- 089 /** 090 * Creates a zero-length period using the standard period type. 091 */ 092 public MutablePeriod() { 093 super(0L, null, null); 094 } 095 096 /** 097 * Creates a zero-length period using the specified period type. 098 * 099 * @param type which set of fields this period supports 100 */ 101 public MutablePeriod(PeriodType type) { 102 super(0L, type, null); 103 } 104 105 /** 106 * Create a period from a set of field values using the standard set of fields. 107 * 108 * @param hours amount of hours in this period 109 * @param minutes amount of minutes in this period 110 * @param seconds amount of seconds in this period 111 * @param millis amount of milliseconds in this period 112 */ 113 public MutablePeriod(int hours, int minutes, int seconds, int millis) { 114 super(0, 0, 0, 0, hours, minutes, seconds, millis, PeriodType.standard()); 115 } 116 117 /** 118 * Create a period from a set of field values using the standard set of fields. 119 * 120 * @param years amount of years in this period 121 * @param months amount of months in this period 122 * @param weeks amount of weeks in this period 123 * @param days amount of days in this period 124 * @param hours amount of hours in this period 125 * @param minutes amount of minutes in this period 126 * @param seconds amount of seconds in this period 127 * @param millis amount of milliseconds in this period 128 */ 129 public MutablePeriod(int years, int months, int weeks, int days, 130 int hours, int minutes, int seconds, int millis) { 131 super(years, months, weeks, days, hours, minutes, seconds, millis, PeriodType.standard()); 132 } 133 134 /** 135 * Create a period from a set of field values. 136 * 137 * @param years amount of years in this period, which must be zero if unsupported 138 * @param months amount of months in this period, which must be zero if unsupported 139 * @param weeks amount of weeks in this period, which must be zero if unsupported 140 * @param days amount of days in this period, which must be zero if unsupported 141 * @param hours amount of hours in this period, which must be zero if unsupported 142 * @param minutes amount of minutes in this period, which must be zero if unsupported 143 * @param seconds amount of seconds in this period, which must be zero if unsupported 144 * @param millis amount of milliseconds in this period, which must be zero if unsupported 145 * @param type which set of fields this period supports, null means AllType 146 * @throws IllegalArgumentException if an unsupported field's value is non-zero 147 */ 148 public MutablePeriod(int years, int months, int weeks, int days, 149 int hours, int minutes, int seconds, int millis, PeriodType type) { 150 super(years, months, weeks, days, hours, minutes, seconds, millis, type); 151 } 152 153 /** 154 * Creates a period from the given millisecond duration using the standard 155 * set of fields. 156 * <p> 157 * Only precise fields in the period type will be used. 158 * For the standard period type this is the time fields only. 159 * Thus the year, month, week and day fields will not be populated. 160 * <p> 161 * If the duration is small, less than one day, then this method will perform 162 * as you might expect and split the fields evenly. 163 * <p> 164 * If the duration is larger than one day then all the remaining duration will 165 * be stored in the largest available precise field, hours in this case. 166 * <p> 167 * For example, a duration equal to (365 + 60 + 5) days will be converted to 168 * ((365 + 60 + 5) * 24) hours by this constructor. 169 * <p> 170 * For more control over the conversion process, you have two options: 171 * <ul> 172 * <li>convert the duration to an {@link Interval}, and from there obtain the period 173 * <li>specify a period type that contains precise definitions of the day and larger 174 * fields, such as the UTC or precise types. 175 * </ul> 176 * 177 * @param duration the duration, in milliseconds 178 */ 179 public MutablePeriod(long duration) { 180 super(duration); 181 } 182 183 /** 184 * Creates a period from the given millisecond duration. 185 * <p> 186 * Only precise fields in the period type will be used. 187 * Imprecise fields will not be populated. 188 * <p> 189 * If the duration is small then this method will perform 190 * as you might expect and split the fields evenly. 191 * <p> 192 * If the duration is large then all the remaining duration will 193 * be stored in the largest available precise field. 194 * For details as to which fields are precise, review the period type javadoc. 195 * 196 * @param duration the duration, in milliseconds 197 * @param type which set of fields this period supports, null means standard 198 */ 199 public MutablePeriod(long duration, PeriodType type) { 200 super(duration, type, null); 201 } 202 203 /** 204 * Creates a period from the given millisecond duration using the standard 205 * set of fields. 206 * <p> 207 * Only precise fields in the period type will be used. 208 * Imprecise fields will not be populated. 209 * <p> 210 * If the duration is small then this method will perform 211 * as you might expect and split the fields evenly. 212 * <p> 213 * If the duration is large then all the remaining duration will 214 * be stored in the largest available precise field. 215 * For details as to which fields are precise, review the period type javadoc. 216 * 217 * @param duration the duration, in milliseconds 218 * @param chronology the chronology to use to split the duration, null means ISO default 219 */ 220 public MutablePeriod(long duration, Chronology chronology) { 221 super(duration, null, chronology); 222 } 223 224 /** 225 * Creates a period from the given millisecond duration. 226 * <p> 227 * Only precise fields in the period type will be used. 228 * Imprecise fields will not be populated. 229 * <p> 230 * If the duration is small then this method will perform 231 * as you might expect and split the fields evenly. 232 * <p> 233 * If the duration is large then all the remaining duration will 234 * be stored in the largest available precise field. 235 * For details as to which fields are precise, review the period type javadoc. 236 * 237 * @param duration the duration, in milliseconds 238 * @param type which set of fields this period supports, null means standard 239 * @param chronology the chronology to use to split the duration, null means ISO default 240 */ 241 public MutablePeriod(long duration, PeriodType type, Chronology chronology) { 242 super(duration, type, chronology); 243 } 244 245 /** 246 * Creates a period from the given interval endpoints using the standard 247 * set of fields. 248 * 249 * @param startInstant interval start, in milliseconds 250 * @param endInstant interval end, in milliseconds 251 */ 252 public MutablePeriod(long startInstant, long endInstant) { 253 super(startInstant, endInstant, null, null); 254 } 255 256 /** 257 * Creates a period from the given interval endpoints. 258 * 259 * @param startInstant interval start, in milliseconds 260 * @param endInstant interval end, in milliseconds 261 * @param type which set of fields this period supports, null means standard 262 */ 263 public MutablePeriod(long startInstant, long endInstant, PeriodType type) { 264 super(startInstant, endInstant, type, null); 265 } 266 267 /** 268 * Creates a period from the given interval endpoints using the standard 269 * set of fields. 270 * 271 * @param startInstant interval start, in milliseconds 272 * @param endInstant interval end, in milliseconds 273 * @param chrono the chronology to use, null means ISO in default zone 274 */ 275 public MutablePeriod(long startInstant, long endInstant, Chronology chrono) { 276 super(startInstant, endInstant, null, chrono); 277 } 278 279 /** 280 * Creates a period from the given interval endpoints. 281 * 282 * @param startInstant interval start, in milliseconds 283 * @param endInstant interval end, in milliseconds 284 * @param type which set of fields this period supports, null means standard 285 * @param chrono the chronology to use, null means ISO in default zone 286 */ 287 public MutablePeriod(long startInstant, long endInstant, PeriodType type, Chronology chrono) { 288 super(startInstant, endInstant, type, chrono); 289 } 290 291 /** 292 * Creates a period from the given interval endpoints using the standard 293 * set of fields. 294 * <p> 295 * The chronology of the start instant is used, unless that is null when the 296 * chronology of the end instant is used instead. 297 * 298 * @param startInstant interval start, null means now 299 * @param endInstant interval end, null means now 300 */ 301 public MutablePeriod(ReadableInstant startInstant, ReadableInstant endInstant) { 302 super(startInstant, endInstant, null); 303 } 304 305 /** 306 * Creates a period from the given interval endpoints. 307 * <p> 308 * The chronology of the start instant is used, unless that is null when the 309 * chronology of the end instant is used instead. 310 * 311 * @param startInstant interval start, null means now 312 * @param endInstant interval end, null means now 313 * @param type which set of fields this period supports, null means AllType 314 */ 315 public MutablePeriod(ReadableInstant startInstant, ReadableInstant endInstant, PeriodType type) { 316 super(startInstant, endInstant, type); 317 } 318 319 /** 320 * Creates a period from the given start point and the duration. 321 * 322 * @param startInstant the interval start, null means now 323 * @param duration the duration of the interval, null means zero-length 324 */ 325 public MutablePeriod(ReadableInstant startInstant, ReadableDuration duration) { 326 super(startInstant, duration, null); 327 } 328 329 /** 330 * Creates a period from the given start point and the duration. 331 * 332 * @param startInstant the interval start, null means now 333 * @param duration the duration of the interval, null means zero-length 334 * @param type which set of fields this period supports, null means standard 335 */ 336 public MutablePeriod(ReadableInstant startInstant, ReadableDuration duration, PeriodType type) { 337 super(startInstant, duration, type); 338 } 339 340 /** 341 * Creates a period from the given duration and end point. 342 * 343 * @param duration the duration of the interval, null means zero-length 344 * @param endInstant the interval end, null means now 345 */ 346 public MutablePeriod(ReadableDuration duration, ReadableInstant endInstant) { 347 super(duration, endInstant, null); 348 } 349 350 /** 351 * Creates a period from the given duration and end point. 352 * 353 * @param duration the duration of the interval, null means zero-length 354 * @param endInstant the interval end, null means now 355 * @param type which set of fields this period supports, null means standard 356 */ 357 public MutablePeriod(ReadableDuration duration, ReadableInstant endInstant, PeriodType type) { 358 super(duration, endInstant, type); 359 } 360 361 /** 362 * Creates a period by converting or copying from another object. 363 * <p> 364 * The recognised object types are defined in 365 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 366 * include ReadablePeriod, ReadableInterval and String. 367 * The String formats are described by {@link ISOPeriodFormat#standard()}. 368 * 369 * @param period period to convert 370 * @throws IllegalArgumentException if period is invalid 371 * @throws UnsupportedOperationException if an unsupported field's value is non-zero 372 */ 373 public MutablePeriod(Object period) { 374 super(period, null, null); 375 } 376 377 /** 378 * Creates a period by converting or copying from another object. 379 * <p> 380 * The recognised object types are defined in 381 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 382 * include ReadablePeriod, ReadableInterval and String. 383 * The String formats are described by {@link ISOPeriodFormat#standard()}. 384 * 385 * @param period period to convert 386 * @param type which set of fields this period supports, null means use converter 387 * @throws IllegalArgumentException if period is invalid 388 * @throws UnsupportedOperationException if an unsupported field's value is non-zero 389 */ 390 public MutablePeriod(Object period, PeriodType type) { 391 super(period, type, null); 392 } 393 394 /** 395 * Creates a period by converting or copying from another object. 396 * <p> 397 * The recognised object types are defined in 398 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 399 * include ReadablePeriod, ReadableInterval and String. 400 * The String formats are described by {@link ISOPeriodFormat#standard()}. 401 * 402 * @param period period to convert 403 * @param chrono the chronology to use, null means ISO in default zone 404 * @throws IllegalArgumentException if period is invalid 405 * @throws UnsupportedOperationException if an unsupported field's value is non-zero 406 */ 407 public MutablePeriod(Object period, Chronology chrono) { 408 super(period, null, chrono); 409 } 410 411 /** 412 * Creates a period by converting or copying from another object. 413 * <p> 414 * The recognised object types are defined in 415 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 416 * include ReadablePeriod, ReadableInterval and String. 417 * The String formats are described by {@link ISOPeriodFormat#standard()}. 418 * 419 * @param period period to convert 420 * @param type which set of fields this period supports, null means use converter 421 * @param chrono the chronology to use, null means ISO in default zone 422 * @throws IllegalArgumentException if period is invalid 423 * @throws UnsupportedOperationException if an unsupported field's value is non-zero 424 */ 425 public MutablePeriod(Object period, PeriodType type, Chronology chrono) { 426 super(period, type, chrono); 427 } 428 429 //----------------------------------------------------------------------- 430 /** 431 * Clears the period, setting all values back to zero. 432 */ 433 public void clear() { 434 super.setValues(new int[size()]); 435 } 436 437 /** 438 * Sets the value of one of the fields by index. 439 * 440 * @param index the field index 441 * @param value the new value for the field 442 * @throws IndexOutOfBoundsException if the index is invalid 443 */ 444 public void setValue(int index, int value) { 445 super.setValue(index, value); 446 } 447 448 /** 449 * Sets the value of one of the fields. 450 * <p> 451 * The field type specified must be one of those that is supported by the period. 452 * 453 * @param field a DurationFieldType instance that is supported by this period, not null 454 * @param value the new value for the field 455 * @throws IllegalArgumentException if the field is null or not supported 456 */ 457 public void set(DurationFieldType field, int value) { 458 super.setField(field, value); 459 } 460 461 /** 462 * Sets all the fields in one go from another ReadablePeriod. 463 * 464 * @param period the period to set, null means zero length period 465 * @throws IllegalArgumentException if an unsupported field's value is non-zero 466 */ 467 public void setPeriod(ReadablePeriod period) { 468 super.setPeriod(period); 469 } 470 471 /** 472 * Sets all the fields in one go. 473 * 474 * @param years amount of years in this period, which must be zero if unsupported 475 * @param months amount of months in this period, which must be zero if unsupported 476 * @param weeks amount of weeks in this period, which must be zero if unsupported 477 * @param days amount of days in this period, which must be zero if unsupported 478 * @param hours amount of hours in this period, which must be zero if unsupported 479 * @param minutes amount of minutes in this period, which must be zero if unsupported 480 * @param seconds amount of seconds in this period, which must be zero if unsupported 481 * @param millis amount of milliseconds in this period, which must be zero if unsupported 482 * @throws IllegalArgumentException if an unsupported field's value is non-zero 483 */ 484 public void setPeriod(int years, int months, int weeks, int days, 485 int hours, int minutes, int seconds, int millis) { 486 super.setPeriod(years, months, weeks, days, hours, minutes, seconds, millis); 487 } 488 489 /** 490 * Sets all the fields in one go from an interval using the ISO chronology 491 * and dividing the fields using the period type. 492 * 493 * @param interval the interval to set, null means zero length 494 * @throws ArithmeticException if the set exceeds the capacity of the period 495 */ 496 public void setPeriod(ReadableInterval interval) { 497 if (interval == null) { 498 setPeriod(0L); 499 } else { 500 Chronology chrono = DateTimeUtils.getChronology(interval.getChronology()); 501 setPeriod(interval.getStartMillis(), interval.getEndMillis(), chrono); 502 } 503 } 504 505 /** 506 * Sets all the fields in one go from two instants representing an interval. 507 * <p> 508 * The chronology of the start instant is used, unless that is null when the 509 * chronology of the end instant is used instead. 510 * 511 * @param start the start instant, null means now 512 * @param end the end instant, null means now 513 * @throws ArithmeticException if the set exceeds the capacity of the period 514 */ 515 public void setPeriod(ReadableInstant start, ReadableInstant end) { 516 if (start == end) { 517 setPeriod(0L); 518 } else { 519 long startMillis = DateTimeUtils.getInstantMillis(start); 520 long endMillis = DateTimeUtils.getInstantMillis(end); 521 Chronology chrono = DateTimeUtils.getIntervalChronology(start, end); 522 setPeriod(startMillis, endMillis, chrono); 523 } 524 } 525 526 /** 527 * Sets all the fields in one go from a millisecond interval using ISOChronology 528 * and dividing the fields using the period type. 529 * 530 * @param startInstant interval start, in milliseconds 531 * @param endInstant interval end, in milliseconds 532 * @throws ArithmeticException if the set exceeds the capacity of the period 533 */ 534 public void setPeriod(long startInstant, long endInstant) { 535 setPeriod(startInstant, endInstant, null); 536 } 537 538 /** 539 * Sets all the fields in one go from a millisecond interval. 540 * 541 * @param startInstant interval start, in milliseconds 542 * @param endInstant interval end, in milliseconds 543 * @param chrono the chronology to use, null means ISO chronology 544 * @throws ArithmeticException if the set exceeds the capacity of the period 545 */ 546 public void setPeriod(long startInstant, long endInstant, Chronology chrono) { 547 chrono = DateTimeUtils.getChronology(chrono); 548 setValues(chrono.get(this, startInstant, endInstant)); 549 } 550 551 /** 552 * Sets all the fields in one go from a duration dividing the 553 * fields using the period type. 554 * <p> 555 * When dividing the duration, only precise fields in the period type will be used. 556 * For large durations, all the remaining duration will be stored in the largest 557 * available precise field. 558 * 559 * @param duration the duration to set, null means zero length 560 * @throws ArithmeticException if the set exceeds the capacity of the period 561 */ 562 public void setPeriod(ReadableDuration duration) { 563 setPeriod(duration, null); 564 } 565 566 /** 567 * Sets all the fields in one go from a duration dividing the 568 * fields using the period type. 569 * <p> 570 * When dividing the duration, only precise fields in the period type will be used. 571 * For large durations, all the remaining duration will be stored in the largest 572 * available precise field. 573 * 574 * @param duration the duration to set, null means zero length 575 * @param chrono the chronology to use, null means ISO default 576 * @throws ArithmeticException if the set exceeds the capacity of the period 577 */ 578 public void setPeriod(ReadableDuration duration, Chronology chrono) { 579 long durationMillis = DateTimeUtils.getDurationMillis(duration); 580 setPeriod(durationMillis, chrono); 581 } 582 583 /** 584 * Sets all the fields in one go from a millisecond duration dividing the 585 * fields using the period type. 586 * <p> 587 * When dividing the duration, only precise fields in the period type will be used. 588 * For large durations, all the remaining duration will be stored in the largest 589 * available precise field. 590 * 591 * @param duration the duration, in milliseconds 592 * @throws ArithmeticException if the set exceeds the capacity of the period 593 */ 594 public void setPeriod(long duration) { 595 setPeriod(duration, null); 596 } 597 598 /** 599 * Sets all the fields in one go from a millisecond duration. 600 * <p> 601 * When dividing the duration, only precise fields in the period type will be used. 602 * For large durations, all the remaining duration will be stored in the largest 603 * available precise field. 604 * 605 * @param duration the duration, in milliseconds 606 * @param chrono the chronology to use, null means ISO chronology 607 * @throws ArithmeticException if the set exceeds the capacity of the period 608 */ 609 public void setPeriod(long duration, Chronology chrono) { 610 chrono = DateTimeUtils.getChronology(chrono); 611 setValues(chrono.get(this, duration)); 612 } 613 614 //----------------------------------------------------------------------- 615 /** 616 * Adds to the value of one of the fields. 617 * <p> 618 * The field type specified must be one of those that is supported by the period. 619 * 620 * @param field a DurationFieldType instance that is supported by this period, not null 621 * @param value the value to add to the field 622 * @throws IllegalArgumentException if the field is null or not supported 623 */ 624 public void add(DurationFieldType field, int value) { 625 super.addField(field, value); 626 } 627 628 /** 629 * Adds a period to this one by adding each field in turn. 630 * 631 * @param period the period to add, null means add nothing 632 * @throws IllegalArgumentException if the period being added contains a field 633 * not supported by this period 634 * @throws ArithmeticException if the addition exceeds the capacity of the period 635 */ 636 public void add(ReadablePeriod period) { 637 super.addPeriod(period); 638 } 639 640 /** 641 * Adds to each field of this period. 642 * 643 * @param years amount of years to add to this period, which must be zero if unsupported 644 * @param months amount of months to add to this period, which must be zero if unsupported 645 * @param weeks amount of weeks to add to this period, which must be zero if unsupported 646 * @param days amount of days to add to this period, which must be zero if unsupported 647 * @param hours amount of hours to add to this period, which must be zero if unsupported 648 * @param minutes amount of minutes to add to this period, which must be zero if unsupported 649 * @param seconds amount of seconds to add to this period, which must be zero if unsupported 650 * @param millis amount of milliseconds to add to this period, which must be zero if unsupported 651 * @throws IllegalArgumentException if the period being added contains a field 652 * not supported by this period 653 * @throws ArithmeticException if the addition exceeds the capacity of the period 654 */ 655 public void add(int years, int months, int weeks, int days, 656 int hours, int minutes, int seconds, int millis) { 657 setPeriod( 658 FieldUtils.safeAdd(getYears(), years), 659 FieldUtils.safeAdd(getMonths(), months), 660 FieldUtils.safeAdd(getWeeks(), weeks), 661 FieldUtils.safeAdd(getDays(), days), 662 FieldUtils.safeAdd(getHours(), hours), 663 FieldUtils.safeAdd(getMinutes(), minutes), 664 FieldUtils.safeAdd(getSeconds(), seconds), 665 FieldUtils.safeAdd(getMillis(), millis) 666 ); 667 } 668 669 /** 670 * Adds an interval to this one by dividing the interval into 671 * fields and calling {@link #add(ReadablePeriod)}. 672 * 673 * @param interval the interval to add, null means add nothing 674 * @throws ArithmeticException if the addition exceeds the capacity of the period 675 */ 676 public void add(ReadableInterval interval) { 677 if (interval != null) { 678 add(interval.toPeriod(getPeriodType())); 679 } 680 } 681 682 /** 683 * Adds a duration to this one by dividing the duration into 684 * fields and calling {@link #add(ReadablePeriod)}. 685 * 686 * @param duration the duration to add, null means add nothing 687 * @throws ArithmeticException if the addition exceeds the capacity of the period 688 */ 689 public void add(ReadableDuration duration) { 690 if (duration != null) { 691 add(new Period(duration.getMillis(), getPeriodType())); 692 } 693 } 694 695 /** 696 * Adds a millisecond duration to this one by dividing the duration into 697 * fields and calling {@link #add(ReadablePeriod)}. 698 * <p> 699 * When dividing the duration, only precise fields in the period type will be used. 700 * For large durations, all the remaining duration will be stored in the largest 701 * available precise field. 702 * 703 * @param duration the duration, in milliseconds 704 * @throws ArithmeticException if the addition exceeds the capacity of the period 705 */ 706 public void add(long duration) { 707 add(new Period(duration, getPeriodType())); 708 } 709 710 /** 711 * Adds a millisecond duration to this one by dividing the duration into 712 * fields and calling {@link #add(ReadablePeriod)}. 713 * <p> 714 * When dividing the duration, only precise fields in the period type will be used. 715 * For large durations, all the remaining duration will be stored in the largest 716 * available precise field. 717 * 718 * @param duration the duration, in milliseconds 719 * @param chrono the chronology to use, null means ISO default 720 * @throws ArithmeticException if the addition exceeds the capacity of the period 721 */ 722 public void add(long duration, Chronology chrono) { 723 add(new Period(duration, getPeriodType(), chrono)); 724 } 725 726 //----------------------------------------------------------------------- 727 /** 728 * Merges all the fields from the specified period into this one. 729 * <p> 730 * Fields that are not present in the specified period are left unaltered. 731 * 732 * @param period the period to set, null ignored 733 * @throws IllegalArgumentException if an unsupported field's value is non-zero 734 */ 735 public void mergePeriod(ReadablePeriod period) { 736 super.mergePeriod(period); 737 } 738 739 //----------------------------------------------------------------------- 740 /** 741 * Gets the years field part of the period. 742 * 743 * @return the number of years in the period, zero if unsupported 744 */ 745 public int getYears() { 746 return getPeriodType().getIndexedField(this, PeriodType.YEAR_INDEX); 747 } 748 749 /** 750 * Gets the months field part of the period. 751 * 752 * @return the number of months in the period, zero if unsupported 753 */ 754 public int getMonths() { 755 return getPeriodType().getIndexedField(this, PeriodType.MONTH_INDEX); 756 } 757 758 /** 759 * Gets the weeks field part of the period. 760 * 761 * @return the number of weeks in the period, zero if unsupported 762 */ 763 public int getWeeks() { 764 return getPeriodType().getIndexedField(this, PeriodType.WEEK_INDEX); 765 } 766 767 /** 768 * Gets the days field part of the period. 769 * 770 * @return the number of days in the period, zero if unsupported 771 */ 772 public int getDays() { 773 return getPeriodType().getIndexedField(this, PeriodType.DAY_INDEX); 774 } 775 776 //----------------------------------------------------------------------- 777 /** 778 * Gets the hours field part of the period. 779 * 780 * @return the number of hours in the period, zero if unsupported 781 */ 782 public int getHours() { 783 return getPeriodType().getIndexedField(this, PeriodType.HOUR_INDEX); 784 } 785 786 /** 787 * Gets the minutes field part of the period. 788 * 789 * @return the number of minutes in the period, zero if unsupported 790 */ 791 public int getMinutes() { 792 return getPeriodType().getIndexedField(this, PeriodType.MINUTE_INDEX); 793 } 794 795 /** 796 * Gets the seconds field part of the period. 797 * 798 * @return the number of seconds in the period, zero if unsupported 799 */ 800 public int getSeconds() { 801 return getPeriodType().getIndexedField(this, PeriodType.SECOND_INDEX); 802 } 803 804 /** 805 * Gets the millis field part of the period. 806 * 807 * @return the number of millis in the period, zero if unsupported 808 */ 809 public int getMillis() { 810 return getPeriodType().getIndexedField(this, PeriodType.MILLI_INDEX); 811 } 812 813 //----------------------------------------------------------------------- 814 /** 815 * Sets the number of years of the period. 816 * 817 * @param years the number of years 818 * @throws IllegalArgumentException if field is not supported and the value is non-zero 819 */ 820 public void setYears(int years) { 821 super.setField(DurationFieldType.years(), years); 822 } 823 824 /** 825 * Adds the specified years to the number of years in the period. 826 * 827 * @param years the number of years 828 * @throws IllegalArgumentException if field is not supported and the value is non-zero 829 * @throws ArithmeticException if the addition exceeds the capacity of the period 830 */ 831 public void addYears(int years) { 832 super.addField(DurationFieldType.years(), years); 833 } 834 835 //----------------------------------------------------------------------- 836 /** 837 * Sets the number of months of the period. 838 * 839 * @param months the number of months 840 * @throws IllegalArgumentException if field is not supported and the value is non-zero 841 */ 842 public void setMonths(int months) { 843 super.setField(DurationFieldType.months(), months); 844 } 845 846 /** 847 * Adds the specified months to the number of months in the period. 848 * 849 * @param months the number of months 850 * @throws IllegalArgumentException if field is not supported and the value is non-zero 851 * @throws ArithmeticException if the addition exceeds the capacity of the period 852 */ 853 public void addMonths(int months) { 854 super.addField(DurationFieldType.months(), months); 855 } 856 857 //----------------------------------------------------------------------- 858 /** 859 * Sets the number of weeks of the period. 860 * 861 * @param weeks the number of weeks 862 * @throws IllegalArgumentException if field is not supported and the value is non-zero 863 */ 864 public void setWeeks(int weeks) { 865 super.setField(DurationFieldType.weeks(), weeks); 866 } 867 868 /** 869 * Adds the specified weeks to the number of weeks in the period. 870 * 871 * @param weeks the number of weeks 872 * @throws IllegalArgumentException if field is not supported and the value is non-zero 873 * @throws ArithmeticException if the addition exceeds the capacity of the period 874 */ 875 public void addWeeks(int weeks) { 876 super.addField(DurationFieldType.weeks(), weeks); 877 } 878 879 //----------------------------------------------------------------------- 880 /** 881 * Sets the number of days of the period. 882 * 883 * @param days the number of days 884 * @throws IllegalArgumentException if field is not supported and the value is non-zero 885 */ 886 public void setDays(int days) { 887 super.setField(DurationFieldType.days(), days); 888 } 889 890 /** 891 * Adds the specified days to the number of days in the period. 892 * 893 * @param days the number of days 894 * @throws IllegalArgumentException if field is not supported and the value is non-zero 895 * @throws ArithmeticException if the addition exceeds the capacity of the period 896 */ 897 public void addDays(int days) { 898 super.addField(DurationFieldType.days(), days); 899 } 900 901 //----------------------------------------------------------------------- 902 /** 903 * Sets the number of hours of the period. 904 * 905 * @param hours the number of hours 906 * @throws IllegalArgumentException if field is not supported and the value is non-zero 907 */ 908 public void setHours(int hours) { 909 super.setField(DurationFieldType.hours(), hours); 910 } 911 912 /** 913 * Adds the specified hours to the number of hours in the period. 914 * 915 * @param hours the number of hours 916 * @throws IllegalArgumentException if field is not supported and the value is non-zero 917 * @throws ArithmeticException if the addition exceeds the capacity of the period 918 */ 919 public void addHours(int hours) { 920 super.addField(DurationFieldType.hours(), hours); 921 } 922 923 //----------------------------------------------------------------------- 924 /** 925 * Sets the number of minutes of the period. 926 * 927 * @param minutes the number of minutes 928 * @throws IllegalArgumentException if field is not supported and the value is non-zero 929 */ 930 public void setMinutes(int minutes) { 931 super.setField(DurationFieldType.minutes(), minutes); 932 } 933 934 /** 935 * Adds the specified minutes to the number of minutes in the period. 936 * 937 * @param minutes the number of minutes 938 * @throws IllegalArgumentException if field is not supported and the value is non-zero 939 * @throws ArithmeticException if the addition exceeds the capacity of the period 940 */ 941 public void addMinutes(int minutes) { 942 super.addField(DurationFieldType.minutes(), minutes); 943 } 944 945 //----------------------------------------------------------------------- 946 /** 947 * Sets the number of seconds of the period. 948 * 949 * @param seconds the number of seconds 950 * @throws IllegalArgumentException if field is not supported and the value is non-zero 951 */ 952 public void setSeconds(int seconds) { 953 super.setField(DurationFieldType.seconds(), seconds); 954 } 955 956 /** 957 * Adds the specified seconds to the number of seconds in the period. 958 * 959 * @param seconds the number of seconds 960 * @throws IllegalArgumentException if field is not supported and the value is non-zero 961 * @throws ArithmeticException if the addition exceeds the capacity of the period 962 */ 963 public void addSeconds(int seconds) { 964 super.addField(DurationFieldType.seconds(), seconds); 965 } 966 967 //----------------------------------------------------------------------- 968 /** 969 * Sets the number of millis of the period. 970 * 971 * @param millis the number of millis 972 * @throws IllegalArgumentException if field is not supported and the value is non-zero 973 */ 974 public void setMillis(int millis) { 975 super.setField(DurationFieldType.millis(), millis); 976 } 977 978 /** 979 * Adds the specified millis to the number of millis in the period. 980 * 981 * @param millis the number of millis 982 * @throws IllegalArgumentException if field is not supported and the value is non-zero 983 * @throws ArithmeticException if the addition exceeds the capacity of the period 984 */ 985 public void addMillis(int millis) { 986 super.addField(DurationFieldType.millis(), millis); 987 } 988 989 // Misc 990 //----------------------------------------------------------------------- 991 /** 992 * Clone this object without having to cast the returned object. 993 * 994 * @return a clone of the this object. 995 */ 996 public MutablePeriod copy() { 997 return (MutablePeriod) clone(); 998 } 999 1000 /** 1001 * Clone this object. 1002 * 1003 * @return a clone of this object. 1004 */ 1005 public Object clone() { 1006 try { 1007 return super.clone(); 1008 } catch (CloneNotSupportedException ex) { 1009 throw new InternalError("Clone error"); 1010 } 1011 } 1012 1013 }