KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > types > Time


1 /*
2  * Copyright 2002-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.axis.types;
17
18 import org.apache.axis.utils.Messages;
19
20 import java.text.SimpleDateFormat JavaDoc;
21 import java.util.Calendar JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.TimeZone JavaDoc;
24
25 /**
26  * Class that represents the xsd:time XML Schema type
27  */

28 public class Time implements java.io.Serializable JavaDoc {
29     private Calendar JavaDoc _value;
30
31
32     /**
33      * a shared java.text.SimpleDateFormat instance used for parsing the basic
34      * component of the timestamp
35      */

36     private static SimpleDateFormat JavaDoc zulu =
37        new SimpleDateFormat JavaDoc("HH:mm:ss.SSS'Z'");
38
39     // We should always format dates in the GMT timezone
40
static {
41         zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
42     }
43
44
45     /**
46      * Initialize with a Calender, year month and date are ignored
47      */

48     public Time(Calendar JavaDoc value) {
49         this._value = value;
50         _value.set(0,0,0); // ignore year, month, date
51
}
52
53     /**
54      * Converts a string formatted as HH:mm:ss[.SSS][+/-offset]
55      */

56     public Time(String JavaDoc value) throws NumberFormatException JavaDoc {
57         _value = makeValue(value);
58     }
59
60     /**
61      * return the time as a calendar: ignore the year, month and date fields
62      * @return calendar value; may be null
63      */

64     public Calendar JavaDoc getAsCalendar() {
65         return _value;
66     }
67
68     /**
69      * set the time; ignore year, month, date
70      * @param date
71      */

72     public void setTime(Calendar JavaDoc date) {
73         this._value = date;
74         _value.set(0,0,0); // ignore year, month, date
75
}
76
77     /**
78      * set the time from a date instance
79      * @param date
80      */

81     public void setTime(Date JavaDoc date) {
82         _value.setTime(date);
83         _value.set(0,0,0); // ignore year, month, date
84
}
85
86     /**
87      * Utility function that parses xsd:time strings and returns a Date object
88      */

89     private Calendar JavaDoc makeValue(String JavaDoc source) throws NumberFormatException JavaDoc {
90         Calendar JavaDoc calendar = Calendar.getInstance();
91         Date JavaDoc date;
92
93         validateSource(source);
94
95         // convert what we have validated so far
96
date = ParseHoursMinutesSeconds(source);
97
98         int pos = 8; // The "." in hh:mm:ss.sss
99

100         // parse optional milliseconds
101
if ( source != null ) {
102             if (pos < source.length() && source.charAt(pos)=='.') {
103                 int milliseconds = 0;
104                 int start = ++pos;
105                 while (pos<source.length() &&
106                        Character.isDigit(source.charAt(pos))) {
107                     pos++;
108                 }
109
110
111                 String JavaDoc decimal=source.substring(start,pos);
112                 if (decimal.length()==3) {
113                     milliseconds=Integer.parseInt(decimal);
114                 } else if (decimal.length() < 3) {
115                     milliseconds=Integer.parseInt((decimal+"000")
116                                                   .substring(0,3));
117                 } else {
118                     milliseconds=Integer.parseInt(decimal.substring(0,3));
119                     if (decimal.charAt(3)>='5') {
120                         ++milliseconds;
121                     }
122                 }
123
124                 // add milliseconds to the current date
125
date.setTime(date.getTime()+milliseconds);
126             }
127
128             // parse optional timezone
129
if (pos+5 < source.length() &&
130                 (source.charAt(pos)=='+' || (source.charAt(pos)=='-'))) {
131                     if (!Character.isDigit(source.charAt(pos+1)) ||
132                         !Character.isDigit(source.charAt(pos+2)) ||
133                         source.charAt(pos+3) != ':' ||
134                         !Character.isDigit(source.charAt(pos+4)) ||
135                         !Character.isDigit(source.charAt(pos+5)))
136                     {
137                         throw new NumberFormatException JavaDoc(
138                                 Messages.getMessage("badTimezone00"));
139                     }
140
141                     int hours = (source.charAt(pos+1)-'0')*10
142                         +source.charAt(pos+2)-'0';
143                     int mins = (source.charAt(pos+4)-'0')*10
144                         +source.charAt(pos+5)-'0';
145                     int milliseconds = (hours*60+mins)*60*1000;
146
147                     // subtract milliseconds from current date to obtain GMT
148
if (source.charAt(pos)=='+') {
149                         milliseconds=-milliseconds;
150                     }
151                     date.setTime(date.getTime()+milliseconds);
152                     pos+=6;
153             }
154
155             if (pos < source.length() && source.charAt(pos)=='Z') {
156                 pos++;
157                 calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
158             }
159
160             if (pos < source.length()) {
161                 throw new NumberFormatException JavaDoc(
162                         Messages.getMessage("badChars00"));
163             }
164         }
165
166         calendar.setTime(date);
167         calendar.set(0,0,0); // ignore year, month, date
168

169         return calendar;
170     }
171
172     private int getTimezoneNumberValue(char c) {
173         int n=c-'0';
174         if(n<0 || n>9) {
175             //oops, out of range
176
throw new NumberFormatException JavaDoc(
177                     Messages.getMessage("badTimezone00"));
178         }
179         return n;
180     }
181
182     /**
183      * parse the hours, minutes and seconds of a string, by handing it off to
184      * the java runtime.
185      * The relevant code will return null if a null string is passed in, so this
186      * code may return a null date in response
187      * @param source
188      * @return
189      * @throws NumberFormatException in the event of trouble
190      */

191     private static Date JavaDoc ParseHoursMinutesSeconds(String JavaDoc source) {
192         Date JavaDoc date;
193         try {
194             synchronized (zulu) {
195                 String JavaDoc fulltime = source == null ? null :
196                                                     (source.substring(0,8)+".000Z");
197                 date = zulu.parse(fulltime);
198             }
199         } catch (Exception JavaDoc e) {
200             throw new NumberFormatException JavaDoc(e.toString());
201         }
202         return date;
203     }
204
205     /**
206      * validate the source
207      * @param source
208      */

209     private void validateSource(String JavaDoc source) {
210         // validate fixed portion of format
211
if ( source != null ) {
212             if (source.charAt(2) != ':' || source.charAt(5) != ':') {
213                 throw new NumberFormatException JavaDoc(
214                         Messages.getMessage("badTime00"));
215             }
216             if (source.length() < 8) {
217                 throw new NumberFormatException JavaDoc(
218                         Messages.getMessage("badTime00"));
219             }
220         }
221     }
222
223     /**
224      * stringify method returns the time as it would be in GMT, only accurate to the
225      * second...millis probably get lost.
226      * @return
227      */

228     public String JavaDoc toString() {
229         if(_value==null) {
230             return "unassigned Time";
231         }
232         synchronized (zulu) {
233             return zulu.format(_value.getTime());
234         }
235
236     }
237
238     public boolean equals(Object JavaDoc obj) {
239         if (obj == null) return false;
240         if (!(obj instanceof Time)) return false;
241         Time other = (Time) obj;
242         if (this == obj) return true;
243
244         boolean _equals;
245         _equals = true &&
246             ((_value ==null && other._value ==null) ||
247              (_value !=null &&
248               _value.getTime().equals(other._value.getTime())));
249
250         return _equals;
251
252     }
253
254     /**
255      * Returns the hashcode of the underlying calendar.
256      *
257      * @return an <code>int</code> value
258      */

259     public int hashCode() {
260         return _value == null ? 0 : _value.hashCode();
261     }
262 }
263
Popular Tags