1 16 package org.joda.time; 17 18 import java.io.IOException ; 19 import java.io.ObjectInputStream ; 20 import java.io.ObjectOutputStream ; 21 import java.io.Serializable ; 22 import java.util.Calendar ; 23 import java.util.Date ; 24 import java.util.HashSet ; 25 import java.util.Locale ; 26 import java.util.Set ; 27 28 import org.joda.time.base.AbstractPartial; 29 import org.joda.time.chrono.ISOChronology; 30 import org.joda.time.convert.ConverterManager; 31 import org.joda.time.convert.PartialConverter; 32 import org.joda.time.field.AbstractReadableInstantFieldProperty; 33 import org.joda.time.field.FieldUtils; 34 import org.joda.time.format.DateTimeFormat; 35 import org.joda.time.format.ISODateTimeFormat; 36 37 77 public final class LocalDate 78 extends AbstractPartial 79 implements ReadablePartial, Serializable { 80 81 82 private static final long serialVersionUID = -8775358157899L; 83 84 85 private static final int YEAR = 0; 86 87 private static final int MONTH_OF_YEAR = 1; 88 89 private static final int DAY_OF_MONTH = 2; 90 91 private static final Set DATE_DURATION_TYPES = new HashSet (); 92 static { 93 DATE_DURATION_TYPES.add(DurationFieldType.days()); 94 DATE_DURATION_TYPES.add(DurationFieldType.weeks()); 95 DATE_DURATION_TYPES.add(DurationFieldType.months()); 96 DATE_DURATION_TYPES.add(DurationFieldType.weekyears()); 97 DATE_DURATION_TYPES.add(DurationFieldType.years()); 98 DATE_DURATION_TYPES.add(DurationFieldType.centuries()); 99 DATE_DURATION_TYPES.add(DurationFieldType.eras()); 101 } 102 103 104 private long iLocalMillis; 105 106 private Chronology iChronology; 107 108 127 public static LocalDate fromCalendarFields(Calendar calendar) { 128 if (calendar == null) { 129 throw new IllegalArgumentException ("The calendar must not be null"); 130 } 131 return new LocalDate( 132 calendar.get(Calendar.YEAR), 133 calendar.get(Calendar.MONTH) + 1, 134 calendar.get(Calendar.DAY_OF_MONTH) 135 ); 136 } 137 138 153 public static LocalDate fromDateFields(Date date) { 154 if (date == null) { 155 throw new IllegalArgumentException ("The date must not be null"); 156 } 157 return new LocalDate( 158 date.getYear() + 1900, 159 date.getMonth() + 1, 160 date.getDate() 161 ); 162 } 163 164 171 public LocalDate() { 172 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance()); 173 } 174 175 184 public LocalDate(DateTimeZone zone) { 185 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone)); 186 } 187 188 197 public LocalDate(Chronology chronology) { 198 this(DateTimeUtils.currentTimeMillis(), chronology); 199 } 200 201 210 public LocalDate(long instant) { 211 this(instant, ISOChronology.getInstance()); 212 } 213 214 224 public LocalDate(long instant, DateTimeZone zone) { 225 this(instant, ISOChronology.getInstance(zone)); 226 } 227 228 238 public LocalDate(long instant, Chronology chronology) { 239 chronology = DateTimeUtils.getChronology(chronology); 240 241 long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant); 242 chronology = chronology.withUTC(); 243 chronology.dayOfMonth().roundFloor(localMillis); 244 iLocalMillis = localMillis; 245 iChronology = chronology; 246 } 247 248 266 public LocalDate(Object instant) { 267 this(instant, (Chronology) null); 268 } 269 270 288 public LocalDate(Object instant, DateTimeZone zone) { 289 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 290 Chronology chronology = converter.getChronology(instant, zone); 291 chronology = DateTimeUtils.getChronology(chronology); 292 iChronology = chronology.withUTC(); 293 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser()); 294 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0); 295 } 296 297 314 public LocalDate(Object instant, Chronology chronology) { 315 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 316 chronology = converter.getChronology(instant, chronology); 317 chronology = DateTimeUtils.getChronology(chronology); 318 iChronology = chronology.withUTC(); 319 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser()); 320 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0); 321 } 322 323 332 public LocalDate( 333 int year, 334 int monthOfYear, 335 int dayOfMonth) { 336 this(year, monthOfYear, dayOfMonth, ISOChronology.getInstanceUTC()); 337 } 338 339 350 public LocalDate( 351 int year, 352 int monthOfYear, 353 int dayOfMonth, 354 Chronology chronology) { 355 super(); 356 chronology = DateTimeUtils.getChronology(chronology).withUTC(); 357 long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, 0); 358 iChronology = chronology; 359 iLocalMillis = instant; 360 } 361 362 371 public int size() { 372 return 3; 373 } 374 375 384 protected DateTimeField getField(int index, Chronology chrono) { 385 switch (index) { 386 case YEAR: 387 return chrono.year(); 388 case MONTH_OF_YEAR: 389 return chrono.monthOfYear(); 390 case DAY_OF_MONTH: 391 return chrono.dayOfMonth(); 392 default: 393 throw new IndexOutOfBoundsException ("Invalid index: " + index); 394 } 395 } 396 397 409 public int getValue(int index) { 410 switch (index) { 411 case YEAR: 412 return getChronology().year().get(getLocalMillis()); 413 case MONTH_OF_YEAR: 414 return getChronology().monthOfYear().get(getLocalMillis()); 415 case DAY_OF_MONTH: 416 return getChronology().dayOfMonth().get(getLocalMillis()); 417 default: 418 throw new IndexOutOfBoundsException ("Invalid index: " + index); 419 } 420 } 421 422 437 public int get(DateTimeFieldType fieldType) { 438 if (fieldType == null) { 439 throw new IllegalArgumentException ("The DateTimeFieldType must not be null"); 440 } 441 if (isSupported(fieldType) == false) { 442 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 443 } 444 return fieldType.getField(getChronology()).get(getLocalMillis()); 445 } 446 447 455 public boolean isSupported(DateTimeFieldType type) { 456 if (type == null) { 457 return false; 458 } 459 DurationFieldType durType = type.getDurationType(); 460 if (DATE_DURATION_TYPES.contains(durType) || 461 durType.getField(getChronology()).getUnitMillis() >= 462 getChronology().days().getUnitMillis()) { 463 return type.getField(getChronology()).isSupported(); 464 } 465 return false; 466 } 467 468 475 public boolean isSupported(DurationFieldType type) { 476 if (type == null) { 477 return false; 478 } 479 DurationField field = type.getField(getChronology()); 480 if (DATE_DURATION_TYPES.contains(type) || 481 field.getUnitMillis() >= getChronology().days().getUnitMillis()) { 482 return field.isSupported(); 483 } 484 return false; 485 } 486 487 494 long getLocalMillis() { 495 return iLocalMillis; 496 } 497 498 503 public Chronology getChronology() { 504 return iChronology; 505 } 506 507 516 public DateTime toDateTimeAtMidnight() { 517 return toDateTimeAtMidnight(null); 518 } 519 520 532 public DateTime toDateTimeAtMidnight(DateTimeZone zone) { 533 zone = DateTimeUtils.getZone(zone); 534 Chronology chrono = getChronology().withZone(zone); 535 return new DateTime(getYear(), getMonthOfYear(), getDayOfMonth(), 0, 0, 0, 0, chrono); 536 } 537 538 548 public DateTime toDateTimeAtCurrentTime() { 549 return toDateTimeAtCurrentTime(null); 550 } 551 552 565 public DateTime toDateTimeAtCurrentTime(DateTimeZone zone) { 566 zone = DateTimeUtils.getZone(zone); 567 Chronology chrono = getChronology().withZone(zone); 568 long instantMillis = DateTimeUtils.currentTimeMillis(); 569 long resolved = chrono.set(this, instantMillis); 570 return new DateTime(resolved, chrono); 571 } 572 573 581 public DateMidnight toDateMidnight() { 582 return toDateMidnight(null); 583 } 584 585 593 public DateMidnight toDateMidnight(DateTimeZone zone) { 594 zone = DateTimeUtils.getZone(zone); 595 Chronology chrono = getChronology().withZone(zone); 596 return new DateMidnight(getYear(), getMonthOfYear(), getDayOfMonth(), chrono); 597 } 598 599 614 public DateTime toDateTime(LocalTime time) { 615 return toDateTime(time, null); 616 } 617 618 633 public DateTime toDateTime(LocalTime time, DateTimeZone zone) { 634 if (time != null && getChronology() != time.getChronology()) { 635 throw new IllegalArgumentException ("The chronology of the time does not match"); 636 } 637 Chronology chrono = getChronology().withZone(zone); 638 long instant = DateTimeUtils.currentTimeMillis(); 639 instant = chrono.set(this, instant); 640 if (time != null) { 641 instant = chrono.set(time, instant); 642 } 643 return new DateTime(instant, chrono); 644 } 645 646 655 public Interval toInterval() { 656 return toInterval(null); 657 } 658 659 667 public Interval toInterval(DateTimeZone zone) { 668 zone = DateTimeUtils.getZone(zone); 669 return toDateMidnight(zone).toInterval(); 670 } 671 672 683 LocalDate withLocalMillis(long newMillis) { 684 newMillis = iChronology.dayOfMonth().roundFloor(newMillis); 685 return (newMillis == getLocalMillis() ? this : new LocalDate(newMillis, getChronology())); 686 } 687 688 702 public LocalDate withFields(ReadablePartial partial) { 703 if (partial == null) { 704 return this; 705 } 706 return withLocalMillis(getChronology().set(partial, getLocalMillis())); 707 } 708 709 727 public LocalDate withField(DateTimeFieldType fieldType, int value) { 728 if (fieldType == null) { 729 throw new IllegalArgumentException ("Field must not be null"); 730 } 731 if (isSupported(fieldType) == false) { 732 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 733 } 734 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value); 735 return withLocalMillis(instant); 736 } 737 738 756 public LocalDate withFieldAdded(DurationFieldType fieldType, int amount) { 757 if (fieldType == null) { 758 throw new IllegalArgumentException ("Field must not be null"); 759 } 760 if (isSupported(fieldType) == false) { 761 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 762 } 763 if (amount == 0) { 764 return this; 765 } 766 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount); 767 return withLocalMillis(instant); 768 } 769 770 789 public LocalDate withPeriodAdded(ReadablePeriod period, int scalar) { 790 if (period == null || scalar == 0) { 791 return this; 792 } 793 long instant = getLocalMillis(); 794 Chronology chrono = getChronology(); 795 for (int i = 0; i < period.size(); i++) { 796 long value = FieldUtils.safeMultiply(period.getValue(i), scalar); 797 DurationFieldType type = period.getFieldType(i); 798 if (isSupported(type)) { 799 instant = type.getField(chrono).add(instant, value); 800 } 801 } 802 return withLocalMillis(instant); 803 } 804 805 822 public LocalDate plus(ReadablePeriod period) { 823 return withPeriodAdded(period, 1); 824 } 825 826 842 public LocalDate plusYears(int years) { 843 if (years == 0) { 844 return this; 845 } 846 long instant = getChronology().years().add(getLocalMillis(), years); 847 return withLocalMillis(instant); 848 } 849 850 865 public LocalDate plusMonths(int months) { 866 if (months == 0) { 867 return this; 868 } 869 long instant = getChronology().months().add(getLocalMillis(), months); 870 return withLocalMillis(instant); 871 } 872 873 888 public LocalDate plusWeeks(int weeks) { 889 if (weeks == 0) { 890 return this; 891 } 892 long instant = getChronology().weeks().add(getLocalMillis(), weeks); 893 return withLocalMillis(instant); 894 } 895 896 911 public LocalDate plusDays(int days) { 912 if (days == 0) { 913 return this; 914 } 915 long instant = getChronology().days().add(getLocalMillis(), days); 916 return withLocalMillis(instant); 917 } 918 919 936 public LocalDate minus(ReadablePeriod period) { 937 return withPeriodAdded(period, -1); 938 } 939 940 956 public LocalDate minusYears(int years) { 957 if (years == 0) { 958 return this; 959 } 960 long instant = getChronology().years().subtract(getLocalMillis(), years); 961 return withLocalMillis(instant); 962 } 963 964 979 public LocalDate minusMonths(int months) { 980 if (months == 0) { 981 return this; 982 } 983 long instant = getChronology().months().subtract(getLocalMillis(), months); 984 return withLocalMillis(instant); 985 } 986 987 1002 public LocalDate minusWeeks(int weeks) { 1003 if (weeks == 0) { 1004 return this; 1005 } 1006 long instant = getChronology().weeks().subtract(getLocalMillis(), weeks); 1007 return withLocalMillis(instant); 1008 } 1009 1010 1025 public LocalDate minusDays(int days) { 1026 if (days == 0) { 1027 return this; 1028 } 1029 long instant = getChronology().days().subtract(getLocalMillis(), days); 1030 return withLocalMillis(instant); 1031 } 1032 1033 1042 public Property property(DateTimeFieldType fieldType) { 1043 if (fieldType == null) { 1044 throw new IllegalArgumentException ("The DateTimeFieldType must not be null"); 1045 } 1046 if (isSupported(fieldType) == false) { 1047 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 1048 } 1049 return new Property(this, fieldType.getField(getChronology())); 1050 } 1051 1052 1058 public int getEra() { 1059 return getChronology().era().get(getLocalMillis()); 1060 } 1061 1062 1067 public int getCenturyOfEra() { 1068 return getChronology().centuryOfEra().get(getLocalMillis()); 1069 } 1070 1071 1076 public int getYearOfEra() { 1077 return getChronology().yearOfEra().get(getLocalMillis()); 1078 } 1079 1080 1085 public int getYearOfCentury() { 1086 return getChronology().yearOfCentury().get(getLocalMillis()); 1087 } 1088 1089 1094 public int getYear() { 1095 return getChronology().year().get(getLocalMillis()); 1096 } 1097 1098 1109 public int getWeekyear() { 1110 return getChronology().weekyear().get(getLocalMillis()); 1111 } 1112 1113 1118 public int getMonthOfYear() { 1119 return getChronology().monthOfYear().get(getLocalMillis()); 1120 } 1121 1122 1127 public int getWeekOfWeekyear() { 1128 return getChronology().weekOfWeekyear().get(getLocalMillis()); 1129 } 1130 1131 1136 public int getDayOfYear() { 1137 return getChronology().dayOfYear().get(getLocalMillis()); 1138 } 1139 1140 1147 public int getDayOfMonth() { 1148 return getChronology().dayOfMonth().get(getLocalMillis()); 1149 } 1150 1151 1158 public int getDayOfWeek() { 1159 return getChronology().dayOfWeek().get(getLocalMillis()); 1160 } 1161 1162 1174 public LocalDate withEra(int era) { 1175 return withLocalMillis(getChronology().era().set(getLocalMillis(), era)); 1176 } 1177 1178 1189 public LocalDate withCenturyOfEra(int centuryOfEra) { 1190 return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra)); 1191 } 1192 1193 1204 public LocalDate withYearOfEra(int yearOfEra) { 1205 return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra)); 1206 } 1207 1208 1219 public LocalDate withYearOfCentury(int yearOfCentury) { 1220 return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury)); 1221 } 1222 1223 1234 public LocalDate withYear(int year) { 1235 return withLocalMillis(getChronology().year().set(getLocalMillis(), year)); 1236 } 1237 1238 1249 public LocalDate withWeekyear(int weekyear) { 1250 return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear)); 1251 } 1252 1253 1264 public LocalDate withMonthOfYear(int monthOfYear) { 1265 return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear)); 1266 } 1267 1268 1279 public LocalDate withWeekOfWeekyear(int weekOfWeekyear) { 1280 return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear)); 1281 } 1282 1283 1294 public LocalDate withDayOfYear(int dayOfYear) { 1295 return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear)); 1296 } 1297 1298 1309 public LocalDate withDayOfMonth(int dayOfMonth) { 1310 return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth)); 1311 } 1312 1313 1324 public LocalDate withDayOfWeek(int dayOfWeek) { 1325 return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek)); 1326 } 1327 1328 1334 public Property era() { 1335 return new Property(this, getChronology().era()); 1336 } 1337 1338 1343 public Property centuryOfEra() { 1344 return new Property(this, getChronology().centuryOfEra()); 1345 } 1346 1347 1352 public Property yearOfCentury() { 1353 return new Property(this, getChronology().yearOfCentury()); 1354 } 1355 1356 1361 public Property yearOfEra() { 1362 return new Property(this, getChronology().yearOfEra()); 1363 } 1364 1365 1370 public Property year() { 1371 return new Property(this, getChronology().year()); 1372 } 1373 1374 1379 public Property weekyear() { 1380 return new Property(this, getChronology().weekyear()); 1381 } 1382 1383 1388 public Property monthOfYear() { 1389 return new Property(this, getChronology().monthOfYear()); 1390 } 1391 1392 1397 public Property weekOfWeekyear() { 1398 return new Property(this, getChronology().weekOfWeekyear()); 1399 } 1400 1401 1406 public Property dayOfYear() { 1407 return new Property(this, getChronology().dayOfYear()); 1408 } 1409 1410 1415 public Property dayOfMonth() { 1416 return new Property(this, getChronology().dayOfMonth()); 1417 } 1418 1419 1424 public Property dayOfWeek() { 1425 return new Property(this, getChronology().dayOfWeek()); 1426 } 1427 1428 1434 public String toString() { 1435 return ISODateTimeFormat.date().print(this); 1436 } 1437 1438 1444 public String toString(String pattern) { 1445 if (pattern == null) { 1446 return toString(); 1447 } 1448 return DateTimeFormat.forPattern(pattern).print(this); 1449 } 1450 1451 1458 public String toString(String pattern, Locale locale) throws IllegalArgumentException { 1459 if (pattern == null) { 1460 return toString(); 1461 } 1462 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this); 1463 } 1464 1465 1493 public static final class Property extends AbstractReadableInstantFieldProperty { 1494 1495 1496 private static final long serialVersionUID = -3193829732634L; 1497 1498 1499 private transient LocalDate iInstant; 1500 1501 private transient DateTimeField iField; 1502 1503 1509 Property(LocalDate instant, DateTimeField field) { 1510 super(); 1511 iInstant = instant; 1512 iField = field; 1513 } 1514 1515 1518 private void writeObject(ObjectOutputStream oos) throws IOException { 1519 oos.writeObject(iInstant); 1520 oos.writeObject(iField.getType()); 1521 } 1522 1523 1526 private void readObject(ObjectInputStream oos) throws IOException , ClassNotFoundException { 1527 iInstant = (LocalDate) oos.readObject(); 1528 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 1529 iField = type.getField(iInstant.getChronology()); 1530 } 1531 1532 1538 public DateTimeField getField() { 1539 return iField; 1540 } 1541 1542 1547 protected long getMillis() { 1548 return iInstant.getLocalMillis(); 1549 } 1550 1551 1557 protected Chronology getChronology() { 1558 return iInstant.getChronology(); 1559 } 1560 1561 1566 public LocalDate getLocalDate() { 1567 return iInstant; 1568 } 1569 1570 1580 public LocalDate addToCopy(int value) { 1581 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 1582 } 1583 1584 1595 public LocalDate addWrapFieldToCopy(int value) { 1596 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value)); 1597 } 1598 1599 1609 public LocalDate setCopy(int value) { 1610 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value)); 1611 } 1612 1613 1623 public LocalDate setCopy(String text, Locale locale) { 1624 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale)); 1625 } 1626 1627 1636 public LocalDate setCopy(String text) { 1637 return setCopy(text, null); 1638 } 1639 1640 1655 public LocalDate withMaximumValue() { 1656 return setCopy(getMaximumValue()); 1657 } 1658 1659 1667 public LocalDate withMinimumValue() { 1668 return setCopy(getMinimumValue()); 1669 } 1670 1671 1682 public LocalDate roundFloorCopy() { 1683 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis())); 1684 } 1685 1686 1696 public LocalDate roundCeilingCopy() { 1697 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis())); 1698 } 1699 1700 1706 public LocalDate roundHalfFloorCopy() { 1707 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis())); 1708 } 1709 1710 1716 public LocalDate roundHalfCeilingCopy() { 1717 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis())); 1718 } 1719 1720 1727 public LocalDate roundHalfEvenCopy() { 1728 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis())); 1729 } 1730 } 1731 1732} 1733 | Popular Tags |