001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.transforms;
014
015import static org.apache.juneau.utils.CalendarUtils.Format.*;
016
017import java.text.*;
018import java.util.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.parser.ParseException;
022import org.apache.juneau.transform.*;
023import org.apache.juneau.utils.*;
024
025/**
026 * Transforms {@link Date Dates} to {@link String Strings}.
027 *
028 * <h5 class='topic'>Behavior-specific subclasses</h5>
029 *
030 * The following direct subclasses are provided for convenience to the following formats:
031 * <ul>
032 *    <li>{@link ToString} - To {@link String Strings} using the {@code Date.toString()} method.
033 *    <li>{@link ISO8601DT} - To ISO8601 date-time strings.
034 *    <li>{@link ISO8601DTZ} - Same as {@link ISO8601DT}, except always serializes in GMT.
035 *    <li>{@link ISO8601DTP} - Same as {@link ISO8601DT} except with millisecond precision.
036 *    <li>{@link ISO8601DTPZ} - Same as {@link ISO8601DTZ} except with millisecond precision.
037 *    <li>{@link RFC2822DT} - To RFC2822 date-time strings.
038 *    <li>{@link RFC2822DTZ} - Same as {@link RFC2822DT}, except always serializes in GMT.
039 *    <li>{@link RFC2822D} - To RFC2822 date strings.
040 *    <li>{@link DateTimeSimple} - To simple <js>"yyyy/MM/dd HH:mm:ss"</js> date-time strings.
041 *    <li>{@link DateSimple} - To simple <js>"yyyy/MM/dd"</js> date strings.
042 *    <li>{@link TimeSimple} - To simple <js>"HH:mm:ss"</js> time strings.
043 *    <li>{@link DateFull} - To {@link DateFormat#FULL} date strings.
044 *    <li>{@link DateLong} - To {@link DateFormat#LONG} date strings.
045 *    <li>{@link DateMedium} - To {@link DateFormat#MEDIUM} date strings.
046 *    <li>{@link DateShort} - To {@link DateFormat#SHORT} date strings.
047 *    <li>{@link TimeFull} - To {@link DateFormat#FULL} time strings.
048 *    <li>{@link TimeLong} - To {@link DateFormat#LONG} time strings.
049 *    <li>{@link TimeMedium} - To {@link DateFormat#MEDIUM} time strings.
050 *    <li>{@link TimeShort} - To {@link DateFormat#SHORT} time strings.
051 *    <li>{@link DateTimeFull} - To {@link DateFormat#FULL} date-time strings.
052 *    <li>{@link DateTimeLong} - To {@link DateFormat#LONG} date-time strings.
053 *    <li>{@link DateTimeMedium} - To {@link DateFormat#MEDIUM} date-time strings.
054 *    <li>{@link DateTimeShort} - To {@link DateFormat#SHORT} date-time strings.
055 * </ul>
056 */
057public class DateSwap extends StringSwap<Date> {
058
059   /**
060    * Transforms {@link Date Dates} to {@link String Strings} using the {@code Date.toString()} method.
061    *
062    * <h5 class='section'>Example Output:</h5>
063    * <ul>
064    *    <li><js>"Wed Jul 04 15:30:45 EST 2001"</js>
065    * </ul>
066    */
067   public static class ToString extends DateSwap {
068
069      @Override /* PojoSwap */
070      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
071         return convert(CalendarUtils.parseDate(o, TO_STRING, session.getLocale(), session.getTimeZone()), hint);
072      }
073
074      @Override /* PojoSwap */
075      public String swap(BeanSession session, Date o) throws Exception {
076         return CalendarUtils.serialize(o, TO_STRING, session.getLocale(), session.getTimeZone());
077      }
078   }
079
080   /**
081    * Transforms {@link Calendar Calendars} to ISO8601 date-time strings.
082    *
083    * <h5 class='section'>Example Output:</h5>
084    * <ul>
085    *    <li><js>"2001-07-04T15:30:45-05:00"</js>
086    *    <li><js>"2001-07-04T15:30:45Z"</js>
087    * </ul>
088    *
089    * <h5 class='topic'>Example input:</h5>
090    * <ul>
091    *    <li><js>"2001-07-04T15:30:45-05:00"</js>
092    *    <li><js>"2001-07-04T15:30:45Z"</js>
093    *    <li><js>"2001-07-04T15:30:45.1Z"</js>
094    *    <li><js>"2001-07-04T15:30Z"</js>
095    *    <li><js>"2001-07-04"</js>
096    *    <li><js>"2001-07"</js>
097    *    <li><js>"2001"</js>
098    * </ul>
099    */
100   public static class ISO8601DT extends DateSwap {
101
102      @Override /* PojoSwap */
103      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
104         return convert(CalendarUtils.parseDate(o, ISO8601_DT, session.getLocale(), session.getTimeZone()), hint);
105      }
106
107      @Override /* PojoSwap */
108      public String swap(BeanSession session, Date o) throws Exception {
109         return CalendarUtils.serialize(o, ISO8601_DT, session.getLocale(), session.getTimeZone());
110      }
111   }
112
113   /**
114    * Transforms {@link Date Dates} to ISO8601 date-time-local strings.
115    *
116    * <h5 class='section'>Example Output:</h5>
117    * <ul>
118    *    <li><js>"2001-07-04T15:30:45"</js>
119    * </ul>
120    *
121    * <h5 class='topic'>Example input:</h5>
122    * <ul>
123    *    <li><js>"2001-07-04T15:30:45"</js>
124    *    <li><js>"2001-07-04T15:30:45.1"</js>
125    *    <li><js>"2001-07-04T15:30"</js>
126    *    <li><js>"2001-07-04"</js>
127    *    <li><js>"2001-07"</js>
128    *    <li><js>"2001"</js>
129    * </ul>
130    */
131   public static class ISO8601DTL extends DateSwap {
132
133      @Override /* PojoSwap */
134      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
135         return convert(CalendarUtils.parseDate(o, ISO8601_DTL, session.getLocale(), session.getTimeZone()), hint);
136      }
137
138      @Override /* PojoSwap */
139      public String swap(BeanSession session, Date o) throws Exception {
140         return CalendarUtils.serialize(o, ISO8601_DTL, session.getLocale(), session.getTimeZone());
141      }
142   }
143
144   /**
145    * Same as {@link ISO8601DT}, except always serializes in GMT.
146    *
147    * <h5 class='section'>Example Output:</h5>
148    * <js>"2001-07-04T15:30:45Z"</js>
149    */
150   public static class ISO8601DTZ extends DateSwap {
151
152      @Override /* PojoSwap */
153      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
154         return CalendarUtils.parseDate(o, ISO8601_DTZ, session.getLocale(), session.getTimeZone());
155      }
156
157      @Override /* PojoSwap */
158      public String swap(BeanSession session, Date o) throws Exception {
159         return CalendarUtils.serialize(o, ISO8601_DTZ, session.getLocale(), session.getTimeZone());
160      }
161   }
162
163   /**
164    * Same as {@link CalendarSwap.ISO8601DT} except serializes to millisecond precision.
165    *
166    * <h5 class='section'>Example Output:</h5>
167    * <js>"2001-07-04T15:30:45.123Z"</js>
168    */
169   public static class ISO8601DTP extends ISO8601DT {
170
171      @Override /* PojoSwap */
172      public String swap(BeanSession session, Date o) throws Exception {
173         return CalendarUtils.serialize(o, ISO8601_DTP, session.getLocale(), session.getTimeZone());
174      }
175   }
176
177   /**
178    * Same as {@link CalendarSwap.ISO8601DTZ} except serializes to millisecond precision.
179    *
180    * <h5 class='section'>Example Output:</h5>
181    * <js>"2001-07-04T15:30:45.123"</js>
182    */
183   public static class ISO8601DTPZ extends ISO8601DTZ {
184
185      @Override /* PojoSwap */
186      public String swap(BeanSession session, Date o) throws Exception {
187         return CalendarUtils.serialize(o, ISO8601_DTPZ, session.getLocale(), session.getTimeZone());
188      }
189   }
190
191   /**
192    * ISO8601 date only.
193    *
194    * <h5 class='section'>Example Output:</h5>
195    * <js>"2001-07-04"</js>
196    */
197   public static class ISO8601D extends DateSwap {
198
199      @Override /* PojoSwap */
200      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
201         return CalendarUtils.parseDate(o, ISO8601_D, session.getLocale(), session.getTimeZone());
202      }
203
204      @Override /* PojoSwap */
205      public String swap(BeanSession session, Date o) throws Exception {
206         return CalendarUtils.serialize(o, ISO8601_D, session.getLocale(), session.getTimeZone());
207      }
208   }
209
210   /**
211    * Transforms {@link Date Dates} to RFC2822 date-time strings.
212    *
213    * <h5 class='section'>Example Output:</h5>
214    * <ul>
215    *    <li><js>"Sat, 03 Mar 2001 10:11:12 +0000"</js> <jc>// en_US</jc>
216    *    <li><js>"土, 03 3 2001 10:11:12 +0000"</js> <jc>// ja_JP</jc>
217    *    <li><js>"토, 03 3월 2001 10:11:12 +0000"</js> <jc>// ko_KR</jc>
218    * </ul>
219    */
220   public static class RFC2822DT extends DateSwap {
221
222      @Override /* PojoSwap */
223      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
224         return CalendarUtils.parseDate(o, RFC2822_DT, session.getLocale(), session.getTimeZone());
225      }
226
227      @Override /* PojoSwap */
228      public String swap(BeanSession session, Date o) throws Exception {
229         return CalendarUtils.serialize(o, RFC2822_DT, session.getLocale(), session.getTimeZone());
230      }
231   }
232
233   /**
234    * Same as {@link DateSwap.RFC2822DT}, except always serializes in GMT.
235    *
236    * <h5 class='section'>Example Output:</h5>
237    * <ul>
238    *    <li><js>"Sat, 03 Mar 2001 10:11:12 GMT"</js> <jc>// en_US</jc>
239    *    <li><js>"土, 03 3 2001 10:11:12 GMT"</js> <jc>// ja_JP</jc>
240    *    <li><js>"토, 03 3월 2001 10:11:12 GMT"</js> <jc>// ko_KR</jc>
241    * </ul>
242    */
243   public static class RFC2822DTZ extends DateSwap {
244
245      @Override /* PojoSwap */
246      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
247         return CalendarUtils.parseDate(o, RFC2822_DTZ, session.getLocale(), session.getTimeZone());
248      }
249
250      @Override /* PojoSwap */
251      public String swap(BeanSession session, Date o) throws Exception {
252         return CalendarUtils.serialize(o, RFC2822_DTZ, session.getLocale(), session.getTimeZone());
253      }
254   }
255
256   /**
257    * Transforms {@link Date Dates} to RFC2822 date strings.
258    *
259    * <h5 class='section'>Example Output:</h5>
260    * <ul>
261    *    <li><js>"03 Mar 2001"</js> <jc>// en_US</jc>
262    *    <li><js>"03 3 2001"</js> <jc>// ja_JP</jc>
263    *    <li><js>"03 3월 2001"</js> <jc>// ko_KR</jc>
264    * </ul>
265    */
266   public static class RFC2822D extends DateSwap {
267
268      @Override /* PojoSwap */
269      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
270         return CalendarUtils.parseDate(o, RFC2822_D, session.getLocale(), session.getTimeZone());
271      }
272
273      @Override /* PojoSwap */
274      public String swap(BeanSession session, Date o) throws Exception {
275         return CalendarUtils.serialize(o, RFC2822_D, session.getLocale(), session.getTimeZone());
276      }
277   }
278
279   /**
280    * Transforms {@link Date Dates} to simple <js>"yyyy/MM/dd HH:mm:ss"</js> date-time strings.
281    *
282    * <h5 class='section'>Example Output:</h5>
283    * <ul>
284    *    <li><js>"2001/03/03 10:11:12"</js>
285    * </ul>
286    */
287   public static class DateTimeSimple extends DateSwap {
288
289      @Override /* PojoSwap */
290      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
291         return CalendarUtils.parseDate(o, SIMPLE_DT, session.getLocale(), session.getTimeZone());
292      }
293
294      @Override /* PojoSwap */
295      public String swap(BeanSession session, Date o) throws Exception {
296         return CalendarUtils.serialize(o, SIMPLE_DT, session.getLocale(), session.getTimeZone());
297      }
298   }
299
300   /**
301    * Transforms {@link Date Dates} to simple <js>"yyyy/MM/dd"</js> date strings.
302    *
303    * <h5 class='section'>Example Output:</h5>
304    * <ul>
305    *    <li><js>"2001/03/03"</js>
306    * </ul>
307    */
308   public static class DateSimple extends DateSwap {
309
310      @Override /* PojoSwap */
311      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
312         return CalendarUtils.parseDate(o, SIMPLE_D, session.getLocale(), session.getTimeZone());
313      }
314
315      @Override /* PojoSwap */
316      public String swap(BeanSession session, Date o) throws Exception {
317         return CalendarUtils.serialize(o, SIMPLE_D, session.getLocale(), session.getTimeZone());
318      }
319   }
320
321   /**
322    * Transforms {@link Date Dates} to simple <js>"HH:mm:ss"</js> time strings.
323    *
324    * <h5 class='section'>Example Output:</h5>
325    * <ul>
326    *    <li><js>"10:11:12"</js>
327    * </ul>
328    */
329   public static class TimeSimple extends DateSwap {
330
331      @Override /* PojoSwap */
332      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
333         return CalendarUtils.parseDate(o, SIMPLE_T, session.getLocale(), session.getTimeZone());
334      }
335
336      @Override /* PojoSwap */
337      public String swap(BeanSession session, Date o) throws Exception {
338         return CalendarUtils.serialize(o, SIMPLE_T, session.getLocale(), session.getTimeZone());
339      }
340   }
341
342   /**
343    * Transforms {@link Date Dates} to {@link DateFormat#FULL} date strings.
344    *
345    * <h5 class='section'>Example Output:</h5>
346    * <ul>
347    *    <li><js>"Saturday, March 3, 2001"</js> <jc>// en_US</jc>
348    *    <li><js>"2001年3月3日"</js> <jc>// ja_JP</jc>
349    *    <li><js>"2001년 3월 3일 토요일"</js> <jc>// ko_KR</jc>
350    * </ul>
351    */
352   public static class DateFull extends DateSwap {
353
354      @Override /* PojoSwap */
355      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
356         return CalendarUtils.parseDate(o, FULL_D, session.getLocale(), session.getTimeZone());
357      }
358
359      @Override /* PojoSwap */
360      public String swap(BeanSession session, Date o) throws Exception {
361         return CalendarUtils.serialize(o, FULL_D, session.getLocale(), session.getTimeZone());
362      }
363   }
364
365   /**
366    * Transforms {@link Date Dates} to {@link DateFormat#LONG} date strings.
367    *
368    * <h5 class='section'>Example Output:</h5>
369    * <ul>
370    *    <li><js>"March 3, 2001"</js> <jc>// en_US</jc>
371    *    <li><js>"2001/03/03"</js> <jc>// ja_JP</jc>
372    *    <li><js>"2001년 3월 3일 (토)"</js> <jc>// ko_KR</jc>
373    * </ul>
374    */
375   public static class DateLong extends DateSwap {
376
377      @Override /* PojoSwap */
378      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
379         return CalendarUtils.parseDate(o, LONG_D, session.getLocale(), session.getTimeZone());
380      }
381
382      @Override /* PojoSwap */
383      public String swap(BeanSession session, Date o) throws Exception {
384         return CalendarUtils.serialize(o, LONG_D, session.getLocale(), session.getTimeZone());
385      }
386   }
387
388   /**
389    * Transforms {@link Date Dates} to {@link DateFormat#MEDIUM} date strings.
390    *
391    * <h5 class='section'>Example Output:</h5>
392    * <ul>
393    *    <li><js>"Mar 3, 2001"</js> <jc>// en_US</jc>
394    *    <li><js>"2001/03/03"</js> <jc>// ja_JP</jc>
395    *    <li><js>"2001. 3. 3"</js> <jc>// ko_KR</jc>
396    * </ul>
397    */
398   public static class DateMedium extends DateSwap {
399
400      @Override /* PojoSwap */
401      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
402         return CalendarUtils.parseDate(o, MEDIUM_D, session.getLocale(), session.getTimeZone());
403      }
404
405      @Override /* PojoSwap */
406      public String swap(BeanSession session, Date o) throws Exception {
407         return CalendarUtils.serialize(o, MEDIUM_D, session.getLocale(), session.getTimeZone());
408      }
409   }
410
411   /**
412    * Transforms {@link Date Dates} to {@link DateFormat#SHORT} date strings.
413    *
414    * <h5 class='section'>Example Output:</h5>
415    * <ul>
416    *    <li><js>"3/3/01"</js> <jc>// en_US</jc>
417    *    <li><js>"01/03/03"</js> <jc>// ja_JP</jc>
418    *    <li><js>"01. 3. 3"</js> <jc>// ko_KR</jc>
419    * </ul>
420    */
421   public static class DateShort extends DateSwap {
422
423      @Override /* PojoSwap */
424      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
425         return CalendarUtils.parseDate(o, SHORT_D, session.getLocale(), session.getTimeZone());
426      }
427
428      @Override /* PojoSwap */
429      public String swap(BeanSession session, Date o) throws Exception {
430         return CalendarUtils.serialize(o, SHORT_D, session.getLocale(), session.getTimeZone());
431      }
432   }
433
434   /**
435    * Transforms {@link Date Dates} to {@link DateFormat#FULL} time strings.
436    *
437    * <h5 class='section'>Example Output:</h5>
438    * <ul>
439    *    <li><js>"10:11:12 AM GMT"</js> <jc>// en_US</jc>
440    *    <li><js>"10時11分12秒 GMT"</js> <jc>// ja_JP</jc>
441    *    <li><js>"오전 10시 11분 12초 GMT"</js> <jc>// ko_KR</jc>
442    * </ul>
443    */
444   public static class TimeFull extends DateSwap {
445
446      @Override /* PojoSwap */
447      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
448         return CalendarUtils.parseDate(o, FULL_T, session.getLocale(), session.getTimeZone());
449      }
450
451      @Override /* PojoSwap */
452      public String swap(BeanSession session, Date o) throws Exception {
453         return CalendarUtils.serialize(o, FULL_T, session.getLocale(), session.getTimeZone());
454      }
455   }
456
457   /**
458    * Transforms {@link Date Dates} to {@link DateFormat#LONG} time strings.
459    *
460    * <h5 class='section'>Example Output:</h5>
461    * <ul>
462    *    <li><js>"10:11:12 AM GMT"</js> <jc>// en_US</jc>
463    *    <li><js>"10:11:12 GMT"</js> <jc>// ja_JP</jc>
464    *    <li><js>"오전 10시 11분 12초"</js> <jc>// ko_KR</jc>
465    * </ul>
466    */
467   public static class TimeLong extends DateSwap {
468
469      @Override /* PojoSwap */
470      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
471         return CalendarUtils.parseDate(o, LONG_T, session.getLocale(), session.getTimeZone());
472      }
473
474      @Override /* PojoSwap */
475      public String swap(BeanSession session, Date o) throws Exception {
476         return CalendarUtils.serialize(o, LONG_T, session.getLocale(), session.getTimeZone());
477      }
478   }
479
480   /**
481    * Transforms {@link Date Dates} to {@link DateFormat#MEDIUM} time strings.
482    *
483    * <h5 class='section'>Example Output:</h5>
484    * <ul>
485    *    <li><js>"10:11:12 AM"</js> <jc>// en_US</jc>
486    *    <li><js>"10:11:12"</js> <jc>// ja_JP</jc>
487    *    <li><js>"오전 10:11:12"</js> <jc>// ko_KR</jc>
488    * </ul>
489    */
490   public static class TimeMedium extends DateSwap {
491
492      @Override /* PojoSwap */
493      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
494         return CalendarUtils.parseDate(o, MEDIUM_T, session.getLocale(), session.getTimeZone());
495      }
496
497      @Override /* PojoSwap */
498      public String swap(BeanSession session, Date o) throws Exception {
499         return CalendarUtils.serialize(o, MEDIUM_T, session.getLocale(), session.getTimeZone());
500      }
501   }
502
503   /**
504    * Transforms {@link Date Dates} to {@link DateFormat#SHORT} time strings.
505    *
506    * <h5 class='section'>Example Output:</h5>
507    * <ul>
508    *    <li><js>"10:11 AM"</js> <jc>// en_US</jc>
509    *    <li><js>"10:11 AM"</js> <jc>// ja_JP</jc>
510    *    <li><js>"오전 10:11"</js> <jc>// ko_KR</jc>
511    * </ul>
512    */
513   public static class TimeShort extends DateSwap {
514
515      @Override /* PojoSwap */
516      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
517         return CalendarUtils.parseDate(o, SHORT_T, session.getLocale(), session.getTimeZone());
518      }
519
520      @Override /* PojoSwap */
521      public String swap(BeanSession session, Date o) throws Exception {
522         return CalendarUtils.serialize(o, SHORT_T, session.getLocale(), session.getTimeZone());
523      }
524   }
525
526   /**
527    * Transforms {@link Date Dates} to {@link DateFormat#FULL} date-time strings.
528    *
529    * <h5 class='section'>Example Output:</h5>
530    * <ul>
531    *    <li><js>"Saturday, March 3, 2001 10:11:12 AM GMT"</js> <jc>// en_US</jc>
532    *    <li><js>"2001年3月3日 10時11分12秒 GMT"</js> <jc>// ja_JP</jc>
533    *    <li><js>"2001년 3월 3일 토요일 오전 10시 11분 12초 GMT"</js> <jc>// ko_KR</jc>
534    * </ul>
535    */
536   public static class DateTimeFull extends DateSwap {
537
538      @Override /* PojoSwap */
539      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
540         return CalendarUtils.parseDate(o, FULL_DT, session.getLocale(), session.getTimeZone());
541      }
542
543      @Override /* PojoSwap */
544      public String swap(BeanSession session, Date o) throws Exception {
545         return CalendarUtils.serialize(o, FULL_DT, session.getLocale(), session.getTimeZone());
546      }
547   }
548
549   /**
550    * Transforms {@link Date Dates} to {@link DateFormat#LONG} date-time strings.
551    *
552    * <h5 class='section'>Example Output:</h5>
553    * <ul>
554    *    <li><js>"March 3, 2001 10:11:12 AM GMT"</js> <jc>// en_US</jc>
555    *    <li><js>"2001/03/03 10:11:12 GMT"</js> <jc>// ja_JP</jc>
556    *    <li><js>"2001년 3월 3일 (토) 오전 10시 11분 12초"</js> <jc>// ko_KR</jc>
557    * </ul>
558    */
559   public static class DateTimeLong extends DateSwap {
560
561      @Override /* PojoSwap */
562      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
563         return CalendarUtils.parseDate(o, LONG_DT, session.getLocale(), session.getTimeZone());
564      }
565
566      @Override /* PojoSwap */
567      public String swap(BeanSession session, Date o) throws Exception {
568         return CalendarUtils.serialize(o, LONG_DT, session.getLocale(), session.getTimeZone());
569      }
570   }
571
572   /**
573    * Transforms {@link Date Dates} to {@link DateFormat#MEDIUM} date-time strings.
574    *
575    * <h5 class='section'>Example Output:</h5>
576    * <ul>
577    *    <li><js>"Mar 3, 2001 10:11:12 AM"</js> <jc>// en_US</jc>
578    *    <li><js>"2001/03/03 10:11:12"</js> <jc>// ja_JP</jc>
579    *    <li><js>"2001. 3. 3 오전 10:11:12"</js> <jc>// ko_KR</jc>
580    * </ul>
581    */
582   public static class DateTimeMedium extends DateSwap {
583
584      @Override /* PojoSwap */
585      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
586         return CalendarUtils.parseDate(o, MEDIUM_DT, session.getLocale(), session.getTimeZone());
587      }
588
589      @Override /* PojoSwap */
590      public String swap(BeanSession session, Date o) throws Exception {
591         return CalendarUtils.serialize(o, MEDIUM_DT, session.getLocale(), session.getTimeZone());
592      }
593   }
594
595   /**
596    * Transforms {@link Date Dates} to {@link DateFormat#SHORT} date-time strings.
597    *
598    * <h5 class='section'>Example Output:</h5>
599    * <ul>
600    *    <li><js>"3/3/01 10:11 AM"</js> <jc>// en_US</jc>
601    *    <li><js>"01/03/03 10:11"</js> <jc>// ja_JP</jc>
602    *    <li><js>"01. 3. 3 오전 10:11"</js> <jc>// ko_KR</jc>
603    * </ul>
604    */
605   public static class DateTimeShort extends DateSwap {
606
607      @Override /* PojoSwap */
608      public Date unswap(BeanSession session, String o, ClassMeta<?> hint) throws Exception {
609         return CalendarUtils.parseDate(o, SHORT_DT, session.getLocale(), session.getTimeZone());
610      }
611
612      @Override /* PojoSwap */
613      public String swap(BeanSession session, Date o) throws Exception {
614         return CalendarUtils.serialize(o, SHORT_DT, session.getLocale(), session.getTimeZone());
615      }
616   }
617
618   static final Date convert(Date in, ClassMeta<?> hint) throws Exception {
619      if (in == null)
620         return null;
621      if (hint == null || hint.isInstance(in))
622         return in;
623      Class<?> c = hint.getInnerClass();
624      if (c == java.util.Date.class)
625         return in;
626      if (c == java.sql.Date.class)
627         return new java.sql.Date(in.getTime());
628      if (c == java.sql.Time.class)
629         return new java.sql.Time(in.getTime());
630      if (c == java.sql.Timestamp.class)
631         return new java.sql.Timestamp(in.getTime());
632      throw new ParseException("DateSwap is unable to narrow object of type ''{0}''", c);
633   }
634}