KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > convert > StringConverter


1 /*
2  * Copyright 2001-2006 Stephen Colebourne
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.joda.time.convert;
17
18 import org.joda.time.Chronology;
19 import org.joda.time.DateTime;
20 import org.joda.time.Period;
21 import org.joda.time.ReadWritableInterval;
22 import org.joda.time.ReadWritablePeriod;
23 import org.joda.time.ReadablePartial;
24 import org.joda.time.field.FieldUtils;
25 import org.joda.time.format.DateTimeFormatter;
26 import org.joda.time.format.ISODateTimeFormat;
27 import org.joda.time.format.ISOPeriodFormat;
28 import org.joda.time.format.PeriodFormatter;
29
30 /**
31  * StringConverter converts from a String to an instant, partial,
32  * duration, period or interval..
33  *
34  * @author Stephen Colebourne
35  * @author Brian S O'Neill
36  * @since 1.0
37  */

38 class StringConverter extends AbstractConverter
39         implements InstantConverter, PartialConverter, DurationConverter, PeriodConverter, IntervalConverter {
40
41     /**
42      * Singleton instance.
43      */

44     static final StringConverter INSTANCE = new StringConverter();
45
46     /**
47      * Restricted constructor.
48      */

49     protected StringConverter() {
50         super();
51     }
52
53     //-----------------------------------------------------------------------
54
/**
55      * Gets the millis, which is the ISO parsed string value.
56      *
57      * @param object the String to convert, must not be null
58      * @param chrono the chronology to use, non-null result of getChronology
59      * @return the millisecond value
60      * @throws IllegalArgumentException if the value if invalid
61      */

62     public long getInstantMillis(Object JavaDoc object, Chronology chrono) {
63         String JavaDoc str = (String JavaDoc) object;
64         DateTimeFormatter p = ISODateTimeFormat.dateTimeParser();
65         return p.withChronology(chrono).parseMillis(str);
66     }
67
68     /**
69      * Extracts the values of the partial from an object of this converter's type.
70      * This method checks if the parser has a zone, and uses it if present.
71      * This is most useful for parsing local times with UTC.
72      *
73      * @param fieldSource a partial that provides access to the fields.
74      * This partial may be incomplete and only getFieldType(int) should be used
75      * @param object the object to convert
76      * @param chrono the chronology to use, which is the non-null result of getChronology()
77      * @param parser the parser to use, may be null
78      * @return the array of field values that match the fieldSource, must be non-null valid
79      * @throws ClassCastException if the object is invalid
80      * @throws IllegalArgumentException if the value if invalid
81      * @since 1.3
82      */

83     public int[] getPartialValues(ReadablePartial fieldSource, Object JavaDoc object, Chronology chrono, DateTimeFormatter parser) {
84         if (parser.getZone() != null) {
85             chrono = chrono.withZone(parser.getZone());
86         }
87         long millis = parser.withChronology(chrono).parseMillis((String JavaDoc) object);
88         return chrono.get(fieldSource, millis);
89     }
90
91     //-----------------------------------------------------------------------
92
/**
93      * Gets the duration of the string using the standard type.
94      * This matches the toString() method of ReadableDuration.
95      *
96      * @param object the String to convert, must not be null
97      * @throws ClassCastException if the object is invalid
98      */

99     public long getDurationMillis(Object JavaDoc object) {
100         // parse here because duration could be bigger than the int supported
101
// by the period parser
102
String JavaDoc original = (String JavaDoc) object;
103         String JavaDoc str = original;
104         int len = str.length();
105         if (len >= 4 &&
106             (str.charAt(0) == 'P' || str.charAt(0) == 'p') &&
107             (str.charAt(1) == 'T' || str.charAt(1) == 't') &&
108             (str.charAt(len - 1) == 'S' || str.charAt(len - 1) == 's')) {
109             // ok
110
} else {
111             throw new IllegalArgumentException JavaDoc("Invalid format: \"" + original + '"');
112         }
113         str = str.substring(2, len - 1);
114         int dot = -1;
115         for (int i = 0; i < str.length(); i++) {
116             if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') ||
117                 (i == 0 && str.charAt(0) == '-')) {
118                 // ok
119
} else if (i > 0 && str.charAt(i) == '.' && dot == -1) {
120                 // ok
121
dot = i;
122             } else {
123                 throw new IllegalArgumentException JavaDoc("Invalid format: \"" + original + '"');
124             }
125         }
126         long millis = 0, seconds = 0;
127         if (dot > 0) {
128             seconds = Long.parseLong(str.substring(0, dot));
129             str = str.substring(dot + 1);
130             if (str.length() != 3) {
131                 str = (str + "000").substring(0, 3);
132             }
133             millis = Integer.parseInt(str);
134         } else {
135             seconds = Long.parseLong(str);
136         }
137         if (seconds < 0) {
138             return FieldUtils.safeAdd(FieldUtils.safeMultiply(seconds, 1000), -millis);
139         } else {
140             return FieldUtils.safeAdd(FieldUtils.safeMultiply(seconds, 1000), millis);
141         }
142     }
143
144     //-----------------------------------------------------------------------
145
/**
146      * Extracts duration values from an object of this converter's type, and
147      * sets them into the given ReadWritableDuration.
148      *
149      * @param period period to get modified
150      * @param object the String to convert, must not be null
151      * @param chrono the chronology to use
152      * @return the millisecond duration
153      * @throws ClassCastException if the object is invalid
154      */

155     public void setInto(ReadWritablePeriod period, Object JavaDoc object, Chronology chrono) {
156         String JavaDoc str = (String JavaDoc) object;
157         PeriodFormatter parser = ISOPeriodFormat.standard();
158         period.clear();
159         int pos = parser.parseInto(period, str, 0);
160         if (pos < str.length()) {
161             if (pos < 0) {
162                 // Parse again to get a better exception thrown.
163
parser.withParseType(period.getPeriodType()).parseMutablePeriod(str);
164             }
165             throw new IllegalArgumentException JavaDoc("Invalid format: \"" + str + '"');
166         }
167     }
168
169     //-----------------------------------------------------------------------
170
/**
171      * Sets the value of the mutable interval from the string.
172      *
173      * @param writableInterval the interval to set
174      * @param object the String to convert, must not be null
175      * @param chrono the chronology to use, may be null
176      */

177     public void setInto(ReadWritableInterval writableInterval, Object JavaDoc object, Chronology chrono) {
178         String JavaDoc str = (String JavaDoc) object;
179
180         int separator = str.indexOf('/');
181         if (separator < 0) {
182             throw new IllegalArgumentException JavaDoc("Format requires a '/' separator: " + str);
183         }
184
185         String JavaDoc leftStr = str.substring(0, separator);
186         if (leftStr.length() <= 0) {
187             throw new IllegalArgumentException JavaDoc("Format invalid: " + str);
188         }
189         String JavaDoc rightStr = str.substring(separator + 1);
190         if (rightStr.length() <= 0) {
191             throw new IllegalArgumentException JavaDoc("Format invalid: " + str);
192         }
193
194         DateTimeFormatter dateTimeParser = ISODateTimeFormat.dateTimeParser();
195         dateTimeParser = dateTimeParser.withChronology(chrono);
196         PeriodFormatter periodParser = ISOPeriodFormat.standard();
197         long startInstant = 0, endInstant = 0;
198         Period period = null;
199         Chronology parsedChrono = null;
200         
201         // before slash
202
char c = leftStr.charAt(0);
203         if (c == 'P' || c == 'p') {
204             period = periodParser.withParseType(getPeriodType(leftStr)).parsePeriod(leftStr);
205         } else {
206             DateTime start = dateTimeParser.parseDateTime(leftStr);
207             startInstant = start.getMillis();
208             parsedChrono = start.getChronology();
209         }
210         
211         // after slash
212
c = rightStr.charAt(0);
213         if (c == 'P' || c == 'p') {
214             if (period != null) {
215                 throw new IllegalArgumentException JavaDoc("Interval composed of two durations: " + str);
216             }
217             period = periodParser.withParseType(getPeriodType(rightStr)).parsePeriod(rightStr);
218             chrono = (chrono != null ? chrono : parsedChrono);
219             endInstant = chrono.add(period, startInstant, 1);
220         } else {
221             DateTime end = dateTimeParser.parseDateTime(rightStr);
222             endInstant = end.getMillis();
223             parsedChrono = (parsedChrono != null ? parsedChrono : end.getChronology());
224             chrono = (chrono != null ? chrono : parsedChrono);
225             if (period != null) {
226                 startInstant = chrono.add(period, endInstant, -1);
227             }
228         }
229         
230         writableInterval.setInterval(startInstant, endInstant);
231         writableInterval.setChronology(chrono);
232     }
233
234     //-----------------------------------------------------------------------
235
/**
236      * Returns String.class.
237      *
238      * @return String.class
239      */

240     public Class JavaDoc getSupportedType() {
241         return String JavaDoc.class;
242     }
243
244 }
245
Popular Tags