Tue, 10 Feb 2015 18:12:00 +0100
Import initial revisions of existing project AndroidCaldavSyncAdapater,
forked from upstream repository at 27e8a0f8495c92e0780d450bdf0c7cec77a03a55.
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.io.IOException;
35 import java.io.Serializable;
36 import java.text.DecimalFormat;
37 import java.text.NumberFormat;
39 import net.fortuna.ical4j.util.Dates;
41 import org.apache.commons.lang.builder.HashCodeBuilder;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
45 /**
46 * $Id$
47 *
48 * Created on 26/06/2005
49 *
50 * Represents a timezone offset from UTC time.
51 *
52 * @author Ben Fortuna
53 */
54 public class UtcOffset implements Serializable {
56 private static final long serialVersionUID = 5883111996721531728L;
58 private static final int HOUR_START_INDEX = 1;
60 private static final int HOUR_END_INDEX = 3;
62 private static final int MINUTE_START_INDEX = 3;
64 private static final int MINUTE_END_INDEX = 5;
66 private static final int SECOND_START_INDEX = 5;
68 private static final int SECOND_END_INDEX = 7;
70 private static final NumberFormat HOUR_FORMAT = new DecimalFormat("00");
72 private static final NumberFormat MINUTE_FORMAT = new DecimalFormat("00");
74 private static final NumberFormat SECOND_FORMAT = new DecimalFormat("00");
76 private long offset;
78 /**
79 * @param value a string representation of an offset
80 */
81 public UtcOffset(final String value) {
83 if (value.length() < MINUTE_END_INDEX) {
84 throw new IllegalArgumentException("Invalid UTC offset [" + value
85 + "] - must be of the form: (+/-)HHMM[SS]");
86 }
88 final boolean negative = value.charAt(0) == '-';
90 if (!negative && !(value.charAt(0) == '+')) {
91 throw new IllegalArgumentException("UTC offset value must be signed");
92 }
94 offset = 0;
95 offset += Integer.parseInt(value.substring(HOUR_START_INDEX,
96 HOUR_END_INDEX))
97 * Dates.MILLIS_PER_HOUR;
98 offset += Integer.parseInt(value.substring(MINUTE_START_INDEX,
99 MINUTE_END_INDEX))
100 * Dates.MILLIS_PER_MINUTE;
101 if (value.length() == SECOND_END_INDEX) {
102 offset += Integer.parseInt(value.substring(SECOND_START_INDEX,
103 SECOND_END_INDEX))
104 * Dates.MILLIS_PER_SECOND;
105 }
106 if (negative) {
107 offset = -offset;
108 }
109 }
111 /**
112 * @param offset an offset value in milliseconds
113 */
114 public UtcOffset(final long offset) {
115 this.offset = (long) Math.floor(offset / (double) Dates.MILLIS_PER_SECOND) * Dates.MILLIS_PER_SECOND;
116 }
118 /**
119 * {@inheritDoc}
120 */
121 public final String toString() {
122 final StringBuffer b = new StringBuffer();
123 long remainder = Math.abs(offset);
125 if (offset < 0) {
126 b.append('-');
127 }
128 else {
129 b.append('+');
130 }
131 b.append(HOUR_FORMAT.format(remainder / Dates.MILLIS_PER_HOUR));
133 remainder = remainder % Dates.MILLIS_PER_HOUR;
134 b.append(MINUTE_FORMAT.format(remainder / Dates.MILLIS_PER_MINUTE));
136 remainder = remainder % Dates.MILLIS_PER_MINUTE;
137 if (remainder > 0) {
138 b.append(SECOND_FORMAT.format(remainder / Dates.MILLIS_PER_SECOND));
139 }
140 return b.toString();
141 }
143 /**
144 * @return Returns the offset.
145 */
146 public final long getOffset() {
147 return offset;
148 }
150 /**
151 * {@inheritDoc}
152 */
153 public final boolean equals(final Object arg0) {
154 if (arg0 instanceof UtcOffset) {
155 return getOffset() == ((UtcOffset) arg0).getOffset();
156 }
157 return super.equals(arg0);
158 }
160 /**
161 * {@inheritDoc}
162 */
163 public final int hashCode() {
164 return new HashCodeBuilder().append(getOffset()).toHashCode();
165 }
166 }