001 /*
002 * Copyright 2001-2005 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.chrono;
017
018 import org.joda.time.Chronology;
019 import org.joda.time.DateTimeField;
020 import org.joda.time.DateTimeZone;
021 import org.joda.time.field.LenientDateTimeField;
022
023 /**
024 * Wraps another Chronology, ensuring all the fields are lenient.
025 * <p>
026 * LenientChronology is thread-safe and immutable.
027 *
028 * @author Brian S O'Neill
029 * @since 1.0
030 * @see LenientDateTimeField
031 * @see StrictChronology
032 */
033 public final class LenientChronology extends AssembledChronology {
034
035 /** Serialization lock */
036 private static final long serialVersionUID = -3148237568046877177L;
037
038 /**
039 * Create a LenientChronology for any chronology.
040 *
041 * @param base the chronology to wrap
042 * @throws IllegalArgumentException if chronology is null
043 */
044 public static LenientChronology getInstance(Chronology base) {
045 if (base == null) {
046 throw new IllegalArgumentException("Must supply a chronology");
047 }
048 return new LenientChronology(base);
049 }
050
051 private transient Chronology iWithUTC;
052
053 /**
054 * Create a LenientChronology for any chronology.
055 *
056 * @param base the chronology to wrap
057 */
058 private LenientChronology(Chronology base) {
059 super(base, null);
060 }
061
062 public Chronology withUTC() {
063 if (iWithUTC == null) {
064 if (getZone() == DateTimeZone.UTC) {
065 iWithUTC = this;
066 } else {
067 iWithUTC = LenientChronology.getInstance(getBase().withUTC());
068 }
069 }
070 return iWithUTC;
071 }
072
073 public Chronology withZone(DateTimeZone zone) {
074 if (zone == null) {
075 zone = DateTimeZone.getDefault();
076 }
077 if (zone == DateTimeZone.UTC) {
078 return withUTC();
079 }
080 if (zone == getZone()) {
081 return this;
082 }
083 return LenientChronology.getInstance(getBase().withZone(zone));
084 }
085
086 protected void assemble(Fields fields) {
087 fields.year = convertField(fields.year);
088 fields.yearOfEra = convertField(fields.yearOfEra);
089 fields.yearOfCentury = convertField(fields.yearOfCentury);
090 fields.centuryOfEra = convertField(fields.centuryOfEra);
091 fields.era = convertField(fields.era);
092 fields.dayOfWeek = convertField(fields.dayOfWeek);
093 fields.dayOfMonth = convertField(fields.dayOfMonth);
094 fields.dayOfYear = convertField(fields.dayOfYear);
095 fields.monthOfYear = convertField(fields.monthOfYear);
096 fields.weekOfWeekyear = convertField(fields.weekOfWeekyear);
097 fields.weekyear = convertField(fields.weekyear);
098 fields.weekyearOfCentury = convertField(fields.weekyearOfCentury);
099
100 fields.millisOfSecond = convertField(fields.millisOfSecond);
101 fields.millisOfDay = convertField(fields.millisOfDay);
102 fields.secondOfMinute = convertField(fields.secondOfMinute);
103 fields.secondOfDay = convertField(fields.secondOfDay);
104 fields.minuteOfHour = convertField(fields.minuteOfHour);
105 fields.minuteOfDay = convertField(fields.minuteOfDay);
106 fields.hourOfDay = convertField(fields.hourOfDay);
107 fields.hourOfHalfday = convertField(fields.hourOfHalfday);
108 fields.clockhourOfDay = convertField(fields.clockhourOfDay);
109 fields.clockhourOfHalfday = convertField(fields.clockhourOfHalfday);
110 fields.halfdayOfDay = convertField(fields.halfdayOfDay);
111 }
112
113 private final DateTimeField convertField(DateTimeField field) {
114 return LenientDateTimeField.getInstance(field, getBase());
115 }
116
117 //-----------------------------------------------------------------------
118 /**
119 * A lenient chronology is only equal to a lenient chronology with the
120 * same base chronology.
121 *
122 * @param obj the object to compare to
123 * @return true if equal
124 * @since 1.4
125 */
126 public boolean equals(Object obj) {
127 if (this == obj) {
128 return true;
129 }
130 if (obj instanceof LenientChronology == false) {
131 return false;
132 }
133 LenientChronology chrono = (LenientChronology) obj;
134 return getBase().equals(chrono.getBase());
135 }
136
137 /**
138 * A suitable hashcode for the chronology.
139 *
140 * @return the hashcode
141 * @since 1.4
142 */
143 public int hashCode() {
144 return 236548278 + getBase().hashCode() * 7;
145 }
146
147 /**
148 * A debugging string for the chronology.
149 *
150 * @return the debugging string
151 */
152 public String toString() {
153 return "LenientChronology[" + getBase().toString() + ']';
154 }
155
156 }