001 /* 002 * Copyright 2001-2013 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.IOException; 019 import java.io.ObjectInputStream; 020 import java.io.ObjectOutputStream; 021 import java.io.Serializable; 022 import java.util.Calendar; 023 import java.util.Date; 024 import java.util.GregorianCalendar; 025 import java.util.Locale; 026 import java.util.TimeZone; 027 028 import org.joda.convert.FromString; 029 import org.joda.convert.ToString; 030 import org.joda.time.base.BaseLocal; 031 import org.joda.time.chrono.ISOChronology; 032 import org.joda.time.convert.ConverterManager; 033 import org.joda.time.convert.PartialConverter; 034 import org.joda.time.field.AbstractReadableInstantFieldProperty; 035 import org.joda.time.format.DateTimeFormat; 036 import org.joda.time.format.DateTimeFormatter; 037 import org.joda.time.format.ISODateTimeFormat; 038 039 /** 040 * LocalDateTime is an unmodifiable datetime class representing a 041 * datetime without a time zone. 042 * <p> 043 * LocalDateTime implements the {@link ReadablePartial} interface. 044 * To do this, certain methods focus on key fields Year, MonthOfYear, 045 * DayOfYear and MillisOfDay. 046 * However, <b>all</b> fields may in fact be queried. 047 * <p> 048 * Internally, LocalDateTime uses a single millisecond-based value to 049 * represent the local datetime. This value is only used internally and 050 * is not exposed to applications. 051 * <p> 052 * Calculations on LocalDateTime are performed using a {@link Chronology}. 053 * This chronology will be set internally to be in the UTC time zone 054 * for all calculations. 055 * 056 * <p>Each individual field can be queried in two ways: 057 * <ul> 058 * <li><code>getHourOfDay()</code> 059 * <li><code>hourOfDay().get()</code> 060 * </ul> 061 * The second technique also provides access to other useful methods on the 062 * field: 063 * <ul> 064 * <li>numeric value 065 * <li>text value 066 * <li>short text value 067 * <li>maximum/minimum values 068 * <li>add/subtract 069 * <li>set 070 * <li>rounding 071 * </ul> 072 * 073 * <p> 074 * LocalDateTime is thread-safe and immutable, provided that the Chronology is as well. 075 * All standard Chronology classes supplied are thread-safe and immutable. 076 * 077 * @author Stephen Colebourne 078 * @since 1.3 079 */ 080 public final class LocalDateTime 081 extends BaseLocal 082 implements ReadablePartial, Serializable { 083 084 /** Serialization lock */ 085 private static final long serialVersionUID = -268716875315837168L; 086 087 /** The index of the year field in the field array */ 088 private static final int YEAR = 0; 089 /** The index of the monthOfYear field in the field array */ 090 private static final int MONTH_OF_YEAR = 1; 091 /** The index of the dayOfMonth field in the field array */ 092 private static final int DAY_OF_MONTH = 2; 093 /** The index of the millis field in the field array */ 094 private static final int MILLIS_OF_DAY = 3; 095 096 /** The local millis from 1970-01-01T00:00:00 */ 097 private final long iLocalMillis; 098 /** The chronology to use in UTC */ 099 private final Chronology iChronology; 100 101 //----------------------------------------------------------------------- 102 /** 103 * Obtains a {@code LocalDateTime} set to the current system millisecond time 104 * using <code>ISOChronology</code> in the default time zone. 105 * The resulting object does not use the zone. 106 * 107 * @return the current date, not null 108 * @since 2.0 109 */ 110 public static LocalDateTime now() { 111 return new LocalDateTime(); 112 } 113 114 /** 115 * Obtains a {@code LocalDateTime} set to the current system millisecond time 116 * using <code>ISOChronology</code> in the specified time zone. 117 * The resulting object does not use the zone. 118 * 119 * @param zone the time zone, not null 120 * @return the current date, not null 121 * @since 2.0 122 */ 123 public static LocalDateTime now(DateTimeZone zone) { 124 if (zone == null) { 125 throw new NullPointerException("Zone must not be null"); 126 } 127 return new LocalDateTime(zone); 128 } 129 130 /** 131 * Obtains a {@code LocalDateTime} set to the current system millisecond time 132 * using the specified chronology. 133 * The resulting object does not use the zone. 134 * 135 * @param chronology the chronology, not null 136 * @return the current date, not null 137 * @since 2.0 138 */ 139 public static LocalDateTime now(Chronology chronology) { 140 if (chronology == null) { 141 throw new NullPointerException("Chronology must not be null"); 142 } 143 return new LocalDateTime(chronology); 144 } 145 146 //----------------------------------------------------------------------- 147 /** 148 * Parses a {@code LocalDateTime} from the specified string. 149 * <p> 150 * This uses {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 151 * 152 * @param str the string to parse, not null 153 * @since 2.0 154 */ 155 @FromString 156 public static LocalDateTime parse(String str) { 157 return parse(str, ISODateTimeFormat.localDateOptionalTimeParser()); 158 } 159 160 /** 161 * Parses a {@code LocalDateTime} from the specified string using a formatter. 162 * 163 * @param str the string to parse, not null 164 * @param formatter the formatter to use, not null 165 * @since 2.0 166 */ 167 public static LocalDateTime parse(String str, DateTimeFormatter formatter) { 168 return formatter.parseLocalDateTime(str); 169 } 170 171 //----------------------------------------------------------------------- 172 /** 173 * Constructs a LocalDateTime from a <code>java.util.Calendar</code> 174 * using exactly the same field values. 175 * <p> 176 * Each field is queried from the Calendar and assigned to the LocalDateTime. 177 * This is useful if you have been using the Calendar as a local date, 178 * ignoring the zone. 179 * <p> 180 * One advantage of this method is that this method is unaffected if the 181 * version of the time zone data differs between the JDK and Joda-Time. 182 * That is because the local field values are transferred, calculated using 183 * the JDK time zone data and without using the Joda-Time time zone data. 184 * <p> 185 * This factory method ignores the type of the calendar and always 186 * creates a LocalDateTime with ISO chronology. It is expected that you 187 * will only pass in instances of <code>GregorianCalendar</code> however 188 * this is not validated. 189 * 190 * @param calendar the Calendar to extract fields from, not null 191 * @return the created local date-time, not null 192 * @throws IllegalArgumentException if the calendar is null 193 * @throws IllegalArgumentException if the date is invalid for the ISO chronology 194 */ 195 public static LocalDateTime fromCalendarFields(Calendar calendar) { 196 if (calendar == null) { 197 throw new IllegalArgumentException("The calendar must not be null"); 198 } 199 int era = calendar.get(Calendar.ERA); 200 int yearOfEra = calendar.get(Calendar.YEAR); 201 return new LocalDateTime( 202 (era == GregorianCalendar.AD ? yearOfEra : 1 - yearOfEra), 203 calendar.get(Calendar.MONTH) + 1, 204 calendar.get(Calendar.DAY_OF_MONTH), 205 calendar.get(Calendar.HOUR_OF_DAY), 206 calendar.get(Calendar.MINUTE), 207 calendar.get(Calendar.SECOND), 208 calendar.get(Calendar.MILLISECOND) 209 ); 210 } 211 212 /** 213 * Constructs a LocalDateTime from a <code>java.util.Date</code> 214 * using exactly the same field values. 215 * <p> 216 * Each field is queried from the Date and assigned to the LocalDateTime. 217 * This is useful if you have been using the Date as a local date, 218 * ignoring the zone. 219 * <p> 220 * One advantage of this method is that this method is unaffected if the 221 * version of the time zone data differs between the JDK and Joda-Time. 222 * That is because the local field values are transferred, calculated using 223 * the JDK time zone data and without using the Joda-Time time zone data. 224 * <p> 225 * This factory method always creates a LocalDateTime with ISO chronology. 226 * 227 * @param date the Date to extract fields from, not null 228 * @return the created local date-time, not null 229 * @throws IllegalArgumentException if the calendar is null 230 * @throws IllegalArgumentException if the date is invalid for the ISO chronology 231 */ 232 @SuppressWarnings("deprecation") 233 public static LocalDateTime fromDateFields(Date date) { 234 if (date == null) { 235 throw new IllegalArgumentException("The date must not be null"); 236 } 237 if (date.getTime() < 0) { 238 // handle years in era BC 239 GregorianCalendar cal = new GregorianCalendar(); 240 cal.setTime(date); 241 return fromCalendarFields(cal); 242 } 243 return new LocalDateTime( 244 date.getYear() + 1900, 245 date.getMonth() + 1, 246 date.getDate(), 247 date.getHours(), 248 date.getMinutes(), 249 date.getSeconds(), 250 (((int) (date.getTime() % 1000)) + 1000) % 1000 251 ); 252 } 253 254 //----------------------------------------------------------------------- 255 /** 256 * Constructs an instance set to the current local time evaluated using 257 * ISO chronology in the default zone. 258 * <p> 259 * Once the constructor is completed, the zone is no longer used. 260 * 261 * @see #now() 262 */ 263 public LocalDateTime() { 264 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance()); 265 } 266 267 /** 268 * Constructs an instance set to the current local time evaluated using 269 * ISO chronology in the specified zone. 270 * <p> 271 * If the specified time zone is null, the default zone is used. 272 * Once the constructor is completed, the zone is no longer used. 273 * 274 * @param zone the time zone, null means default zone 275 * @see #now(DateTimeZone) 276 */ 277 public LocalDateTime(DateTimeZone zone) { 278 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone)); 279 } 280 281 /** 282 * Constructs an instance set to the current local time evaluated using 283 * specified chronology. 284 * <p> 285 * If the chronology is null, ISO chronology in the default time zone is used. 286 * Once the constructor is completed, the zone is no longer used. 287 * 288 * @param chronology the chronology, null means ISOChronology in default zone 289 * @see #now(Chronology) 290 */ 291 public LocalDateTime(Chronology chronology) { 292 this(DateTimeUtils.currentTimeMillis(), chronology); 293 } 294 295 //----------------------------------------------------------------------- 296 /** 297 * Constructs an instance set to the local time defined by the specified 298 * instant evaluated using ISO chronology in the default zone. 299 * <p> 300 * Once the constructor is completed, the zone is no longer used. 301 * 302 * @param instant the milliseconds from 1970-01-01T00:00:00Z 303 */ 304 public LocalDateTime(long instant) { 305 this(instant, ISOChronology.getInstance()); 306 } 307 308 /** 309 * Constructs an instance set to the local time defined by the specified 310 * instant evaluated using ISO chronology in the specified zone. 311 * <p> 312 * If the specified time zone is null, the default zone is used. 313 * Once the constructor is completed, the zone is no longer used. 314 * 315 * @param instant the milliseconds from 1970-01-01T00:00:00Z 316 * @param zone the time zone, null means default zone 317 */ 318 public LocalDateTime(long instant, DateTimeZone zone) { 319 this(instant, ISOChronology.getInstance(zone)); 320 } 321 322 /** 323 * Constructs an instance set to the local time defined by the specified 324 * instant evaluated using the specified chronology. 325 * <p> 326 * If the chronology is null, ISO chronology in the default zone is used. 327 * Once the constructor is completed, the zone is no longer used. 328 * 329 * @param instant the milliseconds from 1970-01-01T00:00:00Z 330 * @param chronology the chronology, null means ISOChronology in default zone 331 */ 332 public LocalDateTime(long instant, Chronology chronology) { 333 chronology = DateTimeUtils.getChronology(chronology); 334 335 long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant); 336 iLocalMillis = localMillis; 337 iChronology = chronology.withUTC(); 338 } 339 340 //----------------------------------------------------------------------- 341 /** 342 * Constructs an instance from an Object that represents a datetime. 343 * <p> 344 * If the object contains no chronology, <code>ISOChronology</code> is used. 345 * If the object contains no time zone, the default zone is used. 346 * Once the constructor is completed, the zone is no longer used. 347 * <p> 348 * The recognised object types are defined in 349 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 350 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 351 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 352 * The default String converter ignores the zone and only parses the field values. 353 * 354 * @param instant the datetime object 355 * @throws IllegalArgumentException if the instant is invalid 356 */ 357 public LocalDateTime(Object instant) { 358 this(instant, (Chronology) null); 359 } 360 361 /** 362 * Constructs an instance from an Object that represents a datetime, 363 * forcing the time zone to that specified. 364 * <p> 365 * If the object contains no chronology, <code>ISOChronology</code> is used. 366 * If the specified time zone is null, the default zone is used. 367 * Once the constructor is completed, the zone is no longer used. 368 * <p> 369 * The recognised object types are defined in 370 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 371 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 372 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 373 * The default String converter ignores the zone and only parses the field values. 374 * 375 * @param instant the datetime object 376 * @param zone the time zone 377 * @throws IllegalArgumentException if the instant is invalid 378 */ 379 public LocalDateTime(Object instant, DateTimeZone zone) { 380 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 381 Chronology chronology = converter.getChronology(instant, zone); 382 chronology = DateTimeUtils.getChronology(chronology); 383 iChronology = chronology.withUTC(); 384 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser()); 385 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]); 386 } 387 388 /** 389 * Constructs an instance from an Object that represents a datetime, 390 * using the specified chronology. 391 * <p> 392 * If the chronology is null, ISO in the default time zone is used. 393 * Once the constructor is completed, the zone is no longer used. 394 * If the instant contains a chronology, it will be ignored. 395 * For example, passing a {@code LocalDate} and a different chronology 396 * will return a date with the year/month/day from the date applied 397 * unaltered to the specified chronology. 398 * <p> 399 * The recognised object types are defined in 400 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 401 * include ReadablePartial, ReadableInstant, String, Calendar and Date. 402 * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}. 403 * The default String converter ignores the zone and only parses the field values. 404 * 405 * @param instant the datetime object 406 * @param chronology the chronology 407 * @throws IllegalArgumentException if the instant is invalid 408 */ 409 public LocalDateTime(Object instant, Chronology chronology) { 410 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant); 411 chronology = converter.getChronology(instant, chronology); 412 chronology = DateTimeUtils.getChronology(chronology); 413 iChronology = chronology.withUTC(); 414 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser()); 415 iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]); 416 } 417 418 //----------------------------------------------------------------------- 419 /** 420 * Constructs an instance set to the specified date and time 421 * using <code>ISOChronology</code>. 422 * 423 * @param year the year 424 * @param monthOfYear the month of the year, from 1 to 12 425 * @param dayOfMonth the day of the month, from 1 to 31 426 * @param hourOfDay the hour of the day, from 0 to 23 427 * @param minuteOfHour the minute of the hour, from 0 to 59 428 */ 429 public LocalDateTime( 430 int year, 431 int monthOfYear, 432 int dayOfMonth, 433 int hourOfDay, 434 int minuteOfHour) { 435 this(year, monthOfYear, dayOfMonth, hourOfDay, 436 minuteOfHour, 0, 0, ISOChronology.getInstanceUTC()); 437 } 438 439 /** 440 * Constructs an instance set to the specified date and time 441 * using <code>ISOChronology</code>. 442 * 443 * @param year the year 444 * @param monthOfYear the month of the year, from 1 to 12 445 * @param dayOfMonth the day of the month, from 1 to 31 446 * @param hourOfDay the hour of the day, from 0 to 23 447 * @param minuteOfHour the minute of the hour, from 0 to 59 448 * @param secondOfMinute the second of the minute, from 0 to 59 449 */ 450 public LocalDateTime( 451 int year, 452 int monthOfYear, 453 int dayOfMonth, 454 int hourOfDay, 455 int minuteOfHour, 456 int secondOfMinute) { 457 this(year, monthOfYear, dayOfMonth, hourOfDay, 458 minuteOfHour, secondOfMinute, 0, ISOChronology.getInstanceUTC()); 459 } 460 461 /** 462 * Constructs an instance set to the specified date and time 463 * using <code>ISOChronology</code>. 464 * 465 * @param year the year 466 * @param monthOfYear the month of the year, from 1 to 12 467 * @param dayOfMonth the day of the month, from 1 to 31 468 * @param hourOfDay the hour of the day, from 0 to 23 469 * @param minuteOfHour the minute of the hour, from 0 to 59 470 * @param secondOfMinute the second of the minute, from 0 to 59 471 * @param millisOfSecond the millisecond of the second, from 0 to 999 472 */ 473 public LocalDateTime( 474 int year, 475 int monthOfYear, 476 int dayOfMonth, 477 int hourOfDay, 478 int minuteOfHour, 479 int secondOfMinute, 480 int millisOfSecond) { 481 this(year, monthOfYear, dayOfMonth, hourOfDay, 482 minuteOfHour, secondOfMinute, millisOfSecond, ISOChronology.getInstanceUTC()); 483 } 484 485 /** 486 * Constructs an instance set to the specified date and time 487 * using the specified chronology, whose zone is ignored. 488 * <p> 489 * If the chronology is null, <code>ISOChronology</code> is used. 490 * 491 * @param year the year, valid values defined by the chronology 492 * @param monthOfYear the month of the year, valid values defined by the chronology 493 * @param dayOfMonth the day of the month, valid values defined by the chronology 494 * @param hourOfDay the hour of the day, valid values defined by the chronology 495 * @param minuteOfHour the minute of the hour, valid values defined by the chronology 496 * @param secondOfMinute the second of the minute, valid values defined by the chronology 497 * @param millisOfSecond the millisecond of the second, valid values defined by the chronology 498 * @param chronology the chronology, null means ISOChronology in default zone 499 */ 500 public LocalDateTime( 501 int year, 502 int monthOfYear, 503 int dayOfMonth, 504 int hourOfDay, 505 int minuteOfHour, 506 int secondOfMinute, 507 int millisOfSecond, 508 Chronology chronology) { 509 super(); 510 chronology = DateTimeUtils.getChronology(chronology).withUTC(); 511 long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, 512 hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond); 513 iChronology = chronology; 514 iLocalMillis = instant; 515 } 516 517 /** 518 * Handle broken serialization from other tools. 519 * @return the resolved object, not null 520 */ 521 private Object readResolve() { 522 if (iChronology == null) { 523 return new LocalDateTime(iLocalMillis, ISOChronology.getInstanceUTC()); 524 } 525 if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) { 526 return new LocalDateTime(iLocalMillis, iChronology.withUTC()); 527 } 528 return this; 529 } 530 531 //----------------------------------------------------------------------- 532 /** 533 * Gets the number of fields in this partial, which is four. 534 * The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 535 * 536 * @return the field count, four 537 */ 538 public int size() { 539 return 4; 540 } 541 542 /** 543 * Gets the field for a specific index in the chronology specified. 544 * <p> 545 * This method must not use any instance variables. 546 * 547 * @param index the index to retrieve 548 * @param chrono the chronology to use 549 * @return the field 550 */ 551 protected DateTimeField getField(int index, Chronology chrono) { 552 switch (index) { 553 case YEAR: 554 return chrono.year(); 555 case MONTH_OF_YEAR: 556 return chrono.monthOfYear(); 557 case DAY_OF_MONTH: 558 return chrono.dayOfMonth(); 559 case MILLIS_OF_DAY: 560 return chrono.millisOfDay(); 561 default: 562 throw new IndexOutOfBoundsException("Invalid index: " + index); 563 } 564 } 565 566 /** 567 * Gets the value of the field at the specifed index. 568 * <p> 569 * This method is required to support the <code>ReadablePartial</code> 570 * interface. The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay. 571 * 572 * @param index the index, zero to two 573 * @return the value 574 * @throws IndexOutOfBoundsException if the index is invalid 575 */ 576 public int getValue(int index) { 577 switch (index) { 578 case YEAR: 579 return getChronology().year().get(getLocalMillis()); 580 case MONTH_OF_YEAR: 581 return getChronology().monthOfYear().get(getLocalMillis()); 582 case DAY_OF_MONTH: 583 return getChronology().dayOfMonth().get(getLocalMillis()); 584 case MILLIS_OF_DAY: 585 return getChronology().millisOfDay().get(getLocalMillis()); 586 default: 587 throw new IndexOutOfBoundsException("Invalid index: " + index); 588 } 589 } 590 591 //----------------------------------------------------------------------- 592 /** 593 * Get the value of one of the fields of a datetime. 594 * <p> 595 * This method gets the value of the specified field. 596 * For example: 597 * <pre> 598 * DateTime dt = new DateTime(); 599 * int year = dt.get(DateTimeFieldType.year()); 600 * </pre> 601 * 602 * @param type a field type, usually obtained from DateTimeFieldType, not null 603 * @return the value of that field 604 * @throws IllegalArgumentException if the field type is null 605 */ 606 public int get(DateTimeFieldType type) { 607 if (type == null) { 608 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 609 } 610 return type.getField(getChronology()).get(getLocalMillis()); 611 } 612 613 /** 614 * Checks if the field type specified is supported by this 615 * local datetime and chronology. 616 * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}. 617 * 618 * @param type a field type, usually obtained from DateTimeFieldType 619 * @return true if the field type is supported 620 */ 621 public boolean isSupported(DateTimeFieldType type) { 622 if (type == null) { 623 return false; 624 } 625 return type.getField(getChronology()).isSupported(); 626 } 627 628 /** 629 * Checks if the duration type specified is supported by this 630 * local datetime and chronology. 631 * 632 * @param type a duration type, usually obtained from DurationFieldType 633 * @return true if the field type is supported 634 */ 635 public boolean isSupported(DurationFieldType type) { 636 if (type == null) { 637 return false; 638 } 639 return type.getField(getChronology()).isSupported(); 640 } 641 642 //----------------------------------------------------------------------- 643 /** 644 * Gets the milliseconds of the datetime instant from the Java epoch 645 * of 1970-01-01T00:00:00 (not fixed to any specific time zone). 646 * 647 * @return the number of milliseconds since 1970-01-01T00:00:00 648 * @since 1.5 (previously private) 649 */ 650 protected long getLocalMillis() { 651 return iLocalMillis; 652 } 653 654 /** 655 * Gets the chronology of the datetime. 656 * 657 * @return the Chronology that the datetime is using 658 */ 659 public Chronology getChronology() { 660 return iChronology; 661 } 662 663 //----------------------------------------------------------------------- 664 /** 665 * Compares this ReadablePartial with another returning true if the chronology, 666 * field types and values are equal. 667 * 668 * @param partial an object to check against 669 * @return true if fields and values are equal 670 */ 671 public boolean equals(Object partial) { 672 // override to perform faster 673 if (this == partial) { 674 return true; 675 } 676 if (partial instanceof LocalDateTime) { 677 LocalDateTime other = (LocalDateTime) partial; 678 if (iChronology.equals(other.iChronology)) { 679 return iLocalMillis == other.iLocalMillis; 680 } 681 } 682 return super.equals(partial); 683 } 684 685 /** 686 * Compares this partial with another returning an integer 687 * indicating the order. 688 * <p> 689 * The fields are compared in order, from largest to smallest. 690 * The first field that is non-equal is used to determine the result. 691 * <p> 692 * The specified object must be a partial instance whose field types 693 * match those of this partial. 694 * 695 * @param partial an object to check against 696 * @return negative if this is less, zero if equal, positive if greater 697 * @throws ClassCastException if the partial is the wrong class 698 * or if it has field types that don't match 699 * @throws NullPointerException if the partial is null 700 */ 701 public int compareTo(ReadablePartial partial) { 702 // override to perform faster 703 if (this == partial) { 704 return 0; 705 } 706 if (partial instanceof LocalDateTime) { 707 LocalDateTime other = (LocalDateTime) partial; 708 if (iChronology.equals(other.iChronology)) { 709 return (iLocalMillis < other.iLocalMillis ? -1 : 710 (iLocalMillis == other.iLocalMillis ? 0 : 1)); 711 712 } 713 } 714 return super.compareTo(partial); 715 } 716 717 //----------------------------------------------------------------------- 718 /** 719 * Converts this object to a DateTime using the default zone. 720 * <p> 721 * This method will throw an exception if the datetime that would be 722 * created does not exist when the time zone is taken into account. 723 * 724 * @return <code>this</code> 725 */ 726 public DateTime toDateTime() { 727 return toDateTime((DateTimeZone) null); 728 } 729 730 /** 731 * Converts this object to a DateTime using the specified zone. 732 * <p> 733 * This method will throw an exception if the datetime that would be 734 * created does not exist when the time zone is taken into account. 735 * 736 * @param zone time zone to apply, or default if null 737 * @return a DateTime using the same millis 738 */ 739 public DateTime toDateTime(DateTimeZone zone) { 740 zone = DateTimeUtils.getZone(zone); 741 Chronology chrono = iChronology.withZone(zone); 742 return new DateTime( 743 getYear(), getMonthOfYear(), getDayOfMonth(), 744 getHourOfDay(), getMinuteOfHour(), 745 getSecondOfMinute(), getMillisOfSecond(), chrono); 746 } 747 748 //----------------------------------------------------------------------- 749 /** 750 * Converts this object to a LocalDate with the same date and chronology. 751 * 752 * @return a LocalDate with the same date and chronology 753 */ 754 public LocalDate toLocalDate() { 755 return new LocalDate(getLocalMillis(), getChronology()); 756 } 757 758 /** 759 * Converts this object to a LocalTime with the same time and chronology. 760 * 761 * @return a LocalTime with the same time and chronology 762 */ 763 public LocalTime toLocalTime() { 764 return new LocalTime(getLocalMillis(), getChronology()); 765 } 766 767 //----------------------------------------------------------------------- 768 /** 769 * Get the date time as a <code>java.util.Date</code>. 770 * <p> 771 * The <code>Date</code> object created has exactly the same fields as this 772 * date-time, except when the time would be invalid due to a daylight savings 773 * gap. In that case, the time will be set to the earliest valid time after the gap. 774 * <p> 775 * In the case of a daylight savings overlap, the earlier instant is selected. 776 * <p> 777 * Converting to a JDK Date is full of complications as the JDK Date constructor 778 * doesn't behave as you might expect around DST transitions. This method works 779 * by taking a first guess and then adjusting. This also handles the situation 780 * where the JDK time zone data differs from the Joda-Time time zone data. 781 * 782 * @return a Date initialised with this date-time, never null 783 * @since 2.0 784 */ 785 @SuppressWarnings("deprecation") 786 public Date toDate() { 787 int dom = getDayOfMonth(); 788 Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom, 789 getHourOfDay(), getMinuteOfHour(), getSecondOfMinute()); 790 date.setTime(date.getTime() + getMillisOfSecond()); 791 LocalDateTime check = LocalDateTime.fromDateFields(date); 792 if (check.isBefore(this)) { 793 // DST gap 794 // move forward in units of one minute until equal/after 795 while (check.isBefore(this)) { 796 date.setTime(date.getTime() + 60000); 797 check = LocalDateTime.fromDateFields(date); 798 } 799 // move back in units of one second until date wrong 800 while (check.isBefore(this) == false) { 801 date.setTime(date.getTime() - 1000); 802 check = LocalDateTime.fromDateFields(date); 803 } 804 date.setTime(date.getTime() + 1000); 805 } else if (check.equals(this)) { 806 // check for DST overlap 807 Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings()); 808 check = LocalDateTime.fromDateFields(earlier); 809 if (check.equals(this)) { 810 date = earlier; 811 } 812 } 813 return date; 814 } 815 816 //----------------------------------------------------------------------- 817 /** 818 * Returns a copy of this datetime with different local millis. 819 * <p> 820 * The returned object will be a new instance of the same type. 821 * Only the millis will change, the chronology is kept. 822 * The returned object will be either be a new instance or <code>this</code>. 823 * 824 * @param newMillis the new millis, from 1970-01-01T00:00:00 825 * @return a copy of this datetime with different millis 826 */ 827 LocalDateTime withLocalMillis(long newMillis) { 828 return (newMillis == getLocalMillis() ? this : new LocalDateTime(newMillis, getChronology())); 829 } 830 831 //----------------------------------------------------------------------- 832 /** 833 * Returns a copy of this datetime with the specified date, 834 * retaining the time fields. 835 * <p> 836 * If the date is already the date passed in, then <code>this</code> is returned. 837 * <p> 838 * To set a single field use the properties, for example: 839 * <pre> 840 * DateTime set = dt.monthOfYear().setCopy(6); 841 * </pre> 842 * 843 * @param year the new year value 844 * @param monthOfYear the new monthOfYear value 845 * @param dayOfMonth the new dayOfMonth value 846 * @return a copy of this datetime with a different date 847 * @throws IllegalArgumentException if any value if invalid 848 */ 849 public LocalDateTime withDate(int year, int monthOfYear, int dayOfMonth) { 850 Chronology chrono = getChronology(); 851 long instant = getLocalMillis(); 852 instant = chrono.year().set(instant, year); 853 instant = chrono.monthOfYear().set(instant, monthOfYear); 854 instant = chrono.dayOfMonth().set(instant, dayOfMonth); 855 return withLocalMillis(instant); 856 } 857 858 /** 859 * Returns a copy of this datetime with the specified time, 860 * retaining the date fields. 861 * <p> 862 * If the time is already the time passed in, then <code>this</code> is returned. 863 * <p> 864 * To set a single field use the properties, for example: 865 * <pre> 866 * LocalDateTime set = dt.hourOfDay().setCopy(6); 867 * </pre> 868 * 869 * @param hourOfDay the hour of the day 870 * @param minuteOfHour the minute of the hour 871 * @param secondOfMinute the second of the minute 872 * @param millisOfSecond the millisecond of the second 873 * @return a copy of this datetime with a different time 874 * @throws IllegalArgumentException if any value if invalid 875 */ 876 public LocalDateTime withTime(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) { 877 Chronology chrono = getChronology(); 878 long instant = getLocalMillis(); 879 instant = chrono.hourOfDay().set(instant, hourOfDay); 880 instant = chrono.minuteOfHour().set(instant, minuteOfHour); 881 instant = chrono.secondOfMinute().set(instant, secondOfMinute); 882 instant = chrono.millisOfSecond().set(instant, millisOfSecond); 883 return withLocalMillis(instant); 884 } 885 886 //----------------------------------------------------------------------- 887 /** 888 * Returns a copy of this datetime with the partial set of fields 889 * replacing those from this instance. 890 * <p> 891 * For example, if the partial is a <code>TimeOfDay</code> then the time fields 892 * would be changed in the returned instance. 893 * If the partial is null, then <code>this</code> is returned. 894 * 895 * @param partial the partial set of fields to apply to this datetime, null ignored 896 * @return a copy of this datetime with a different set of fields 897 * @throws IllegalArgumentException if any value is invalid 898 */ 899 public LocalDateTime withFields(ReadablePartial partial) { 900 if (partial == null) { 901 return this; 902 } 903 return withLocalMillis(getChronology().set(partial, getLocalMillis())); 904 } 905 906 /** 907 * Returns a copy of this datetime with the specified field set to a new value. 908 * <p> 909 * For example, if the field type is <code>hourOfDay</code> then the hour of day 910 * field would be changed in the returned instance. 911 * If the field type is null, then <code>this</code> is returned. 912 * <p> 913 * These three lines are equivalent: 914 * <pre> 915 * LocalDateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6); 916 * LocalDateTime updated = dt.dayOfMonth().setCopy(6); 917 * LocalDateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6); 918 * </pre> 919 * 920 * @param fieldType the field type to set, not null 921 * @param value the value to set 922 * @return a copy of this datetime with the field set 923 * @throws IllegalArgumentException if the value is null or invalid 924 */ 925 public LocalDateTime withField(DateTimeFieldType fieldType, int value) { 926 if (fieldType == null) { 927 throw new IllegalArgumentException("Field must not be null"); 928 } 929 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value); 930 return withLocalMillis(instant); 931 } 932 933 /** 934 * Returns a copy of this datetime with the value of the specified 935 * field increased. 936 * <p> 937 * If the addition is zero or the field is null, then <code>this</code> is returned. 938 * <p> 939 * These three lines are equivalent: 940 * <pre> 941 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 942 * LocalDateTime added = dt.plusYears(6); 943 * LocalDateTime added = dt.plus(Period.years(6)); 944 * </pre> 945 * 946 * @param fieldType the field type to add to, not null 947 * @param amount the amount to add 948 * @return a copy of this datetime with the field updated 949 * @throws IllegalArgumentException if the value is null or invalid 950 * @throws ArithmeticException if the result exceeds the internal capacity 951 */ 952 public LocalDateTime withFieldAdded(DurationFieldType fieldType, int amount) { 953 if (fieldType == null) { 954 throw new IllegalArgumentException("Field must not be null"); 955 } 956 if (amount == 0) { 957 return this; 958 } 959 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount); 960 return withLocalMillis(instant); 961 } 962 963 //----------------------------------------------------------------------- 964 /** 965 * Returns a copy of this datetime with the specified duration added. 966 * <p> 967 * If the addition is zero, then <code>this</code> is returned. 968 * 969 * @param durationToAdd the duration to add to this one, null means zero 970 * @param scalar the amount of times to add, such as -1 to subtract once 971 * @return a copy of this datetime with the duration added 972 * @throws ArithmeticException if the result exceeds the internal capacity 973 */ 974 public LocalDateTime withDurationAdded(ReadableDuration durationToAdd, int scalar) { 975 if (durationToAdd == null || scalar == 0) { 976 return this; 977 } 978 long instant = getChronology().add(getLocalMillis(), durationToAdd.getMillis(), scalar); 979 return withLocalMillis(instant); 980 } 981 982 /** 983 * Returns a copy of this datetime with the specified period added. 984 * <p> 985 * If the addition is zero, then <code>this</code> is returned. 986 * <p> 987 * This method is typically used to add multiple copies of complex 988 * period instances. Adding one field is best achieved using methods 989 * like {@link #withFieldAdded(DurationFieldType, int)} 990 * or {@link #plusYears(int)}. 991 * 992 * @param period the period to add to this one, null means zero 993 * @param scalar the amount of times to add, such as -1 to subtract once 994 * @return a copy of this datetime with the period added 995 * @throws ArithmeticException if the result exceeds the internal capacity 996 */ 997 public LocalDateTime withPeriodAdded(ReadablePeriod period, int scalar) { 998 if (period == null || scalar == 0) { 999 return this; 1000 } 1001 long instant = getChronology().add(period, getLocalMillis(), scalar); 1002 return withLocalMillis(instant); 1003 } 1004 1005 //----------------------------------------------------------------------- 1006 /** 1007 * Returns a copy of this datetime with the specified duration added. 1008 * <p> 1009 * If the amount is zero or null, then <code>this</code> is returned. 1010 * 1011 * @param duration the duration to add to this one, null means zero 1012 * @return a copy of this datetime with the duration added 1013 * @throws ArithmeticException if the result exceeds the internal capacity 1014 */ 1015 public LocalDateTime plus(ReadableDuration duration) { 1016 return withDurationAdded(duration, 1); 1017 } 1018 1019 /** 1020 * Returns a copy of this datetime with the specified period added. 1021 * <p> 1022 * If the amount is zero or null, then <code>this</code> is returned. 1023 * <p> 1024 * This method is typically used to add complex period instances. 1025 * Adding one field is best achieved using methods 1026 * like {@link #plusYears(int)}. 1027 * 1028 * @param period the period to add to this one, null means zero 1029 * @return a copy of this datetime with the period added 1030 * @throws ArithmeticException if the result exceeds the internal capacity 1031 */ 1032 public LocalDateTime plus(ReadablePeriod period) { 1033 return withPeriodAdded(period, 1); 1034 } 1035 1036 //----------------------------------------------------------------------- 1037 /** 1038 * Returns a copy of this datetime plus the specified number of years. 1039 * <p> 1040 * This LocalDateTime instance is immutable and unaffected by this method call. 1041 * <p> 1042 * The following three lines are identical in effect: 1043 * <pre> 1044 * LocalDateTime added = dt.plusYears(6); 1045 * LocalDateTime added = dt.plus(Period.years(6)); 1046 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6); 1047 * </pre> 1048 * 1049 * @param years the amount of years to add, may be negative 1050 * @return the new LocalDateTime plus the increased years 1051 */ 1052 public LocalDateTime plusYears(int years) { 1053 if (years == 0) { 1054 return this; 1055 } 1056 long instant = getChronology().years().add(getLocalMillis(), years); 1057 return withLocalMillis(instant); 1058 } 1059 1060 /** 1061 * Returns a copy of this datetime plus the specified number of months. 1062 * <p> 1063 * This LocalDateTime instance is immutable and unaffected by this method call. 1064 * <p> 1065 * The following three lines are identical in effect: 1066 * <pre> 1067 * LocalDateTime added = dt.plusMonths(6); 1068 * LocalDateTime added = dt.plus(Period.months(6)); 1069 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.months(), 6); 1070 * </pre> 1071 * 1072 * @param months the amount of months to add, may be negative 1073 * @return the new LocalDateTime plus the increased months 1074 */ 1075 public LocalDateTime plusMonths(int months) { 1076 if (months == 0) { 1077 return this; 1078 } 1079 long instant = getChronology().months().add(getLocalMillis(), months); 1080 return withLocalMillis(instant); 1081 } 1082 1083 /** 1084 * Returns a copy of this datetime plus the specified number of weeks. 1085 * <p> 1086 * This LocalDateTime instance is immutable and unaffected by this method call. 1087 * <p> 1088 * The following three lines are identical in effect: 1089 * <pre> 1090 * LocalDateTime added = dt.plusWeeks(6); 1091 * LocalDateTime added = dt.plus(Period.weeks(6)); 1092 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.weeks(), 6); 1093 * </pre> 1094 * 1095 * @param weeks the amount of weeks to add, may be negative 1096 * @return the new LocalDateTime plus the increased weeks 1097 */ 1098 public LocalDateTime plusWeeks(int weeks) { 1099 if (weeks == 0) { 1100 return this; 1101 } 1102 long instant = getChronology().weeks().add(getLocalMillis(), weeks); 1103 return withLocalMillis(instant); 1104 } 1105 1106 /** 1107 * Returns a copy of this datetime plus the specified number of days. 1108 * <p> 1109 * This LocalDateTime instance is immutable and unaffected by this method call. 1110 * <p> 1111 * The following three lines are identical in effect: 1112 * <pre> 1113 * LocalDateTime added = dt.plusDays(6); 1114 * LocalDateTime added = dt.plus(Period.days(6)); 1115 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.days(), 6); 1116 * </pre> 1117 * 1118 * @param days the amount of days to add, may be negative 1119 * @return the new LocalDateTime plus the increased days 1120 */ 1121 public LocalDateTime plusDays(int days) { 1122 if (days == 0) { 1123 return this; 1124 } 1125 long instant = getChronology().days().add(getLocalMillis(), days); 1126 return withLocalMillis(instant); 1127 } 1128 1129 //----------------------------------------------------------------------- 1130 /** 1131 * Returns a copy of this datetime plus the specified number of hours. 1132 * <p> 1133 * This LocalDateTime instance is immutable and unaffected by this method call. 1134 * <p> 1135 * The following three lines are identical in effect: 1136 * <pre> 1137 * LocalDateTime added = dt.plusHours(6); 1138 * LocalDateTime added = dt.plus(Period.hours(6)); 1139 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.hours(), 6); 1140 * </pre> 1141 * 1142 * @param hours the amount of hours to add, may be negative 1143 * @return the new LocalDateTime plus the increased hours 1144 */ 1145 public LocalDateTime plusHours(int hours) { 1146 if (hours == 0) { 1147 return this; 1148 } 1149 long instant = getChronology().hours().add(getLocalMillis(), hours); 1150 return withLocalMillis(instant); 1151 } 1152 1153 /** 1154 * Returns a copy of this datetime plus the specified number of minutes. 1155 * <p> 1156 * This LocalDateTime instance is immutable and unaffected by this method call. 1157 * <p> 1158 * The following three lines are identical in effect: 1159 * <pre> 1160 * LocalDateTime added = dt.plusMinutes(6); 1161 * LocalDateTime added = dt.plus(Period.minutes(6)); 1162 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6); 1163 * </pre> 1164 * 1165 * @param minutes the amount of minutes to add, may be negative 1166 * @return the new LocalDateTime plus the increased minutes 1167 */ 1168 public LocalDateTime plusMinutes(int minutes) { 1169 if (minutes == 0) { 1170 return this; 1171 } 1172 long instant = getChronology().minutes().add(getLocalMillis(), minutes); 1173 return withLocalMillis(instant); 1174 } 1175 1176 /** 1177 * Returns a copy of this datetime plus the specified number of seconds. 1178 * <p> 1179 * This LocalDateTime instance is immutable and unaffected by this method call. 1180 * <p> 1181 * The following three lines are identical in effect: 1182 * <pre> 1183 * LocalDateTime added = dt.plusSeconds(6); 1184 * LocalDateTime added = dt.plus(Period.seconds(6)); 1185 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6); 1186 * </pre> 1187 * 1188 * @param seconds the amount of seconds to add, may be negative 1189 * @return the new LocalDateTime plus the increased seconds 1190 */ 1191 public LocalDateTime plusSeconds(int seconds) { 1192 if (seconds == 0) { 1193 return this; 1194 } 1195 long instant = getChronology().seconds().add(getLocalMillis(), seconds); 1196 return withLocalMillis(instant); 1197 } 1198 1199 /** 1200 * Returns a copy of this datetime plus the specified number of millis. 1201 * <p> 1202 * This LocalDateTime instance is immutable and unaffected by this method call. 1203 * <p> 1204 * The following three lines are identical in effect: 1205 * <pre> 1206 * LocalDateTime added = dt.plusMillis(6); 1207 * LocalDateTime added = dt.plus(Period.millis(6)); 1208 * LocalDateTime added = dt.withFieldAdded(DurationFieldType.millis(), 6); 1209 * </pre> 1210 * 1211 * @param millis the amount of millis to add, may be negative 1212 * @return the new LocalDateTime plus the increased millis 1213 */ 1214 public LocalDateTime plusMillis(int millis) { 1215 if (millis == 0) { 1216 return this; 1217 } 1218 long instant = getChronology().millis().add(getLocalMillis(), millis); 1219 return withLocalMillis(instant); 1220 } 1221 1222 //----------------------------------------------------------------------- 1223 /** 1224 * Returns a copy of this datetime with the specified duration taken away. 1225 * <p> 1226 * If the amount is zero or null, then <code>this</code> is returned. 1227 * 1228 * @param duration the duration to reduce this instant by 1229 * @return a copy of this datetime with the duration taken away 1230 * @throws ArithmeticException if the result exceeds the internal capacity 1231 */ 1232 public LocalDateTime minus(ReadableDuration duration) { 1233 return withDurationAdded(duration, -1); 1234 } 1235 1236 /** 1237 * Returns a copy of this datetime with the specified period taken away. 1238 * <p> 1239 * If the amount is zero or null, then <code>this</code> is returned. 1240 * <p> 1241 * This method is typically used to subtract complex period instances. 1242 * Subtracting one field is best achieved using methods 1243 * like {@link #minusYears(int)}. 1244 * 1245 * @param period the period to reduce this instant by 1246 * @return a copy of this datetime with the period taken away 1247 * @throws ArithmeticException if the result exceeds the internal capacity 1248 */ 1249 public LocalDateTime minus(ReadablePeriod period) { 1250 return withPeriodAdded(period, -1); 1251 } 1252 1253 //----------------------------------------------------------------------- 1254 /** 1255 * Returns a copy of this datetime minus the specified number of years. 1256 * <p> 1257 * This LocalDateTime instance is immutable and unaffected by this method call. 1258 * <p> 1259 * The following three lines are identical in effect: 1260 * <pre> 1261 * LocalDateTime subtracted = dt.minusYears(6); 1262 * LocalDateTime subtracted = dt.minus(Period.years(6)); 1263 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6); 1264 * </pre> 1265 * 1266 * @param years the amount of years to subtract, may be negative 1267 * @return the new LocalDateTime minus the increased years 1268 */ 1269 public LocalDateTime minusYears(int years) { 1270 if (years == 0) { 1271 return this; 1272 } 1273 long instant = getChronology().years().subtract(getLocalMillis(), years); 1274 return withLocalMillis(instant); 1275 } 1276 1277 /** 1278 * Returns a copy of this datetime minus the specified number of months. 1279 * <p> 1280 * This LocalDateTime instance is immutable and unaffected by this method call. 1281 * <p> 1282 * The following three lines are identical in effect: 1283 * <pre> 1284 * LocalDateTime subtracted = dt.minusMonths(6); 1285 * LocalDateTime subtracted = dt.minus(Period.months(6)); 1286 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.months(), -6); 1287 * </pre> 1288 * 1289 * @param months the amount of months to subtract, may be negative 1290 * @return the new LocalDateTime minus the increased months 1291 */ 1292 public LocalDateTime minusMonths(int months) { 1293 if (months == 0) { 1294 return this; 1295 } 1296 long instant = getChronology().months().subtract(getLocalMillis(), months); 1297 return withLocalMillis(instant); 1298 } 1299 1300 /** 1301 * Returns a copy of this datetime minus the specified number of weeks. 1302 * <p> 1303 * This LocalDateTime instance is immutable and unaffected by this method call. 1304 * <p> 1305 * The following three lines are identical in effect: 1306 * <pre> 1307 * LocalDateTime subtracted = dt.minusWeeks(6); 1308 * LocalDateTime subtracted = dt.minus(Period.weeks(6)); 1309 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6); 1310 * </pre> 1311 * 1312 * @param weeks the amount of weeks to subtract, may be negative 1313 * @return the new LocalDateTime minus the increased weeks 1314 */ 1315 public LocalDateTime minusWeeks(int weeks) { 1316 if (weeks == 0) { 1317 return this; 1318 } 1319 long instant = getChronology().weeks().subtract(getLocalMillis(), weeks); 1320 return withLocalMillis(instant); 1321 } 1322 1323 /** 1324 * Returns a copy of this datetime minus the specified number of days. 1325 * <p> 1326 * This LocalDateTime instance is immutable and unaffected by this method call. 1327 * <p> 1328 * The following three lines are identical in effect: 1329 * <pre> 1330 * LocalDateTime subtracted = dt.minusDays(6); 1331 * LocalDateTime subtracted = dt.minus(Period.days(6)); 1332 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.days(), -6); 1333 * </pre> 1334 * 1335 * @param days the amount of days to subtract, may be negative 1336 * @return the new LocalDateTime minus the increased days 1337 */ 1338 public LocalDateTime minusDays(int days) { 1339 if (days == 0) { 1340 return this; 1341 } 1342 long instant = getChronology().days().subtract(getLocalMillis(), days); 1343 return withLocalMillis(instant); 1344 } 1345 1346 //----------------------------------------------------------------------- 1347 /** 1348 * Returns a copy of this datetime minus the specified number of hours. 1349 * <p> 1350 * This LocalDateTime instance is immutable and unaffected by this method call. 1351 * <p> 1352 * The following three lines are identical in effect: 1353 * <pre> 1354 * LocalDateTime subtracted = dt.minusHours(6); 1355 * LocalDateTime subtracted = dt.minus(Period.hours(6)); 1356 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6); 1357 * </pre> 1358 * 1359 * @param hours the amount of hours to subtract, may be negative 1360 * @return the new LocalDateTime minus the increased hours 1361 */ 1362 public LocalDateTime minusHours(int hours) { 1363 if (hours == 0) { 1364 return this; 1365 } 1366 long instant = getChronology().hours().subtract(getLocalMillis(), hours); 1367 return withLocalMillis(instant); 1368 } 1369 1370 /** 1371 * Returns a copy of this datetime minus the specified number of minutes. 1372 * <p> 1373 * This LocalDateTime instance is immutable and unaffected by this method call. 1374 * <p> 1375 * The following three lines are identical in effect: 1376 * <pre> 1377 * LocalDateTime subtracted = dt.minusMinutes(6); 1378 * LocalDateTime subtracted = dt.minus(Period.minutes(6)); 1379 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6); 1380 * </pre> 1381 * 1382 * @param minutes the amount of minutes to subtract, may be negative 1383 * @return the new LocalDateTime minus the increased minutes 1384 */ 1385 public LocalDateTime minusMinutes(int minutes) { 1386 if (minutes == 0) { 1387 return this; 1388 } 1389 long instant = getChronology().minutes().subtract(getLocalMillis(), minutes); 1390 return withLocalMillis(instant); 1391 } 1392 1393 /** 1394 * Returns a copy of this datetime minus the specified number of seconds. 1395 * <p> 1396 * This LocalDateTime instance is immutable and unaffected by this method call. 1397 * <p> 1398 * The following three lines are identical in effect: 1399 * <pre> 1400 * LocalDateTime subtracted = dt.minusSeconds(6); 1401 * LocalDateTime subtracted = dt.minus(Period.seconds(6)); 1402 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6); 1403 * </pre> 1404 * 1405 * @param seconds the amount of seconds to subtract, may be negative 1406 * @return the new LocalDateTime minus the increased seconds 1407 */ 1408 public LocalDateTime minusSeconds(int seconds) { 1409 if (seconds == 0) { 1410 return this; 1411 } 1412 long instant = getChronology().seconds().subtract(getLocalMillis(), seconds); 1413 return withLocalMillis(instant); 1414 } 1415 1416 /** 1417 * Returns a copy of this datetime minus the specified number of millis. 1418 * <p> 1419 * This LocalDateTime instance is immutable and unaffected by this method call. 1420 * <p> 1421 * The following three lines are identical in effect: 1422 * <pre> 1423 * LocalDateTime subtracted = dt.minusMillis(6); 1424 * LocalDateTime subtracted = dt.minus(Period.millis(6)); 1425 * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6); 1426 * </pre> 1427 * 1428 * @param millis the amount of millis to subtract, may be negative 1429 * @return the new LocalDateTime minus the increased millis 1430 */ 1431 public LocalDateTime minusMillis(int millis) { 1432 if (millis == 0) { 1433 return this; 1434 } 1435 long instant = getChronology().millis().subtract(getLocalMillis(), millis); 1436 return withLocalMillis(instant); 1437 } 1438 1439 //----------------------------------------------------------------------- 1440 /** 1441 * Gets the property object for the specified type, which contains many 1442 * useful methods. 1443 * 1444 * @param fieldType the field type to get the chronology for 1445 * @return the property object 1446 * @throws IllegalArgumentException if the field is null or unsupported 1447 */ 1448 public Property property(DateTimeFieldType fieldType) { 1449 if (fieldType == null) { 1450 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 1451 } 1452 if (isSupported(fieldType) == false) { 1453 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported"); 1454 } 1455 return new Property(this, fieldType.getField(getChronology())); 1456 } 1457 1458 //----------------------------------------------------------------------- 1459 /** 1460 * Get the era field value. 1461 * 1462 * @return the era 1463 */ 1464 public int getEra() { 1465 return getChronology().era().get(getLocalMillis()); 1466 } 1467 1468 /** 1469 * Get the year of era field value. 1470 * 1471 * @return the year of era 1472 */ 1473 public int getCenturyOfEra() { 1474 return getChronology().centuryOfEra().get(getLocalMillis()); 1475 } 1476 1477 /** 1478 * Get the year of era field value. 1479 * 1480 * @return the year of era 1481 */ 1482 public int getYearOfEra() { 1483 return getChronology().yearOfEra().get(getLocalMillis()); 1484 } 1485 1486 /** 1487 * Get the year of century field value. 1488 * 1489 * @return the year of century 1490 */ 1491 public int getYearOfCentury() { 1492 return getChronology().yearOfCentury().get(getLocalMillis()); 1493 } 1494 1495 /** 1496 * Get the year field value. 1497 * 1498 * @return the year 1499 */ 1500 public int getYear() { 1501 return getChronology().year().get(getLocalMillis()); 1502 } 1503 1504 /** 1505 * Get the weekyear field value. 1506 * <p> 1507 * The weekyear is the year that matches with the weekOfWeekyear field. 1508 * In the standard ISO8601 week algorithm, the first week of the year 1509 * is that in which at least 4 days are in the year. As a result of this 1510 * definition, day 1 of the first week may be in the previous year. 1511 * The weekyear allows you to query the effective year for that day. 1512 * 1513 * @return the weekyear 1514 */ 1515 public int getWeekyear() { 1516 return getChronology().weekyear().get(getLocalMillis()); 1517 } 1518 1519 /** 1520 * Get the month of year field value. 1521 * 1522 * @return the month of year 1523 */ 1524 public int getMonthOfYear() { 1525 return getChronology().monthOfYear().get(getLocalMillis()); 1526 } 1527 1528 /** 1529 * Get the week of weekyear field value. 1530 * <p> 1531 * This field is associated with the "weekyear" via {@link #getWeekyear()}. 1532 * In the standard ISO8601 week algorithm, the first week of the year 1533 * is that in which at least 4 days are in the year. As a result of this 1534 * definition, day 1 of the first week may be in the previous year. 1535 * 1536 * @return the week of a week based year 1537 */ 1538 public int getWeekOfWeekyear() { 1539 return getChronology().weekOfWeekyear().get(getLocalMillis()); 1540 } 1541 1542 /** 1543 * Get the day of year field value. 1544 * 1545 * @return the day of year 1546 */ 1547 public int getDayOfYear() { 1548 return getChronology().dayOfYear().get(getLocalMillis()); 1549 } 1550 1551 /** 1552 * Get the day of month field value. 1553 * <p> 1554 * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}. 1555 * 1556 * @return the day of month 1557 */ 1558 public int getDayOfMonth() { 1559 return getChronology().dayOfMonth().get(getLocalMillis()); 1560 } 1561 1562 /** 1563 * Get the day of week field value. 1564 * <p> 1565 * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}. 1566 * 1567 * @return the day of week 1568 */ 1569 public int getDayOfWeek() { 1570 return getChronology().dayOfWeek().get(getLocalMillis()); 1571 } 1572 1573 //----------------------------------------------------------------------- 1574 /** 1575 * Get the hour of day field value. 1576 * 1577 * @return the hour of day 1578 */ 1579 public int getHourOfDay() { 1580 return getChronology().hourOfDay().get(getLocalMillis()); 1581 } 1582 1583 /** 1584 * Get the minute of hour field value. 1585 * 1586 * @return the minute of hour 1587 */ 1588 public int getMinuteOfHour() { 1589 return getChronology().minuteOfHour().get(getLocalMillis()); 1590 } 1591 1592 /** 1593 * Get the second of minute field value. 1594 * 1595 * @return the second of minute 1596 */ 1597 public int getSecondOfMinute() { 1598 return getChronology().secondOfMinute().get(getLocalMillis()); 1599 } 1600 1601 /** 1602 * Get the millis of second field value. 1603 * 1604 * @return the millis of second 1605 */ 1606 public int getMillisOfSecond() { 1607 return getChronology().millisOfSecond().get(getLocalMillis()); 1608 } 1609 1610 /** 1611 * Get the millis of day field value. 1612 * 1613 * @return the millis of day 1614 */ 1615 public int getMillisOfDay() { 1616 return getChronology().millisOfDay().get(getLocalMillis()); 1617 } 1618 1619 //----------------------------------------------------------------------- 1620 /** 1621 * Returns a copy of this datetime with the era field updated. 1622 * <p> 1623 * LocalDateTime is immutable, so there are no set methods. 1624 * Instead, this method returns a new instance with the value of 1625 * era changed. 1626 * 1627 * @param era the era to set 1628 * @return a copy of this object with the field set 1629 * @throws IllegalArgumentException if the value is invalid 1630 */ 1631 public LocalDateTime withEra(int era) { 1632 return withLocalMillis(getChronology().era().set(getLocalMillis(), era)); 1633 } 1634 1635 /** 1636 * Returns a copy of this datetime with the century of era field updated. 1637 * <p> 1638 * LocalDateTime is immutable, so there are no set methods. 1639 * Instead, this method returns a new instance with the value of 1640 * century of era changed. 1641 * 1642 * @param centuryOfEra the centurey of era to set 1643 * @return a copy of this object with the field set 1644 * @throws IllegalArgumentException if the value is invalid 1645 */ 1646 public LocalDateTime withCenturyOfEra(int centuryOfEra) { 1647 return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra)); 1648 } 1649 1650 /** 1651 * Returns a copy of this datetime with the year of era field updated. 1652 * <p> 1653 * LocalDateTime is immutable, so there are no set methods. 1654 * Instead, this method returns a new instance with the value of 1655 * year of era changed. 1656 * 1657 * @param yearOfEra the year of era to set 1658 * @return a copy of this object with the field set 1659 * @throws IllegalArgumentException if the value is invalid 1660 */ 1661 public LocalDateTime withYearOfEra(int yearOfEra) { 1662 return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra)); 1663 } 1664 1665 /** 1666 * Returns a copy of this datetime with the year of century field updated. 1667 * <p> 1668 * LocalDateTime is immutable, so there are no set methods. 1669 * Instead, this method returns a new instance with the value of 1670 * year of century changed. 1671 * 1672 * @param yearOfCentury the year of century to set 1673 * @return a copy of this object with the field set 1674 * @throws IllegalArgumentException if the value is invalid 1675 */ 1676 public LocalDateTime withYearOfCentury(int yearOfCentury) { 1677 return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury)); 1678 } 1679 1680 /** 1681 * Returns a copy of this datetime with the year field updated. 1682 * <p> 1683 * LocalDateTime is immutable, so there are no set methods. 1684 * Instead, this method returns a new instance with the value of 1685 * year changed. 1686 * 1687 * @param year the year to set 1688 * @return a copy of this object with the field set 1689 * @throws IllegalArgumentException if the value is invalid 1690 */ 1691 public LocalDateTime withYear(int year) { 1692 return withLocalMillis(getChronology().year().set(getLocalMillis(), year)); 1693 } 1694 1695 /** 1696 * Returns a copy of this datetime with the weekyear field updated. 1697 * <p> 1698 * The weekyear is the year that matches with the weekOfWeekyear field. 1699 * In the standard ISO8601 week algorithm, the first week of the year 1700 * is that in which at least 4 days are in the year. As a result of this 1701 * definition, day 1 of the first week may be in the previous year. 1702 * The weekyear allows you to query the effective year for that day. 1703 * <p> 1704 * LocalDateTime is immutable, so there are no set methods. 1705 * Instead, this method returns a new instance with the value of 1706 * weekyear changed. 1707 * 1708 * @param weekyear the weekyear to set 1709 * @return a copy of this object with the field set 1710 * @throws IllegalArgumentException if the value is invalid 1711 */ 1712 public LocalDateTime withWeekyear(int weekyear) { 1713 return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear)); 1714 } 1715 1716 /** 1717 * Returns a copy of this datetime with the month of year field updated. 1718 * <p> 1719 * LocalDateTime is immutable, so there are no set methods. 1720 * Instead, this method returns a new instance with the value of 1721 * month of year changed. 1722 * 1723 * @param monthOfYear the month of year to set 1724 * @return a copy of this object with the field set 1725 * @throws IllegalArgumentException if the value is invalid 1726 */ 1727 public LocalDateTime withMonthOfYear(int monthOfYear) { 1728 return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear)); 1729 } 1730 1731 /** 1732 * Returns a copy of this datetime with the week of weekyear field updated. 1733 * <p> 1734 * This field is associated with the "weekyear" via {@link #withWeekyear(int)}. 1735 * In the standard ISO8601 week algorithm, the first week of the year 1736 * is that in which at least 4 days are in the year. As a result of this 1737 * definition, day 1 of the first week may be in the previous year. 1738 * <p> 1739 * LocalDateTime is immutable, so there are no set methods. 1740 * Instead, this method returns a new instance with the value of 1741 * week of weekyear changed. 1742 * 1743 * @param weekOfWeekyear the week of weekyear to set 1744 * @return a copy of this object with the field set 1745 * @throws IllegalArgumentException if the value is invalid 1746 */ 1747 public LocalDateTime withWeekOfWeekyear(int weekOfWeekyear) { 1748 return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear)); 1749 } 1750 1751 /** 1752 * Returns a copy of this datetime with the day of year field updated. 1753 * <p> 1754 * LocalDateTime is immutable, so there are no set methods. 1755 * Instead, this method returns a new instance with the value of 1756 * day of year changed. 1757 * 1758 * @param dayOfYear the day of year to set 1759 * @return a copy of this object with the field set 1760 * @throws IllegalArgumentException if the value is invalid 1761 */ 1762 public LocalDateTime withDayOfYear(int dayOfYear) { 1763 return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear)); 1764 } 1765 1766 /** 1767 * Returns a copy of this datetime with the day of month field updated. 1768 * <p> 1769 * LocalDateTime is immutable, so there are no set methods. 1770 * Instead, this method returns a new instance with the value of 1771 * day of month changed. 1772 * 1773 * @param dayOfMonth the day of month to set 1774 * @return a copy of this object with the field set 1775 * @throws IllegalArgumentException if the value is invalid 1776 */ 1777 public LocalDateTime withDayOfMonth(int dayOfMonth) { 1778 return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth)); 1779 } 1780 1781 /** 1782 * Returns a copy of this datetime with the day of week field updated. 1783 * <p> 1784 * LocalDateTime is immutable, so there are no set methods. 1785 * Instead, this method returns a new instance with the value of 1786 * day of week changed. 1787 * 1788 * @param dayOfWeek the day of week to set 1789 * @return a copy of this object with the field set 1790 * @throws IllegalArgumentException if the value is invalid 1791 */ 1792 public LocalDateTime withDayOfWeek(int dayOfWeek) { 1793 return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek)); 1794 } 1795 1796 //----------------------------------------------------------------------- 1797 /** 1798 * Returns a copy of this datetime with the hour of day field updated. 1799 * <p> 1800 * LocalDateTime is immutable, so there are no set methods. 1801 * Instead, this method returns a new instance with the value of 1802 * hour of day changed. 1803 * 1804 * @param hour the hour of day to set 1805 * @return a copy of this object with the field set 1806 * @throws IllegalArgumentException if the value is invalid 1807 */ 1808 public LocalDateTime withHourOfDay(int hour) { 1809 return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour)); 1810 } 1811 1812 /** 1813 * Returns a copy of this datetime with the minute of hour field updated. 1814 * <p> 1815 * LocalDateTime is immutable, so there are no set methods. 1816 * Instead, this method returns a new instance with the value of 1817 * minute of hour changed. 1818 * 1819 * @param minute the minute of hour to set 1820 * @return a copy of this object with the field set 1821 * @throws IllegalArgumentException if the value is invalid 1822 */ 1823 public LocalDateTime withMinuteOfHour(int minute) { 1824 return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute)); 1825 } 1826 1827 /** 1828 * Returns a copy of this datetime with the second of minute field updated. 1829 * <p> 1830 * LocalDateTime is immutable, so there are no set methods. 1831 * Instead, this method returns a new instance with the value of 1832 * second of minute changed. 1833 * 1834 * @param second the second of minute to set 1835 * @return a copy of this object with the field set 1836 * @throws IllegalArgumentException if the value is invalid 1837 */ 1838 public LocalDateTime withSecondOfMinute(int second) { 1839 return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second)); 1840 } 1841 1842 /** 1843 * Returns a copy of this datetime with the millis of second field updated. 1844 * <p> 1845 * LocalDateTime is immutable, so there are no set methods. 1846 * Instead, this method returns a new instance with the value of 1847 * millis of second changed. 1848 * 1849 * @param millis the millis of second to set 1850 * @return a copy of this object with the field set 1851 * @throws IllegalArgumentException if the value is invalid 1852 */ 1853 public LocalDateTime withMillisOfSecond(int millis) { 1854 return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis)); 1855 } 1856 1857 /** 1858 * Returns a copy of this datetime with the millis of day field updated. 1859 * <p> 1860 * LocalDateTime is immutable, so there are no set methods. 1861 * Instead, this method returns a new instance with the value of 1862 * millis of day changed. 1863 * 1864 * @param millis the millis of day to set 1865 * @return a copy of this object with the field set 1866 * @throws IllegalArgumentException if the value is invalid 1867 */ 1868 public LocalDateTime withMillisOfDay(int millis) { 1869 return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis)); 1870 } 1871 1872 //----------------------------------------------------------------------- 1873 /** 1874 * Get the era property which provides access to advanced functionality. 1875 * 1876 * @return the era property 1877 */ 1878 public Property era() { 1879 return new Property(this, getChronology().era()); 1880 } 1881 1882 /** 1883 * Get the century of era property which provides access to advanced functionality. 1884 * 1885 * @return the year of era property 1886 */ 1887 public Property centuryOfEra() { 1888 return new Property(this, getChronology().centuryOfEra()); 1889 } 1890 1891 /** 1892 * Get the year of century property which provides access to advanced functionality. 1893 * 1894 * @return the year of era property 1895 */ 1896 public Property yearOfCentury() { 1897 return new Property(this, getChronology().yearOfCentury()); 1898 } 1899 1900 /** 1901 * Get the year of era property which provides access to advanced functionality. 1902 * 1903 * @return the year of era property 1904 */ 1905 public Property yearOfEra() { 1906 return new Property(this, getChronology().yearOfEra()); 1907 } 1908 1909 /** 1910 * Get the year property which provides access to advanced functionality. 1911 * 1912 * @return the year property 1913 */ 1914 public Property year() { 1915 return new Property(this, getChronology().year()); 1916 } 1917 1918 /** 1919 * Get the weekyear property which provides access to advanced functionality. 1920 * 1921 * @return the weekyear property 1922 */ 1923 public Property weekyear() { 1924 return new Property(this, getChronology().weekyear()); 1925 } 1926 1927 /** 1928 * Get the month of year property which provides access to advanced functionality. 1929 * 1930 * @return the month of year property 1931 */ 1932 public Property monthOfYear() { 1933 return new Property(this, getChronology().monthOfYear()); 1934 } 1935 1936 /** 1937 * Get the week of a week based year property which provides access to advanced functionality. 1938 * 1939 * @return the week of a week based year property 1940 */ 1941 public Property weekOfWeekyear() { 1942 return new Property(this, getChronology().weekOfWeekyear()); 1943 } 1944 1945 /** 1946 * Get the day of year property which provides access to advanced functionality. 1947 * 1948 * @return the day of year property 1949 */ 1950 public Property dayOfYear() { 1951 return new Property(this, getChronology().dayOfYear()); 1952 } 1953 1954 /** 1955 * Get the day of month property which provides access to advanced functionality. 1956 * 1957 * @return the day of month property 1958 */ 1959 public Property dayOfMonth() { 1960 return new Property(this, getChronology().dayOfMonth()); 1961 } 1962 1963 /** 1964 * Get the day of week property which provides access to advanced functionality. 1965 * 1966 * @return the day of week property 1967 */ 1968 public Property dayOfWeek() { 1969 return new Property(this, getChronology().dayOfWeek()); 1970 } 1971 1972 //----------------------------------------------------------------------- 1973 /** 1974 * Get the hour of day field property which provides access to advanced functionality. 1975 * 1976 * @return the hour of day property 1977 */ 1978 public Property hourOfDay() { 1979 return new Property(this, getChronology().hourOfDay()); 1980 } 1981 1982 /** 1983 * Get the minute of hour field property which provides access to advanced functionality. 1984 * 1985 * @return the minute of hour property 1986 */ 1987 public Property minuteOfHour() { 1988 return new Property(this, getChronology().minuteOfHour()); 1989 } 1990 1991 /** 1992 * Get the second of minute field property which provides access to advanced functionality. 1993 * 1994 * @return the second of minute property 1995 */ 1996 public Property secondOfMinute() { 1997 return new Property(this, getChronology().secondOfMinute()); 1998 } 1999 2000 /** 2001 * Get the millis of second property which provides access to advanced functionality. 2002 * 2003 * @return the millis of second property 2004 */ 2005 public Property millisOfSecond() { 2006 return new Property(this, getChronology().millisOfSecond()); 2007 } 2008 2009 /** 2010 * Get the millis of day property which provides access to advanced functionality. 2011 * 2012 * @return the millis of day property 2013 */ 2014 public Property millisOfDay() { 2015 return new Property(this, getChronology().millisOfDay()); 2016 } 2017 2018 //----------------------------------------------------------------------- 2019 /** 2020 * Output the date time in ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSS). 2021 * 2022 * @return ISO8601 time formatted string. 2023 */ 2024 @ToString 2025 public String toString() { 2026 return ISODateTimeFormat.dateTime().print(this); 2027 } 2028 2029 /** 2030 * Output the date using the specified format pattern. 2031 * 2032 * @param pattern the pattern specification, null means use <code>toString</code> 2033 * @see org.joda.time.format.DateTimeFormat 2034 */ 2035 public String toString(String pattern) { 2036 if (pattern == null) { 2037 return toString(); 2038 } 2039 return DateTimeFormat.forPattern(pattern).print(this); 2040 } 2041 2042 /** 2043 * Output the date using the specified format pattern. 2044 * 2045 * @param pattern the pattern specification, null means use <code>toString</code> 2046 * @param locale Locale to use, null means default 2047 * @see org.joda.time.format.DateTimeFormat 2048 */ 2049 public String toString(String pattern, Locale locale) throws IllegalArgumentException { 2050 if (pattern == null) { 2051 return toString(); 2052 } 2053 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this); 2054 } 2055 2056 //----------------------------------------------------------------------- 2057 /** 2058 * LocalDateTime.Property binds a LocalDateTime to a DateTimeField allowing 2059 * powerful datetime functionality to be easily accessed. 2060 * <p> 2061 * The simplest use of this class is as an alternative get method, here used to 2062 * get the year '1972' (as an int) and the month 'December' (as a String). 2063 * <pre> 2064 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2065 * int year = dt.year().get(); 2066 * String monthStr = dt.month().getAsText(); 2067 * </pre> 2068 * <p> 2069 * Methods are also provided that allow date modification. These return 2070 * new instances of LocalDateTime - they do not modify the original. 2071 * The example below yields two independent immutable date objects 2072 * 20 years apart. 2073 * <pre> 2074 * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0); 2075 * LocalDateTime dt1920 = dt.year().setCopy(1920); 2076 * </pre> 2077 * <p> 2078 * LocalDateTime.Property itself is thread-safe and immutable, as well as the 2079 * LocalDateTime being operated on. 2080 * 2081 * @author Stephen Colebourne 2082 * @author Brian S O'Neill 2083 * @since 1.3 2084 */ 2085 public static final class Property extends AbstractReadableInstantFieldProperty { 2086 2087 /** Serialization version */ 2088 private static final long serialVersionUID = -358138762846288L; 2089 2090 /** The instant this property is working against */ 2091 private transient LocalDateTime iInstant; 2092 /** The field this property is working against */ 2093 private transient DateTimeField iField; 2094 2095 /** 2096 * Constructor. 2097 * 2098 * @param instant the instant to set 2099 * @param field the field to use 2100 */ 2101 Property(LocalDateTime instant, DateTimeField field) { 2102 super(); 2103 iInstant = instant; 2104 iField = field; 2105 } 2106 2107 /** 2108 * Writes the property in a safe serialization format. 2109 */ 2110 private void writeObject(ObjectOutputStream oos) throws IOException { 2111 oos.writeObject(iInstant); 2112 oos.writeObject(iField.getType()); 2113 } 2114 2115 /** 2116 * Reads the property from a safe serialization format. 2117 */ 2118 private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException { 2119 iInstant = (LocalDateTime) oos.readObject(); 2120 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 2121 iField = type.getField(iInstant.getChronology()); 2122 } 2123 2124 //----------------------------------------------------------------------- 2125 /** 2126 * Gets the field being used. 2127 * 2128 * @return the field 2129 */ 2130 public DateTimeField getField() { 2131 return iField; 2132 } 2133 2134 /** 2135 * Gets the milliseconds of the datetime that this property is linked to. 2136 * 2137 * @return the milliseconds 2138 */ 2139 protected long getMillis() { 2140 return iInstant.getLocalMillis(); 2141 } 2142 2143 /** 2144 * Gets the chronology of the datetime that this property is linked to. 2145 * 2146 * @return the chronology 2147 * @since 1.4 2148 */ 2149 protected Chronology getChronology() { 2150 return iInstant.getChronology(); 2151 } 2152 2153 /** 2154 * Gets the LocalDateTime object linked to this property. 2155 * 2156 * @return the linked LocalDateTime 2157 */ 2158 public LocalDateTime getLocalDateTime() { 2159 return iInstant; 2160 } 2161 2162 //----------------------------------------------------------------------- 2163 /** 2164 * Adds to this field in a copy of this LocalDateTime. 2165 * <p> 2166 * The LocalDateTime attached to this property is unchanged by this call. 2167 * 2168 * @param value the value to add to the field in the copy 2169 * @return a copy of the LocalDateTime with the field value changed 2170 * @throws IllegalArgumentException if the value isn't valid 2171 */ 2172 public LocalDateTime addToCopy(int value) { 2173 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2174 } 2175 2176 /** 2177 * Adds to this field in a copy of this LocalDateTime. 2178 * <p> 2179 * The LocalDateTime attached to this property is unchanged by this call. 2180 * 2181 * @param value the value to add to the field in the copy 2182 * @return a copy of the LocalDateTime with the field value changed 2183 * @throws IllegalArgumentException if the value isn't valid 2184 */ 2185 public LocalDateTime addToCopy(long value) { 2186 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value)); 2187 } 2188 2189 /** 2190 * Adds to this field, possibly wrapped, in a copy of this LocalDateTime. 2191 * A field wrapped operation only changes this field. 2192 * Thus 31st January addWrapField one day goes to the 1st January. 2193 * <p> 2194 * The LocalDateTime attached to this property is unchanged by this call. 2195 * 2196 * @param value the value to add to the field in the copy 2197 * @return a copy of the LocalDateTime with the field value changed 2198 * @throws IllegalArgumentException if the value isn't valid 2199 */ 2200 public LocalDateTime addWrapFieldToCopy(int value) { 2201 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value)); 2202 } 2203 2204 //----------------------------------------------------------------------- 2205 /** 2206 * Sets this field in a copy of the LocalDateTime. 2207 * <p> 2208 * The LocalDateTime attached to this property is unchanged by this call. 2209 * 2210 * @param value the value to set the field in the copy to 2211 * @return a copy of the LocalDateTime with the field value changed 2212 * @throws IllegalArgumentException if the value isn't valid 2213 */ 2214 public LocalDateTime setCopy(int value) { 2215 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value)); 2216 } 2217 2218 /** 2219 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2220 * <p> 2221 * The LocalDateTime attached to this property is unchanged by this call. 2222 * 2223 * @param text the text value to set 2224 * @param locale optional locale to use for selecting a text symbol 2225 * @return a copy of the LocalDateTime with the field value changed 2226 * @throws IllegalArgumentException if the text value isn't valid 2227 */ 2228 public LocalDateTime setCopy(String text, Locale locale) { 2229 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale)); 2230 } 2231 2232 /** 2233 * Sets this field in a copy of the LocalDateTime to a parsed text value. 2234 * <p> 2235 * The LocalDateTime attached to this property is unchanged by this call. 2236 * 2237 * @param text the text value to set 2238 * @return a copy of the LocalDateTime with the field value changed 2239 * @throws IllegalArgumentException if the text value isn't valid 2240 */ 2241 public LocalDateTime setCopy(String text) { 2242 return setCopy(text, null); 2243 } 2244 2245 //----------------------------------------------------------------------- 2246 /** 2247 * Returns a new LocalDateTime with this field set to the maximum value 2248 * for this field. 2249 * <p> 2250 * This operation is useful for obtaining a LocalDateTime on the last day 2251 * of the month, as month lengths vary. 2252 * <pre> 2253 * LocalDateTime lastDayOfMonth = dt.dayOfMonth().withMaximumValue(); 2254 * </pre> 2255 * <p> 2256 * The LocalDateTime attached to this property is unchanged by this call. 2257 * 2258 * @return a copy of the LocalDateTime with this field set to its maximum 2259 */ 2260 public LocalDateTime withMaximumValue() { 2261 return setCopy(getMaximumValue()); 2262 } 2263 2264 /** 2265 * Returns a new LocalDateTime with this field set to the minimum value 2266 * for this field. 2267 * <p> 2268 * The LocalDateTime attached to this property is unchanged by this call. 2269 * 2270 * @return a copy of the LocalDateTime with this field set to its minimum 2271 */ 2272 public LocalDateTime withMinimumValue() { 2273 return setCopy(getMinimumValue()); 2274 } 2275 2276 //----------------------------------------------------------------------- 2277 /** 2278 * Rounds to the lowest whole unit of this field on a copy of this 2279 * LocalDateTime. 2280 * <p> 2281 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2282 * where the time is 10:30 would result in new LocalDateTime with the 2283 * time of 10:00. 2284 * 2285 * @return a copy of the LocalDateTime with the field value changed 2286 */ 2287 public LocalDateTime roundFloorCopy() { 2288 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis())); 2289 } 2290 2291 /** 2292 * Rounds to the highest whole unit of this field on a copy of this 2293 * LocalDateTime. 2294 * <p> 2295 * For example, rounding floor on the hourOfDay field of a LocalDateTime 2296 * where the time is 10:30 would result in new LocalDateTime with the 2297 * time of 11:00. 2298 * 2299 * @return a copy of the LocalDateTime with the field value changed 2300 */ 2301 public LocalDateTime roundCeilingCopy() { 2302 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis())); 2303 } 2304 2305 /** 2306 * Rounds to the nearest whole unit of this field on a copy of this 2307 * LocalDateTime, favoring the floor if halfway. 2308 * 2309 * @return a copy of the LocalDateTime with the field value changed 2310 */ 2311 public LocalDateTime roundHalfFloorCopy() { 2312 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis())); 2313 } 2314 2315 /** 2316 * Rounds to the nearest whole unit of this field on a copy of this 2317 * LocalDateTime, favoring the ceiling if halfway. 2318 * 2319 * @return a copy of the LocalDateTime with the field value changed 2320 */ 2321 public LocalDateTime roundHalfCeilingCopy() { 2322 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis())); 2323 } 2324 2325 /** 2326 * Rounds to the nearest whole unit of this field on a copy of this 2327 * LocalDateTime. If halfway, the ceiling is favored over the floor 2328 * only if it makes this field's value even. 2329 * 2330 * @return a copy of the LocalDateTime with the field value changed 2331 */ 2332 public LocalDateTime roundHalfEvenCopy() { 2333 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis())); 2334 } 2335 } 2336 2337 }