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