View Javadoc

1   /*
2    * $Id: UtcOffsetFormat.java [15-May-2004]
3    *
4    * Copyright (c) 2004, Ben Fortuna
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 	o Redistributions of source code must retain the above copyright
12   * notice, this list of conditions and the following disclaimer.
13   *
14   * 	o Redistributions in binary form must reproduce the above copyright
15   * notice, this list of conditions and the following disclaimer in the
16   * documentation and/or other materials provided with the distribution.
17   *
18   * 	o Neither the name of Ben Fortuna nor the names of any other contributors
19   * may be used to endorse or promote products derived from this software
20   * without specific prior written permission.
21   *
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25   * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
26   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   */
34  package net.fortuna.ical4j.util;
35  
36  import java.text.DecimalFormat;
37  import java.text.NumberFormat;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  
42  /***
43   * Defines the format used by all iCalendar UTC offsets.
44   *
45   * @author benfortuna
46   */
47  public final class UtcOffsetFormat {
48  
49      private static final long MILLIS_PER_SECOND = 1000;
50  
51      private static final long MILLIS_PER_MINUTE = 60000;
52  
53      private static final long MILLIS_PER_HOUR = 3600000;
54  
55      private static final int HOUR_START_INDEX = 1;
56  
57      private static final int HOUR_END_INDEX = 3;
58  
59      private static final int MINUTE_START_INDEX = 3;
60  
61      private static final int MINUTE_END_INDEX = 5;
62  
63      private static final int SECOND_START_INDEX = 5;
64  
65      private static final int SECOND_END_INDEX = 7;
66  
67      private static final NumberFormat HOUR_FORMAT = new DecimalFormat("00");
68  
69      private static final NumberFormat MINUTE_FORMAT = new DecimalFormat("00");
70  
71      private static final NumberFormat SECOND_FORMAT = new DecimalFormat("00");
72  
73      private static Log log = LogFactory.getLog(UtcOffsetFormat.class);
74  
75      private static UtcOffsetFormat instance = new UtcOffsetFormat();
76  
77      /***
78       * Constructor made private to enforce singleton.
79       */
80      private UtcOffsetFormat() {
81      }
82  
83      /***
84       * @return Returns the instance.
85       */
86      public static UtcOffsetFormat getInstance() {
87          return instance;
88      }
89  
90      /***
91       * Parses an iCalendar utc-offset string.
92       *
93       * @param aString
94       *            the utc-offset string to parse
95       * @return the timezone offset in milliseconds
96       */
97      public long parse(final String aString) {
98  
99          long offset = 0;
100 
101         boolean negative = aString.startsWith("-");
102 
103         offset += Integer.parseInt(aString.substring(HOUR_START_INDEX,
104                 HOUR_END_INDEX))
105                 * MILLIS_PER_HOUR;
106 
107         offset += Integer.parseInt(aString.substring(MINUTE_START_INDEX,
108                 MINUTE_END_INDEX))
109                 * MILLIS_PER_MINUTE;
110 
111         try {
112 
113             offset += Integer.parseInt(aString.substring(SECOND_START_INDEX,
114                     SECOND_END_INDEX))
115                     * MILLIS_PER_SECOND;
116         }
117         catch (Exception e) {
118             // seconds not supplied..
119             log.debug("Seconds not specified", e);
120         }
121 
122         return offset;
123     }
124 
125     /***
126      * Returns a string representation of an UTC offset.
127      * @param offset an UTC offset in milliseconds
128      * @return a string
129      */
130     public String format(final long offset) {
131 
132         StringBuffer b = new StringBuffer();
133 
134         long remainder = offset;
135 
136         if (offset < 0) {
137             b.append('-');
138         }
139         else {
140             b.append('+');
141         }
142 
143         b.append(HOUR_FORMAT.format(remainder / MILLIS_PER_HOUR));
144 
145         remainder = remainder % MILLIS_PER_HOUR;
146 
147         b.append(MINUTE_FORMAT.format(remainder / MILLIS_PER_MINUTE));
148 
149         remainder = remainder % MILLIS_PER_MINUTE;
150 
151         if (remainder > 0) {
152             b.append(SECOND_FORMAT.format(remainder / MILLIS_PER_SECOND));
153         }
154 
155         return b.toString();
156     }
157 }