Tue, 10 Feb 2015 19:38:00 +0100
Upgrade embedded ical4j from ancient whatever to upstream version 1.0.6.
1 /**
2 * Copyright (c) 2012, Ben Fortuna
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * o Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * o Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * o Neither the name of Ben Fortuna nor the names of any other contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 package net.fortuna.ical4j.model;
34 import java.util.Calendar;
35 import java.util.Collections;
36 import java.util.Date;
37 import java.util.List;
39 import net.fortuna.ical4j.model.component.Daylight;
40 import net.fortuna.ical4j.model.component.Observance;
41 import net.fortuna.ical4j.model.component.VTimeZone;
42 import net.fortuna.ical4j.model.property.TzId;
43 import net.fortuna.ical4j.model.property.TzOffsetTo;
45 /**
46 * $Id$
47 *
48 * Created on 13/09/2005
49 *
50 * A Java timezone implementation based on an underlying VTimeZone
51 * definition.
52 * @author Ben Fortuna
53 */
54 public class TimeZone extends java.util.TimeZone {
56 private static final long serialVersionUID = -5620979316746547234L;
58 private final VTimeZone vTimeZone;
59 private final int rawOffset;
61 /**
62 * Constructs a new instance based on the specified VTimeZone.
63 * @param vTimeZone a VTIMEZONE object instance
64 */
65 public TimeZone(final VTimeZone vTimeZone) {
66 this.vTimeZone = vTimeZone;
67 final TzId tzId = (TzId) vTimeZone.getProperty(Property.TZID);
68 setID(tzId.getValue());
69 this.rawOffset = getRawOffset(vTimeZone);
70 }
72 /**
73 * {@inheritDoc}
74 */
75 public final int getOffset(final int era, final int year, final int month, final int dayOfMonth,
76 final int dayOfWeek, final int milliseconds) {
78 // calculate time of day
79 int ms = milliseconds;
80 final int hour = ms / 3600000;
81 ms -= hour*3600000;
82 final int minute = ms / 60000;
83 ms -= minute*60000;
84 final int second = ms / 1000;
85 ms -= second*1000;
87 final Calendar cal = Calendar.getInstance();
88 cal.clear(); // don't retain current date/time, it may disturb the calculation
90 // set date and time
91 cal.set(Calendar.ERA, era);
92 cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
93 cal.set(year, month, dayOfMonth, hour, minute, second);
94 cal.set(Calendar.MILLISECOND, ms);
96 final Observance observance = vTimeZone.getApplicableObservance(new DateTime(cal.getTime()));
97 if (observance != null) {
98 final TzOffsetTo offset = (TzOffsetTo) observance.getProperty(Property.TZOFFSETTO);
99 return (int) offset.getOffset().getOffset();
100 }
101 return 0;
102 }
104 /**
105 * {@inheritDoc}
106 */
107 public int getOffset(long date) {
108 final Observance observance = vTimeZone.getApplicableObservance(new DateTime(date));
109 if (observance != null) {
110 final TzOffsetTo offset = (TzOffsetTo) observance.getProperty(Property.TZOFFSETTO);
111 if (offset.getOffset().getOffset() < getRawOffset()) {
112 return getRawOffset();
113 }
114 else {
115 return (int) offset.getOffset().getOffset();
116 }
117 }
118 return 0;
119 }
121 /**
122 * {@inheritDoc}
123 */
124 public final int getRawOffset() {
125 return rawOffset;
126 }
128 /**
129 * Determines if the specified date is in daylight time according to
130 * this timezone. This is done by finding the latest supporting
131 * observance for the specified date and identifying whether it is
132 * daylight time.
133 * @param date a date instance
134 * @return true if the specified date is in daylight time, otherwise false
135 */
136 public final boolean inDaylightTime(final Date date) {
137 final Observance observance = vTimeZone.getApplicableObservance(new DateTime(date));
138 return (observance != null && observance instanceof Daylight);
139 }
141 /**
142 * {@inheritDoc}
143 */
144 public final void setRawOffset(final int offsetMillis) {
145 throw new UnsupportedOperationException("Updates to the VTIMEZONE object must be performed directly");
146 }
148 /**
149 * {@inheritDoc}
150 */
151 public final boolean useDaylightTime() {
152 final ComponentList daylights = vTimeZone.getObservances().getComponents(Observance.DAYLIGHT);
153 return (!daylights.isEmpty());
154 }
156 /**
157 * @return Returns the VTimeZone backing this instance.
158 */
159 public final VTimeZone getVTimeZone() {
160 return vTimeZone;
161 }
163 private static final int getRawOffset(VTimeZone vt) {
165 List seasonalTimes = vt.getObservances().getComponents(Observance.STANDARD);
166 // if no standard time use daylight time..
167 if (seasonalTimes.isEmpty()) {
168 seasonalTimes = vt.getObservances().getComponents(Observance.DAYLIGHT);
169 if (seasonalTimes.isEmpty()) {
170 return 0;
171 }
172 }
173 Observance latestSeasonalTime = null;
174 if (seasonalTimes.size() > 1) {
175 // per java spec and when dealing with historical time,
176 // rawoffset is the raw offset at the current date
177 final DateTime now = new DateTime();
178 Date latestOnset = null;
179 for (int i = 0; i < seasonalTimes.size(); i++) {
180 Observance seasonalTime = (Observance) seasonalTimes.get(i);
181 Date onset = seasonalTime.getLatestOnset(now);
182 if (onset == null) {
183 continue;
184 }
185 if (latestOnset == null || onset.after(latestOnset)) {
186 latestOnset = onset;
187 latestSeasonalTime = seasonalTime;
188 }
189 }
190 } else {
191 latestSeasonalTime = (Observance)seasonalTimes.get(0);
192 }
193 if (latestSeasonalTime != null) {
194 final TzOffsetTo offsetTo = (TzOffsetTo) latestSeasonalTime.getProperty(Property.TZOFFSETTO);
195 if (offsetTo != null) {
196 return (int) offsetTo.getOffset().getOffset();
197 }
198 }
199 return 0;
200 }
202 public boolean equals(Object o) {
203 if (this == o) return true;
204 if (o == null || getClass() != o.getClass()) return false;
206 TimeZone timeZone = (TimeZone) o;
208 if (rawOffset != timeZone.rawOffset) return false;
209 if (vTimeZone != null ? !vTimeZone.equals(timeZone.vTimeZone) : timeZone.vTimeZone != null) return false;
211 return true;
212 }
214 public int hashCode() {
215 int result = vTimeZone != null ? vTimeZone.hashCode() : 0;
216 result = 31 * result + rawOffset;
217 return result;
218 }
219 }