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.format.DateTimeFormat; 34 import org.joda.time.format.ISODateTimeFormat; 35 36 73 public final class LocalTime 74 extends AbstractPartial 75 implements ReadablePartial, Serializable { 76 77 78 private static final long serialVersionUID = -12873158713873L; 79 80 81 public static final LocalTime MIDNIGHT = new LocalTime(0, 0, 0, 0); 82 83 84 private static final int HOUR_OF_DAY = 0; 85 86 private static final int MINUTE_OF_HOUR = 1; 87 88 private static final int SECOND_OF_MINUTE = 2; 89 90 private static final int MILLIS_OF_SECOND = 3; 91 92 private static final Set TIME_DURATION_TYPES = new HashSet (); 93 static { 94 TIME_DURATION_TYPES.add(DurationFieldType.millis()); 95 TIME_DURATION_TYPES.add(DurationFieldType.seconds()); 96 TIME_DURATION_TYPES.add(DurationFieldType.minutes()); 97 TIME_DURATION_TYPES.add(DurationFieldType.hours()); 98 } 99 100 101 private long iLocalMillis; 102 103 private Chronology iChronology; 104 105 116 public static LocalTime fromMillisOfDay(long millisOfDay) { 117 return fromMillisOfDay(millisOfDay, null); 118 } 119 120 131 public static LocalTime fromMillisOfDay(long millisOfDay, Chronology chrono) { 132 chrono = DateTimeUtils.getChronology(chrono).withUTC(); 133 return new LocalTime(millisOfDay, chrono); 134 } 135 136 155 public static LocalTime fromCalendarFields(Calendar calendar) { 156 if (calendar == null) { 157 throw new IllegalArgumentException ("The calendar must not be null"); 158 } 159 return new LocalTime( 160 calendar.get(Calendar.HOUR_OF_DAY), 161 calendar.get(Calendar.MINUTE), 162 calendar.get(Calendar.SECOND), 163 calendar.get(Calendar.MILLISECOND) 164 ); 165 } 166 167 182 public static LocalTime fromDateFields(Date date) { 183 if (date == null) { 184 throw new IllegalArgumentException ("The date must not be null"); 185 } 186 return new LocalTime( 187 date.getHours(), 188 date.getMinutes(), 189 date.getSeconds(), 190 (int) (date.getTime() % 1000) 191 ); 192 } 193 194 201 public LocalTime() { 202 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance()); 203 } 204 205 214 public LocalTime(DateTimeZone zone) { 215 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone)); 216 } 217 218 227 public LocalTime(Chronology chronology) { 228 this(DateTimeUtils.currentTimeMillis(), chronology); 229 } 230 231 240 public LocalTime(long instant) { 241 this(instant, ISOChronology.getInstance()); 242 } 243 244 254 public LocalTime(long instant, DateTimeZone zone) { 255 this(instant, ISOChronology.getInstance(zone)); 256 } 257 258 268 public LocalTime(long instant, Chronology chronology) { 269 chronology = DateTimeUtils.getChronology(chronology); 270 271 long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant); 272 chronology = chronology.withUTC(); 273 chronology.millisOfDay().get(localMillis); 274 iLocalMillis = localMillis; 275 iChronology = chronology; 276 } 277 278 295 public LocalTime(Object instant) { 296 this(instant, (Chronology) null); 297 } 298 299 317 public LocalTime(Object instant, DateTimeZone zone) { 318 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 319 Chronology chronology = converter.getChronology(instant, zone); 320 chronology = DateTimeUtils.getChronology(chronology); 321 iChronology = chronology.withUTC(); 322 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localTimeParser()); 323 iLocalMillis = iChronology.getDateTimeMillis(0L, values[0], values[1], values[2], values[3]); 324 } 325 326 343 public LocalTime(Object instant, Chronology chronology) { 344 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 345 chronology = converter.getChronology(instant, chronology); 346 chronology = DateTimeUtils.getChronology(chronology); 347 iChronology = chronology.withUTC(); 348 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localTimeParser()); 349 iLocalMillis = iChronology.getDateTimeMillis(0L, values[0], values[1], values[2], values[3]); 350 } 351 352 360 public LocalTime( 361 int hourOfDay, 362 int minuteOfHour) { 363 this(hourOfDay, minuteOfHour, 0, 0, ISOChronology.getInstanceUTC()); 364 } 365 366 374 public LocalTime( 375 int hourOfDay, 376 int minuteOfHour, 377 int secondOfMinute) { 378 this(hourOfDay, minuteOfHour, secondOfMinute, 0, ISOChronology.getInstanceUTC()); 379 } 380 381 390 public LocalTime( 391 int hourOfDay, 392 int minuteOfHour, 393 int secondOfMinute, 394 int millisOfSecond) { 395 this(hourOfDay, minuteOfHour, secondOfMinute, 396 millisOfSecond, ISOChronology.getInstanceUTC()); 397 } 398 399 411 public LocalTime( 412 int hourOfDay, 413 int minuteOfHour, 414 int secondOfMinute, 415 int millisOfSecond, 416 Chronology chronology) { 417 super(); 418 chronology = DateTimeUtils.getChronology(chronology).withUTC(); 419 long instant = chronology.getDateTimeMillis( 420 0L, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond); 421 iChronology = chronology; 422 iLocalMillis = instant; 423 } 424 425 433 public int size() { 434 return 4; 435 } 436 437 446 protected DateTimeField getField(int index, Chronology chrono) { 447 switch (index) { 448 case HOUR_OF_DAY: 449 return chrono.hourOfDay(); 450 case MINUTE_OF_HOUR: 451 return chrono.minuteOfHour(); 452 case SECOND_OF_MINUTE: 453 return chrono.secondOfMinute(); 454 case MILLIS_OF_SECOND: 455 return chrono.millisOfSecond(); 456 default: 457 throw new IndexOutOfBoundsException ("Invalid index: " + index); 458 } 459 } 460 461 472 public int getValue(int index) { 473 switch (index) { 474 case HOUR_OF_DAY: 475 return getChronology().hourOfDay().get(getLocalMillis()); 476 case MINUTE_OF_HOUR: 477 return getChronology().minuteOfHour().get(getLocalMillis()); 478 case SECOND_OF_MINUTE: 479 return getChronology().secondOfMinute().get(getLocalMillis()); 480 case MILLIS_OF_SECOND: 481 return getChronology().millisOfSecond().get(getLocalMillis()); 482 default: 483 throw new IndexOutOfBoundsException ("Invalid index: " + index); 484 } 485 } 486 487 502 public int get(DateTimeFieldType fieldType) { 503 if (fieldType == null) { 504 throw new IllegalArgumentException ("The DateTimeFieldType must not be null"); 505 } 506 if (isSupported(fieldType) == false) { 507 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 508 } 509 return fieldType.getField(getChronology()).get(getLocalMillis()); 510 } 511 512 520 public boolean isSupported(DateTimeFieldType type) { 521 if (type == null) { 522 return false; 523 } 524 if (isSupported(type.getDurationType()) == false) { 525 return false; 526 } 527 DurationFieldType range = type.getRangeDurationType(); 528 return (isSupported(range) || range == DurationFieldType.days()); 529 } 530 531 538 public boolean isSupported(DurationFieldType type) { 539 if (type == null) { 540 return false; 541 } 542 DurationField field = type.getField(getChronology()); 543 if (TIME_DURATION_TYPES.contains(type) || 544 field.getUnitMillis() < getChronology().days().getUnitMillis()) { 545 return field.isSupported(); 546 } 547 return false; 548 } 549 550 557 long getLocalMillis() { 558 return iLocalMillis; 559 } 560 561 566 public Chronology getChronology() { 567 return iChronology; 568 } 569 570 581 LocalTime withLocalMillis(long newMillis) { 582 return (newMillis == getLocalMillis() ? this : new LocalTime(newMillis, getChronology())); 583 } 584 585 599 public LocalTime withFields(ReadablePartial partial) { 600 if (partial == null) { 601 return this; 602 } 603 return withLocalMillis(getChronology().set(partial, getLocalMillis())); 604 } 605 606 625 public LocalTime withField(DateTimeFieldType fieldType, int value) { 626 if (fieldType == null) { 627 throw new IllegalArgumentException ("Field must not be null"); 628 } 629 if (isSupported(fieldType) == false) { 630 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 631 } 632 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value); 633 return withLocalMillis(instant); 634 } 635 636 658 public LocalTime withFieldAdded(DurationFieldType fieldType, int amount) { 659 if (fieldType == null) { 660 throw new IllegalArgumentException ("Field must not be null"); 661 } 662 if (isSupported(fieldType) == false) { 663 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 664 } 665 if (amount == 0) { 666 return this; 667 } 668 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount); 669 return withLocalMillis(instant); 670 } 671 672 688 public LocalTime withPeriodAdded(ReadablePeriod period, int scalar) { 689 if (period == null || scalar == 0) { 690 return this; 691 } 692 long instant = getChronology().add(period, getLocalMillis(), scalar); 693 return withLocalMillis(instant); 694 } 695 696 710 public LocalTime plus(ReadablePeriod period) { 711 return withPeriodAdded(period, 1); 712 } 713 714 730 public LocalTime plusHours(int hours) { 731 if (hours == 0) { 732 return this; 733 } 734 long instant = getChronology().hours().add(getLocalMillis(), hours); 735 return withLocalMillis(instant); 736 } 737 738 753 public LocalTime plusMinutes(int minutes) { 754 if (minutes == 0) { 755 return this; 756 } 757 long instant = getChronology().minutes().add(getLocalMillis(), minutes); 758 return withLocalMillis(instant); 759 } 760 761 776 public LocalTime plusSeconds(int seconds) { 777 if (seconds == 0) { 778 return this; 779 } 780 long instant = getChronology().seconds().add(getLocalMillis(), seconds); 781 return withLocalMillis(instant); 782 } 783 784 799 public LocalTime plusMillis(int millis) { 800 if (millis == 0) { 801 return this; 802 } 803 long instant = getChronology().millis().add(getLocalMillis(), millis); 804 return withLocalMillis(instant); 805 } 806 807 821 public LocalTime minus(ReadablePeriod period) { 822 return withPeriodAdded(period, -1); 823 } 824 825 841 public LocalTime minusHours(int hours) { 842 if (hours == 0) { 843 return this; 844 } 845 long instant = getChronology().hours().subtract(getLocalMillis(), hours); 846 return withLocalMillis(instant); 847 } 848 849 864 public LocalTime minusMinutes(int minutes) { 865 if (minutes == 0) { 866 return this; 867 } 868 long instant = getChronology().minutes().subtract(getLocalMillis(), minutes); 869 return withLocalMillis(instant); 870 } 871 872 887 public LocalTime minusSeconds(int seconds) { 888 if (seconds == 0) { 889 return this; 890 } 891 long instant = getChronology().seconds().subtract(getLocalMillis(), seconds); 892 return withLocalMillis(instant); 893 } 894 895 910 public LocalTime minusMillis(int millis) { 911 if (millis == 0) { 912 return this; 913 } 914 long instant = getChronology().millis().subtract(getLocalMillis(), millis); 915 return withLocalMillis(instant); 916 } 917 918 927 public Property property(DateTimeFieldType fieldType) { 928 if (fieldType == null) { 929 throw new IllegalArgumentException ("The DateTimeFieldType must not be null"); 930 } 931 if (isSupported(fieldType) == false) { 932 throw new IllegalArgumentException ("Field '" + fieldType + "' is not supported"); 933 } 934 return new Property(this, fieldType.getField(getChronology())); 935 } 936 937 943 public int getHourOfDay() { 944 return getChronology().hourOfDay().get(getLocalMillis()); 945 } 946 947 952 public int getMinuteOfHour() { 953 return getChronology().minuteOfHour().get(getLocalMillis()); 954 } 955 956 961 public int getSecondOfMinute() { 962 return getChronology().secondOfMinute().get(getLocalMillis()); 963 } 964 965 970 public int getMillisOfSecond() { 971 return getChronology().millisOfSecond().get(getLocalMillis()); 972 } 973 974 979 public int getMillisOfDay() { 980 return getChronology().millisOfDay().get(getLocalMillis()); 981 } 982 983 995 public LocalTime withHourOfDay(int hour) { 996 return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour)); 997 } 998 999 1010 public LocalTime withMinuteOfHour(int minute) { 1011 return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute)); 1012 } 1013 1014 1025 public LocalTime withSecondOfMinute(int second) { 1026 return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second)); 1027 } 1028 1029 1040 public LocalTime withMillisOfSecond(int millis) { 1041 return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis)); 1042 } 1043 1044 1055 public LocalTime withMillisOfDay(int millis) { 1056 return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis)); 1057 } 1058 1059 1065 public Property hourOfDay() { 1066 return new Property(this, getChronology().hourOfDay()); 1067 } 1068 1069 1074 public Property minuteOfHour() { 1075 return new Property(this, getChronology().minuteOfHour()); 1076 } 1077 1078 1083 public Property secondOfMinute() { 1084 return new Property(this, getChronology().secondOfMinute()); 1085 } 1086 1087 1092 public Property millisOfSecond() { 1093 return new Property(this, getChronology().millisOfSecond()); 1094 } 1095 1096 1101 public Property millisOfDay() { 1102 return new Property(this, getChronology().millisOfDay()); 1103 } 1104 1105 1113 public DateTime toDateTimeToday() { 1114 return toDateTimeToday(null); 1115 } 1116 1117 1128 public DateTime toDateTimeToday(DateTimeZone zone) { 1129 Chronology chrono = getChronology().withZone(zone); 1130 long instantMillis = DateTimeUtils.currentTimeMillis(); 1131 long resolved = chrono.set(this, instantMillis); 1132 return new DateTime(resolved, chrono); 1133 } 1134 1135 1141 public String toString() { 1142 return ISODateTimeFormat.time().print(this); 1143 } 1144 1145 1151 public String toString(String pattern) { 1152 if (pattern == null) { 1153 return toString(); 1154 } 1155 return DateTimeFormat.forPattern(pattern).print(this); 1156 } 1157 1158 1165 public String toString(String pattern, Locale locale) throws IllegalArgumentException { 1166 if (pattern == null) { 1167 return toString(); 1168 } 1169 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this); 1170 } 1171 1172 1199 public static final class Property extends AbstractReadableInstantFieldProperty { 1200 1201 1202 private static final long serialVersionUID = -325842547277223L; 1203 1204 1205 private transient LocalTime iInstant; 1206 1207 private transient DateTimeField iField; 1208 1209 1215 Property(LocalTime instant, DateTimeField field) { 1216 super(); 1217 iInstant = instant; 1218 iField = field; 1219 } 1220 1221 1224 private void writeObject(ObjectOutputStream oos) throws IOException { 1225 oos.writeObject(iInstant); 1226 oos.writeObject(iField.getType()); 1227 } 1228 1229 1232 private void readObject(ObjectInputStream oos) throws IOException , ClassNotFoundException { 1233 iInstant = (LocalTime) oos.readObject(); 1234 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 1235 iField = type.getField(iInstant.getChronology()); 1236 } 1237 1238 1244 public DateTimeField getField() { 1245 return iField; 1246 } 1247 1248 1253 protected long getMillis() { 1254 return iInstant.getLocalMillis(); 1255 } 1256 1257 1263 protected Chronology getChronology() { 1264 return iInstant.getChronology(); 1265 } 1266 1267 1272 public LocalTime getLocalTime() { 1273 return iInstant; 1274 } 1275 1276 1285 public LocalTime addCopy(int value) { 1286 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 1287 } 1288 1289 1299 public LocalTime addCopy(long value) { 1300 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 1301 } 1302 1303 1315 public LocalTime addNoWrapToCopy(int value) { 1316 long millis = iField.add(iInstant.getLocalMillis(), value); 1317 long rounded = iInstant.getChronology().millisOfDay().get(millis); 1318 if (rounded != millis) { 1319 throw new IllegalArgumentException ("The addition exceeded the boundaries of LocalTime"); 1320 } 1321 return iInstant.withLocalMillis(millis); 1322 } 1323 1324 1335 public LocalTime addWrapFieldToCopy(int value) { 1336 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value)); 1337 } 1338 1339 1349 public LocalTime setCopy(int value) { 1350 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value)); 1351 } 1352 1353 1363 public LocalTime setCopy(String text, Locale locale) { 1364 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale)); 1365 } 1366 1367 1376 public LocalTime setCopy(String text) { 1377 return setCopy(text, null); 1378 } 1379 1380 1389 public LocalTime withMaximumValue() { 1390 return setCopy(getMaximumValue()); 1391 } 1392 1393 1401 public LocalTime withMinimumValue() { 1402 return setCopy(getMinimumValue()); 1403 } 1404 1405 1416 public LocalTime roundFloorCopy() { 1417 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis())); 1418 } 1419 1420 1430 public LocalTime roundCeilingCopy() { 1431 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis())); 1432 } 1433 1434 1440 public LocalTime roundHalfFloorCopy() { 1441 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis())); 1442 } 1443 1444 1450 public LocalTime roundHalfCeilingCopy() { 1451 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis())); 1452 } 1453 1454 1461 public LocalTime roundHalfEvenCopy() { 1462 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis())); 1463 } 1464 } 1465 1466} 1467 | Popular Tags |