1 16 package org.joda.time.field; 17 18 import java.util.Locale ; 19 20 import org.joda.time.DateTimeField; 21 import org.joda.time.DateTimeFieldType; 22 import org.joda.time.DurationField; 23 import org.joda.time.IllegalFieldValueException; 24 import org.joda.time.ReadablePartial; 25 26 41 public abstract class BaseDateTimeField extends DateTimeField { 42 43 44 private final DateTimeFieldType iType; 45 46 49 protected BaseDateTimeField(DateTimeFieldType type) { 50 super(); 51 if (type == null) { 52 throw new IllegalArgumentException ("The type must not be null"); 53 } 54 iType = type; 55 } 56 57 public final DateTimeFieldType getType() { 58 return iType; 59 } 60 61 public final String getName() { 62 return iType.getName(); 63 } 64 65 68 public final boolean isSupported() { 69 return true; 70 } 71 72 80 public abstract int get(long instant); 81 82 93 public String getAsText(long instant, Locale locale) { 94 return getAsText(get(instant), locale); 95 } 96 97 105 public final String getAsText(long instant) { 106 return getAsText(instant, null); 107 } 108 109 120 public String getAsText(ReadablePartial partial, int fieldValue, Locale locale) { 121 return getAsText(fieldValue, locale); 122 } 123 124 135 public final String getAsText(ReadablePartial partial, Locale locale) { 136 return getAsText(partial, partial.get(getType()), locale); 137 } 138 139 152 public String getAsText(int fieldValue, Locale locale) { 153 return Integer.toString(fieldValue); 154 } 155 156 167 public String getAsShortText(long instant, Locale locale) { 168 return getAsShortText(get(instant), locale); 169 } 170 171 179 public final String getAsShortText(long instant) { 180 return getAsShortText(instant, null); 181 } 182 183 194 public String getAsShortText(ReadablePartial partial, int fieldValue, Locale locale) { 195 return getAsShortText(fieldValue, locale); 196 } 197 198 209 public final String getAsShortText(ReadablePartial partial, Locale locale) { 210 return getAsShortText(partial, partial.get(getType()), locale); 211 } 212 213 226 public String getAsShortText(int fieldValue, Locale locale) { 227 return getAsText(fieldValue, locale); 228 } 229 230 252 public long add(long instant, int value) { 253 return getDurationField().add(instant, value); 254 } 255 256 266 public long add(long instant, long value) { 267 return getDurationField().add(instant, value); 268 } 269 270 297 public int[] add(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { 298 if (valueToAdd == 0) { 299 return values; 300 } 301 DateTimeField nextField = null; 305 306 while (valueToAdd > 0) { 307 int max = getMaximumValue(instant, values); 308 long proposed = values[fieldIndex] + valueToAdd; 309 if (proposed <= max) { 310 values[fieldIndex] = (int) proposed; 311 break; 312 } 313 if (nextField == null) { 314 if (fieldIndex == 0) { 315 throw new IllegalArgumentException ("Maximum value exceeded for add"); 316 } 317 nextField = instant.getField(fieldIndex - 1); 318 if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { 320 throw new IllegalArgumentException ("Fields invalid for add"); 321 } 322 } 323 valueToAdd -= (max + 1) - values[fieldIndex]; values = nextField.add(instant, fieldIndex - 1, values, 1); values[fieldIndex] = getMinimumValue(instant, values); } 327 while (valueToAdd < 0) { 328 int min = getMinimumValue(instant, values); 329 long proposed = values[fieldIndex] + valueToAdd; 330 if (proposed >= min) { 331 values[fieldIndex] = (int) proposed; 332 break; 333 } 334 if (nextField == null) { 335 if (fieldIndex == 0) { 336 throw new IllegalArgumentException ("Maximum value exceeded for add"); 337 } 338 nextField = instant.getField(fieldIndex - 1); 339 if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { 340 throw new IllegalArgumentException ("Fields invalid for add"); 341 } 342 } 343 valueToAdd -= (min - 1) - values[fieldIndex]; values = nextField.add(instant, fieldIndex - 1, values, -1); values[fieldIndex] = getMaximumValue(instant, values); } 347 348 return set(instant, fieldIndex, values, values[fieldIndex]); } 350 351 378 public int[] addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { 379 if (valueToAdd == 0) { 380 return values; 381 } 382 DateTimeField nextField = null; 386 387 while (valueToAdd > 0) { 388 int max = getMaximumValue(instant, values); 389 long proposed = values[fieldIndex] + valueToAdd; 390 if (proposed <= max) { 391 values[fieldIndex] = (int) proposed; 392 break; 393 } 394 if (nextField == null) { 395 if (fieldIndex == 0) { 396 valueToAdd -= (max + 1) - values[fieldIndex]; 397 values[fieldIndex] = getMinimumValue(instant, values); 398 continue; 399 } 400 nextField = instant.getField(fieldIndex - 1); 401 if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { 403 throw new IllegalArgumentException ("Fields invalid for add"); 404 } 405 } 406 valueToAdd -= (max + 1) - values[fieldIndex]; values = nextField.addWrapPartial(instant, fieldIndex - 1, values, 1); values[fieldIndex] = getMinimumValue(instant, values); } 410 while (valueToAdd < 0) { 411 int min = getMinimumValue(instant, values); 412 long proposed = values[fieldIndex] + valueToAdd; 413 if (proposed >= min) { 414 values[fieldIndex] = (int) proposed; 415 break; 416 } 417 if (nextField == null) { 418 if (fieldIndex == 0) { 419 valueToAdd -= (min - 1) - values[fieldIndex]; 420 values[fieldIndex] = getMaximumValue(instant, values); 421 continue; 422 } 423 nextField = instant.getField(fieldIndex - 1); 424 if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { 425 throw new IllegalArgumentException ("Fields invalid for add"); 426 } 427 } 428 valueToAdd -= (min - 1) - values[fieldIndex]; values = nextField.addWrapPartial(instant, fieldIndex - 1, values, -1); values[fieldIndex] = getMaximumValue(instant, values); } 432 433 return set(instant, fieldIndex, values, values[fieldIndex]); } 435 436 460 public long addWrapField(long instant, int value) { 461 int current = get(instant); 462 int wrapped = FieldUtils.getWrappedValue 463 (current, value, getMinimumValue(instant), getMaximumValue(instant)); 464 return set(instant, wrapped); 465 } 466 467 494 public int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { 495 int current = values[fieldIndex]; 496 int wrapped = FieldUtils.getWrappedValue 497 (current, valueToAdd, getMinimumValue(instant), getMaximumValue(instant)); 498 return set(instant, fieldIndex, values, wrapped); } 500 501 521 public int getDifference(long minuendInstant, long subtrahendInstant) { 522 return getDurationField().getDifference(minuendInstant, subtrahendInstant); 523 } 524 525 544 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) { 545 return getDurationField().getDifferenceAsLong(minuendInstant, subtrahendInstant); 546 } 547 548 564 public abstract long set(long instant, int value); 565 566 584 public int[] set(ReadablePartial partial, int fieldIndex, int[] values, int newValue) { 585 FieldUtils.verifyValueBounds(this, newValue, getMinimumValue(partial, values), getMaximumValue(partial, values)); 586 values[fieldIndex] = newValue; 587 588 for (int i = fieldIndex + 1; i < partial.size(); i++) { 590 DateTimeField field = partial.getField(i); 591 if (values[i] > field.getMaximumValue(partial, values)) { 592 values[i] = field.getMaximumValue(partial, values); 593 } 594 if (values[i] < field.getMinimumValue(partial, values)) { 595 values[i] = field.getMinimumValue(partial, values); 596 } 597 } 598 return values; 599 } 600 601 617 public long set(long instant, String text, Locale locale) { 618 int value = convertText(text, locale); 619 return set(instant, value); 620 } 621 622 634 public final long set(long instant, String text) { 635 return set(instant, text, null); 636 } 637 638 653 public int[] set(ReadablePartial instant, int fieldIndex, int[] values, String text, Locale locale) { 654 int value = convertText(text, locale); 655 return set(instant, fieldIndex, values, value); 656 } 657 658 666 protected int convertText(String text, Locale locale) { 667 try { 668 return Integer.parseInt(text); 669 } catch (NumberFormatException ex) { 670 throw new IllegalFieldValueException(getType(), text); 671 } 672 } 673 674 683 public abstract DurationField getDurationField(); 684 685 691 public abstract DurationField getRangeDurationField(); 692 693 703 public boolean isLeap(long instant) { 704 return false; 705 } 706 707 715 public int getLeapAmount(long instant) { 716 return 0; 717 } 718 719 725 public DurationField getLeapDurationField() { 726 return null; 727 } 728 729 735 public abstract int getMinimumValue(); 736 737 745 public int getMinimumValue(long instant) { 746 return getMinimumValue(); 747 } 748 749 757 public int getMinimumValue(ReadablePartial instant) { 758 return getMinimumValue(); 759 } 760 761 771 public int getMinimumValue(ReadablePartial instant, int[] values) { 772 return getMinimumValue(instant); 773 } 774 775 781 public abstract int getMaximumValue(); 782 783 791 public int getMaximumValue(long instant) { 792 return getMaximumValue(); 793 } 794 795 803 public int getMaximumValue(ReadablePartial instant) { 804 return getMaximumValue(); 805 } 806 807 817 public int getMaximumValue(ReadablePartial instant, int[] values) { 818 return getMaximumValue(instant); 819 } 820 821 828 public int getMaximumTextLength(Locale locale) { 829 int max = getMaximumValue(); 830 if (max >= 0) { 831 if (max < 10) { 832 return 1; 833 } else if (max < 100) { 834 return 2; 835 } else if (max < 1000) { 836 return 3; 837 } 838 } 839 return Integer.toString(max).length(); 840 } 841 842 849 public int getMaximumShortTextLength(Locale locale) { 850 return getMaximumTextLength(locale); 851 } 852 853 867 public abstract long roundFloor(long instant); 868 869 885 public long roundCeiling(long instant) { 886 long newInstant = roundFloor(instant); 887 if (newInstant != instant) { 888 instant = add(newInstant, 1); 889 } 890 return instant; 891 } 892 893 902 public long roundHalfFloor(long instant) { 903 long floor = roundFloor(instant); 904 long ceiling = roundCeiling(instant); 905 906 long diffFromFloor = instant - floor; 907 long diffToCeiling = ceiling - instant; 908 909 if (diffFromFloor <= diffToCeiling) { 910 return floor; 912 } else { 913 return ceiling; 914 } 915 } 916 917 926 public long roundHalfCeiling(long instant) { 927 long floor = roundFloor(instant); 928 long ceiling = roundCeiling(instant); 929 930 long diffFromFloor = instant - floor; 931 long diffToCeiling = ceiling - instant; 932 933 if (diffToCeiling <= diffFromFloor) { 934 return ceiling; 936 } else { 937 return floor; 938 } 939 } 940 941 954 public long roundHalfEven(long instant) { 955 long floor = roundFloor(instant); 956 long ceiling = roundCeiling(instant); 957 958 long diffFromFloor = instant - floor; 959 long diffToCeiling = ceiling - instant; 960 961 if (diffFromFloor < diffToCeiling) { 962 return floor; 964 } else if (diffToCeiling < diffFromFloor) { 965 return ceiling; 967 } else { 968 if ((get(ceiling) & 1) == 0) { 971 return ceiling; 972 } 973 return floor; 974 } 975 } 976 977 993 public long remainder(long instant) { 994 return instant - roundFloor(instant); 995 } 996 997 1002 public String toString() { 1003 return "DateTimeField[" + getName() + ']'; 1004 } 1005 1006} 1007 | Popular Tags |