1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 package org.exolab.castor.types;
37
38 import java.text.SimpleDateFormat;
39 import java.text.ParseException;
40
41
42
43
44
45
46
47
48
49
50
51 public class GYearMonth extends DateTimeBase {
52
53
54 private static final long serialVersionUID = -8864050276805766473L;
55
56
57 private static final String YEARMONTH_FORMAT = "yyyy-MM";
58
59 private static final String BAD_GYEARMONTH = "Bad gYearMonth format: ";
60
61
62
63
64 public GYearMonth() {
65
66 }
67
68
69
70
71
72
73
74
75 public GYearMonth(short century, short year, short month) {
76 this.setCentury(century);
77 this.setYear(year);
78 this.setMonth(month);
79 }
80
81
82
83
84
85
86
87 public GYearMonth(int year, int month) {
88 short century = (short) (year / 100);
89 year = year % 100;
90 setCentury(century);
91 setYear((short) year);
92 setMonth((short) month);
93 }
94
95
96
97
98
99
100
101 public GYearMonth(short[] values) {
102 setValues(values);
103 }
104
105
106
107
108
109
110
111
112 public GYearMonth(String gyearMonth) throws ParseException {
113 parseGYearMonthInternal(gyearMonth, this);
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 public void setValues(short[] values) {
131 if (values.length != 3) {
132 throw new IllegalArgumentException("GYearMonth#setValues: not the right number of values");
133 }
134 this.setCentury(values[0]);
135 this.setYear(values[1]);
136 this.setMonth(values[2]);
137 }
138
139
140
141
142
143
144
145
146 public short[] getValues() {
147 short[] result = new short[3];
148 result[0] = this.getCentury();
149 result[1] = this.getYear();
150 result[2] = this.getMonth();
151 return result;
152 }
153
154
155
156
157
158
159 public java.util.Date toDate() {
160 SimpleDateFormat df = new SimpleDateFormat(YEARMONTH_FORMAT);
161 setDateFormatTimeZone(df);
162
163 java.util.Date date = null;
164 try {
165 date = df.parse(this.toString());
166 } catch (ParseException e) {
167
168 e.printStackTrace();
169 return null;
170 }
171
172 return date;
173 }
174
175
176
177
178
179
180
181 public String toString() {
182 StringBuffer result = new StringBuffer();
183
184 if (isNegative()) {
185 result.append('-');
186 }
187
188 if ((this.getCentury() / 10) == 0) {
189 result.append(0);
190 }
191 result.append(this.getCentury());
192 if ((this.getYear() / 10) == 0) {
193 result.append(0);
194 }
195 result.append(this.getYear());
196
197 result.append('-');
198
199 if ((this.getMonth() / 10) == 0) {
200 result.append(0);
201 }
202 result.append(this.getMonth());
203
204 appendTimeZoneString(result);
205
206 return result.toString();
207 }
208
209
210
211
212
213
214
215
216
217 public static Object parse(String str) throws ParseException {
218 return parseGYearMonth(str);
219 }
220
221
222
223
224
225
226
227
228
229 public static GYearMonth parseGYearMonth(String str) throws ParseException {
230 GYearMonth result = new GYearMonth();
231 return parseGYearMonthInternal(str, result);
232 }
233
234 private static GYearMonth parseGYearMonthInternal(String str, GYearMonth result)
235 throws ParseException {
236 if (str == null) {
237 throw new IllegalArgumentException("The string to be parsed must not be null.");
238 }
239
240 if (result == null) {
241 result = new GYearMonth();
242 }
243
244 char[] chars = str.toCharArray();
245 int idx = 0;
246
247 if (chars[idx] == '-') {
248 result.setNegative();
249 idx++;
250 }
251
252
253 if (!Character.isDigit(chars[idx]) || !Character.isDigit(chars[idx + 1])
254 || !Character.isDigit(chars[idx + 2]) || !Character.isDigit(chars[idx + 3])) {
255 throw new ParseException(
256 BAD_GYEARMONTH + str + "\nA gYearMonth must follow the pattern CCYY(Z|((+|-)hh:mm)).",
257 idx);
258 }
259
260 short value1 = (short) ((chars[idx] - '0') * 10 + (chars[idx + 1] - '0'));
261 short value2 = (short) ((chars[idx + 2] - '0') * 10 + (chars[idx + 3] - '0'));
262 if (value1 == 0 && value2 == 0) {
263 throw new ParseException(BAD_GYEARMONTH + str + "\n'0000' is not allowed as a year.", idx);
264 }
265
266 result.setCentury(value1);
267 result.setYear(value2);
268
269 idx += 4;
270
271 if (chars[idx] != '-') {
272 throw new ParseException(
273 BAD_GYEARMONTH + str + "\nA gYearMonth must follow the pattern CCYY(Z|((+|-)hh:mm)).",
274 idx);
275 }
276
277 idx++;
278
279
280 if (!Character.isDigit(chars[idx]) || !Character.isDigit(chars[idx + 1])) {
281 throw new ParseException(BAD_GYEARMONTH + str + "\nThe Month must be 2 digits long", idx);
282 }
283
284 value1 = (short) ((chars[idx] - '0') * 10 + (chars[idx + 1] - '0'));
285 result.setMonth(value1);
286
287 idx += 2;
288
289 parseTimeZone(str, result, chars, idx, BAD_GYEARMONTH);
290
291 return result;
292 }
293
294
295
296 public boolean hasDay() {
297 return false;
298 }
299
300 public short getDay() {
301 String err = "org.exolab.castor.types.GYearMonth does not have a Day field.";
302 throw new UnsupportedOperationException(err);
303 }
304
305 public void setDay(short day) {
306 String err = "org.exolab.castor.types.GYearMonth does not have a Day field.";
307 throw new UnsupportedOperationException(err);
308 }
309
310 public boolean hasHour() {
311 return false;
312 }
313
314 public short getHour() {
315 String err = "org.exolab.castor.types.GYearMonth does not have an Hour field.";
316 throw new UnsupportedOperationException(err);
317 }
318
319 public void setHour(short hour) {
320 String err = "org.exolab.castor.types.GYearMonth does not have an Hour field.";
321 throw new UnsupportedOperationException(err);
322 }
323
324 public boolean hasMinute() {
325 return false;
326 }
327
328 public short getMinute() {
329 String err = "org.exolab.castor.types.GYearMonth does not have a Minute field.";
330 throw new UnsupportedOperationException(err);
331 }
332
333 public void setMinute(short minute) {
334 String err = "org.exolab.castor.types.GYearMonth does not have a Minute field.";
335 throw new UnsupportedOperationException(err);
336 }
337
338 public boolean hasSeconds() {
339 return false;
340 }
341
342 public short getSeconds() {
343 String err = "org.exolab.castor.types.GYearMonth does not have a Seconds field.";
344 throw new UnsupportedOperationException(err);
345 }
346
347 public void setSecond(short second) {
348 String err = "org.exolab.castor.types.GYearMonth does not have a Seconds field.";
349 throw new UnsupportedOperationException(err);
350 }
351
352 public boolean hasMilli() {
353 return false;
354 }
355
356 public short getMilli() {
357 String err = "org.exolab.castor.types.GYearMonth does not have a Milliseconds field.";
358 throw new UnsupportedOperationException(err);
359 }
360
361 public void setMilliSecond(short millisecond) {
362 String err = "org.exolab.castor.types.GYearMonth does not have a Milliseconds field.";
363 throw new UnsupportedOperationException(err);
364 }
365
366 }