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