1 16 package org.joda.time.base; 17 18 import java.io.Serializable ; 19 20 import org.joda.time.Chronology; 21 import org.joda.time.DateTimeUtils; 22 import org.joda.time.Duration; 23 import org.joda.time.DurationFieldType; 24 import org.joda.time.MutablePeriod; 25 import org.joda.time.PeriodType; 26 import org.joda.time.ReadWritablePeriod; 27 import org.joda.time.ReadableDuration; 28 import org.joda.time.ReadableInstant; 29 import org.joda.time.ReadablePartial; 30 import org.joda.time.ReadablePeriod; 31 import org.joda.time.convert.ConverterManager; 32 import org.joda.time.convert.PeriodConverter; 33 import org.joda.time.field.FieldUtils; 34 35 49 public abstract class BasePeriod 50 extends AbstractPeriod 51 implements ReadablePeriod, Serializable { 52 53 54 private static final long serialVersionUID = -2110953284060001145L; 55 56 57 private PeriodType iType; 58 59 private int[] iValues; 60 61 77 protected BasePeriod(int years, int months, int weeks, int days, 78 int hours, int minutes, int seconds, int millis, 79 PeriodType type) { 80 super(); 81 type = checkPeriodType(type); 82 iType = type; 83 setPeriodInternal(years, months, weeks, days, hours, minutes, seconds, millis); } 85 86 95 protected BasePeriod(long startInstant, long endInstant, PeriodType type, Chronology chrono) { 96 super(); 97 type = checkPeriodType(type); 98 chrono = DateTimeUtils.getChronology(chrono); 99 iType = type; 100 iValues = chrono.get(this, startInstant, endInstant); 101 } 102 103 111 protected BasePeriod(ReadableInstant startInstant, ReadableInstant endInstant, PeriodType type) { 112 super(); 113 type = checkPeriodType(type); 114 if (startInstant == null && endInstant == null) { 115 iType = type; 116 iValues = new int[size()]; 117 } else { 118 long startMillis = DateTimeUtils.getInstantMillis(startInstant); 119 long endMillis = DateTimeUtils.getInstantMillis(endInstant); 120 Chronology chrono = DateTimeUtils.getIntervalChronology(startInstant, endInstant); 121 chrono = DateTimeUtils.getChronology(chrono); 122 iType = type; 123 iValues = chrono.get(this, startMillis, endMillis); 124 } 125 } 126 127 145 protected BasePeriod(ReadablePartial start, ReadablePartial end, PeriodType type) { 146 super(); 147 if (start == null || end == null) { 148 throw new IllegalArgumentException ("ReadablePartial objects must not be null"); 149 } 150 if (start.size() != end.size()) { 151 throw new IllegalArgumentException ("ReadablePartial objects must have the same set of fields"); 152 } 153 for (int i = 0, isize = start.size(); i < isize; i++) { 154 if (start.getFieldType(i) != end.getFieldType(i)) { 155 throw new IllegalArgumentException ("ReadablePartial objects must have the same set of fields"); 156 } 157 } 158 if (DateTimeUtils.isContiguous(start) == false) { 159 throw new IllegalArgumentException ("ReadablePartial objects must be contiguous"); 160 } 161 iType = checkPeriodType(type); 162 Chronology chrono = DateTimeUtils.getChronology(start.getChronology()).withUTC(); 163 iValues = chrono.get(this, chrono.set(start, 0L), chrono.set(end, 0L)); 164 } 165 166 173 protected BasePeriod(ReadableInstant startInstant, ReadableDuration duration, PeriodType type) { 174 super(); 175 type = checkPeriodType(type); 176 long startMillis = DateTimeUtils.getInstantMillis(startInstant); 177 long durationMillis = DateTimeUtils.getDurationMillis(duration); 178 long endMillis = FieldUtils.safeAdd(startMillis, durationMillis); 179 Chronology chrono = DateTimeUtils.getInstantChronology(startInstant); 180 iType = type; 181 iValues = chrono.get(this, startMillis, endMillis); 182 } 183 184 191 protected BasePeriod(ReadableDuration duration, ReadableInstant endInstant, PeriodType type) { 192 super(); 193 type = checkPeriodType(type); 194 long durationMillis = DateTimeUtils.getDurationMillis(duration); 195 long endMillis = DateTimeUtils.getInstantMillis(endInstant); 196 long startMillis = FieldUtils.safeSubtract(endMillis, durationMillis); 197 Chronology chrono = DateTimeUtils.getInstantChronology(endInstant); 198 iType = type; 199 iValues = chrono.get(this, startMillis, endMillis); 200 } 201 202 214 protected BasePeriod(long duration, PeriodType type, Chronology chrono) { 215 super(); 216 type = checkPeriodType(type); 217 chrono = DateTimeUtils.getChronology(chrono); 218 iType = type; 219 iValues = chrono.get(this, duration); 220 } 221 222 231 protected BasePeriod(Object period, PeriodType type, Chronology chrono) { 232 super(); 233 PeriodConverter converter = ConverterManager.getInstance().getPeriodConverter(period); 234 type = (type == null ? converter.getPeriodType(period) : type); 235 type = checkPeriodType(type); 236 iType = type; 237 if (this instanceof ReadWritablePeriod) { 238 iValues = new int[size()]; 239 chrono = DateTimeUtils.getChronology(chrono); 240 converter.setInto((ReadWritablePeriod) this, period, chrono); 241 } else { 242 iValues = new MutablePeriod(period, type, chrono).getValues(); 243 } 244 } 245 246 253 protected BasePeriod(int[] values, PeriodType type) { 254 super(); 255 iType = type; 256 iValues = values; 257 } 258 259 268 protected PeriodType checkPeriodType(PeriodType type) { 269 return DateTimeUtils.getPeriodType(type); 270 } 271 272 278 public PeriodType getPeriodType() { 279 return iType; 280 } 281 282 288 public int size() { 289 return iType.size(); 290 } 291 292 299 public DurationFieldType getFieldType(int index) { 300 return iType.getFieldType(index); 301 } 302 303 310 public int getValue(int index) { 311 return iValues[index]; 312 } 313 314 325 public Duration toDurationFrom(ReadableInstant startInstant) { 326 long startMillis = DateTimeUtils.getInstantMillis(startInstant); 327 Chronology chrono = DateTimeUtils.getInstantChronology(startInstant); 328 long endMillis = chrono.add(this, startMillis, 1); 329 return new Duration(startMillis, endMillis); 330 } 331 332 341 public Duration toDurationTo(ReadableInstant endInstant) { 342 long endMillis = DateTimeUtils.getInstantMillis(endInstant); 343 Chronology chrono = DateTimeUtils.getInstantChronology(endInstant); 344 long startMillis = chrono.add(this, endMillis, -1); 345 return new Duration(startMillis, endMillis); 346 } 347 348 357 private void checkAndUpdate(DurationFieldType type, int[] values, int newValue) { 358 int index = indexOf(type); 359 if (index == -1) { 360 if (newValue != 0) { 361 throw new IllegalArgumentException ( 362 "Period does not support field '" + type.getName() + "'"); 363 } 364 } else { 365 values[index] = newValue; 366 } 367 } 368 369 376 protected void setPeriod(ReadablePeriod period) { 377 if (period == null) { 378 setValues(new int[size()]); 379 } else { 380 setPeriodInternal(period); 381 } 382 } 383 384 387 private void setPeriodInternal(ReadablePeriod period) { 388 int[] newValues = new int[size()]; 389 for (int i = 0, isize = period.size(); i < isize; i++) { 390 DurationFieldType type = period.getFieldType(i); 391 int value = period.getValue(i); 392 checkAndUpdate(type, newValues, value); 393 } 394 iValues = newValues; 395 } 396 397 410 protected void setPeriod(int years, int months, int weeks, int days, 411 int hours, int minutes, int seconds, int millis) { 412 setPeriodInternal(years, months, weeks, days, hours, minutes, seconds, millis); 413 } 414 415 418 private void setPeriodInternal(int years, int months, int weeks, int days, 419 int hours, int minutes, int seconds, int millis) { 420 int[] newValues = new int[size()]; 421 checkAndUpdate(DurationFieldType.years(), newValues, years); 422 checkAndUpdate(DurationFieldType.months(), newValues, months); 423 checkAndUpdate(DurationFieldType.weeks(), newValues, weeks); 424 checkAndUpdate(DurationFieldType.days(), newValues, days); 425 checkAndUpdate(DurationFieldType.hours(), newValues, hours); 426 checkAndUpdate(DurationFieldType.minutes(), newValues, minutes); 427 checkAndUpdate(DurationFieldType.seconds(), newValues, seconds); 428 checkAndUpdate(DurationFieldType.millis(), newValues, millis); 429 iValues = newValues; 430 } 431 432 440 protected void setField(DurationFieldType field, int value) { 441 setFieldInto(iValues, field, value); 442 } 443 444 452 protected void setFieldInto(int[] values, DurationFieldType field, int value) { 453 int index = indexOf(field); 454 if (index == -1) { 455 if (value != 0 || field == null) { 456 throw new IllegalArgumentException ( 457 "Period does not support field '" + field + "'"); 458 } 459 } else { 460 values[index] = value; 461 } 462 } 463 464 471 protected void addField(DurationFieldType field, int value) { 472 addFieldInto(iValues, field, value); 473 } 474 475 483 protected void addFieldInto(int[] values, DurationFieldType field, int value) { 484 int index = indexOf(field); 485 if (index == -1) { 486 if (value != 0 || field == null) { 487 throw new IllegalArgumentException ( 488 "Period does not support field '" + field + "'"); 489 } 490 } else { 491 values[index] = FieldUtils.safeAdd(values[index], value); 492 } 493 } 494 495 501 protected void mergePeriod(ReadablePeriod period) { 502 if (period != null) { 503 iValues = mergePeriodInto(getValues(), period); 504 } 505 } 506 507 515 protected int[] mergePeriodInto(int[] values, ReadablePeriod period) { 516 for (int i = 0, isize = period.size(); i < isize; i++) { 517 DurationFieldType type = period.getFieldType(i); 518 int value = period.getValue(i); 519 checkAndUpdate(type, values, value); 520 } 521 return values; 522 } 523 524 530 protected void addPeriod(ReadablePeriod period) { 531 if (period != null) { 532 iValues = addPeriodInto(getValues(), period); 533 } 534 } 535 536 544 protected int[] addPeriodInto(int[] values, ReadablePeriod period) { 545 for (int i = 0, isize = period.size(); i < isize; i++) { 546 DurationFieldType type = period.getFieldType(i); 547 int value = period.getValue(i); 548 if (value != 0) { 549 int index = indexOf(type); 550 if (index == -1) { 551 throw new IllegalArgumentException ( 552 "Period does not support field '" + type.getName() + "'"); 553 } else { 554 values[index] = FieldUtils.safeAdd(getValue(index), value); 555 } 556 } 557 } 558 return values; 559 } 560 561 569 protected void setValue(int index, int value) { 570 iValues[index] = value; 571 } 572 573 578 protected void setValues(int[] values) { 579 iValues = values; 580 } 581 582 } 583 | Popular Tags |