001 /******************************************************************************* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 *******************************************************************************/ 019 package org.apache.commons.convert; 020 021 import java.sql.Time; 022 import java.sql.Timestamp; 023 import java.text.DateFormat; 024 import java.text.ParseException; 025 import java.text.SimpleDateFormat; 026 import java.util.Calendar; 027 import java.util.Date; 028 import java.util.Locale; 029 import java.util.TimeZone; 030 031 /** Date/time <code>Converter</code> classes. */ 032 public class DateTimeConverters implements ConverterLoader { 033 034 /** 035 * Calendar format string: <code>EEE MMM dd HH:mm:ss.SSS z yyyy</code>. 036 */ 037 public static final String CALENDAR_FORMAT = "EEE MMM dd HH:mm:ss.SSS z yyyy"; 038 /** 039 * JDBC DATE format string: <code>yyyy-MM-dd</code>. 040 */ 041 public static final String JDBC_DATE_FORMAT = "yyyy-MM-dd"; 042 /** 043 * JDBC TIME format string: <code>HH:mm:ss</code>. 044 */ 045 public static final String JDBC_TIME_FORMAT = "HH:mm:ss"; 046 047 /** 048 * Returns an initialized DateFormat object. 049 * 050 * @param tz 051 * @return DateFormat object 052 */ 053 protected static DateFormat toDateFormat(TimeZone tz) { 054 DateFormat df = new SimpleDateFormat(JDBC_DATE_FORMAT); 055 df.setTimeZone(tz); 056 return df; 057 } 058 059 /** 060 * Returns an initialized DateFormat object. 061 * 062 * @param dateTimeFormat 063 * optional format string 064 * @param tz 065 * @param locale 066 * can be null if dateTimeFormat is not null 067 * @return DateFormat object 068 */ 069 protected static DateFormat toDateTimeFormat(String dateTimeFormat, TimeZone tz, Locale locale) { 070 DateFormat df = null; 071 if (Util.isEmpty(dateTimeFormat)) { 072 df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale); 073 } else { 074 df = new SimpleDateFormat(dateTimeFormat); 075 } 076 df.setTimeZone(tz); 077 return df; 078 } 079 080 /** 081 * Returns an initialized DateFormat object. 082 * 083 * @param tz 084 * @return DateFormat object 085 */ 086 protected static DateFormat toTimeFormat(TimeZone tz) { 087 DateFormat df = new SimpleDateFormat(JDBC_TIME_FORMAT); 088 df.setTimeZone(tz); 089 return df; 090 } 091 092 public void loadConverters() { 093 Converters.loadContainedConverters(DateTimeConverters.class); 094 Converters.registerConverter(new GenericDateToLong<java.util.Date>(java.util.Date.class)); 095 Converters.registerConverter(new GenericDateToLong<java.sql.Date>(java.sql.Date.class)); 096 Converters.registerConverter(new GenericDateToLong<java.sql.Time>(java.sql.Time.class)); 097 Converters.registerConverter(new GenericDateToLong<java.sql.Timestamp>(java.sql.Timestamp.class)); 098 Converters.registerConverter(new GenericSingletonToList<java.util.Calendar>(java.util.Calendar.class)); 099 Converters.registerConverter(new GenericSingletonToList<java.util.Date>(java.util.Date.class)); 100 Converters.registerConverter(new GenericSingletonToList<java.util.TimeZone>(java.util.TimeZone.class)); 101 Converters.registerConverter(new GenericSingletonToList<java.sql.Date>(java.sql.Date.class)); 102 Converters.registerConverter(new GenericSingletonToList<java.sql.Time>(java.sql.Time.class)); 103 Converters.registerConverter(new GenericSingletonToList<java.sql.Timestamp>(java.sql.Timestamp.class)); 104 Converters.registerConverter(new GenericSingletonToSet<java.util.Calendar>(java.util.Calendar.class)); 105 Converters.registerConverter(new GenericSingletonToSet<java.util.Date>(java.util.Date.class)); 106 Converters.registerConverter(new GenericSingletonToSet<java.util.TimeZone>(java.util.TimeZone.class)); 107 Converters.registerConverter(new GenericSingletonToSet<java.sql.Date>(java.sql.Date.class)); 108 Converters.registerConverter(new GenericSingletonToSet<java.sql.Time>(java.sql.Time.class)); 109 Converters.registerConverter(new GenericSingletonToSet<java.sql.Timestamp>(java.sql.Timestamp.class)); 110 } 111 112 /** 113 * An object that converts a <code>Calendar</code> to a <code>Date</code>. 114 */ 115 public static class CalendarToDate extends AbstractConverter<Calendar, Date> { 116 public CalendarToDate() { 117 super(Calendar.class, Date.class); 118 } 119 120 @Override 121 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 122 return Util.instanceOf(sourceClass, this.getSourceClass()) && Date.class.equals(targetClass); 123 } 124 125 public Date convert(Calendar obj) throws ConversionException { 126 return obj.getTime(); 127 } 128 } 129 130 /** 131 * An object that converts a <code>Calendar</code> to a <code>Long</code>. 132 */ 133 public static class CalendarToLong extends AbstractConverter<Calendar, Long> { 134 public CalendarToLong() { 135 super(Calendar.class, Long.class); 136 } 137 138 /** 139 * Returns the millisecond value of <code>obj</code>. 140 */ 141 public Long convert(Calendar obj) throws ConversionException { 142 return obj.getTimeInMillis(); 143 } 144 } 145 146 /** 147 * An object that converts a <code>Calendar</code> to a <code>String</code>. 148 */ 149 public static class CalendarToString extends AbstractLocalizedConverter<Calendar, String> { 150 public CalendarToString() { 151 super(Calendar.class, String.class); 152 } 153 154 /** 155 * Converts <code>obj</code> to a <code>String</code> formatted as 156 * {@link DateTimeConverters#CALENDAR_FORMAT}. The returned string is 157 * referenced to the default time zone. 158 */ 159 public String convert(Calendar obj) throws ConversionException { 160 DateFormat df = new SimpleDateFormat(CALENDAR_FORMAT); 161 df.setCalendar(obj); 162 return df.format(obj.getTime()); 163 } 164 165 /** 166 * Converts <code>obj</code> to a <code>String</code> using the supplied 167 * locale, time zone, and format string. If <code>formatString</code> is 168 * <code>null</code>, the string is formatted as 169 * {@link DateTimeConverters#CALENDAR_FORMAT}. 170 */ 171 public String convert(Calendar obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 172 DateFormat df = toDateTimeFormat(formatString == null ? CALENDAR_FORMAT : formatString, timeZone, locale); 173 df.setCalendar(obj); 174 return df.format(obj.getTime()); 175 } 176 } 177 178 /** 179 * An object that converts a <code>Calendar</code> to a <code>Timestamp</code>. 180 */ 181 public static class CalendarToTimestamp extends AbstractConverter<Calendar, Timestamp> { 182 public CalendarToTimestamp() { 183 super(Calendar.class, Timestamp.class); 184 } 185 186 @Override 187 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 188 return Util.instanceOf(sourceClass, this.getSourceClass()) && Timestamp.class.equals(targetClass); 189 } 190 191 public Timestamp convert(Calendar obj) throws ConversionException { 192 return new Timestamp(obj.getTimeInMillis()); 193 } 194 } 195 196 197 /** 198 * An object that converts a <code>Date</code> to a <code>Calendar</code>. 199 */ 200 public static class DateToCalendar extends GenericLocalizedConverter<Date, Calendar> { 201 public DateToCalendar() { 202 super(Date.class, Calendar.class); 203 } 204 205 public Calendar convert(Date obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 206 Calendar cal = Calendar.getInstance(timeZone, locale); 207 cal.setTime(obj); 208 return cal; 209 } 210 } 211 212 /** 213 * An object that converts a <code>java.util.Date</code> to a 214 * <code>java.sql.Date</code>. 215 */ 216 public static class DateToSqlDate extends AbstractConverter<Date, java.sql.Date> { 217 public DateToSqlDate() { 218 super(Date.class, java.sql.Date.class); 219 } 220 221 @Override 222 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 223 return (java.util.Date.class.equals(sourceClass) || java.sql.Timestamp.class.equals(sourceClass)) && java.sql.Date.class.equals(targetClass); 224 } 225 226 /** 227 * Returns <code>obj</code> converted to a <code>java.sql.Date</code>. 228 */ 229 @SuppressWarnings("deprecation") 230 public java.sql.Date convert(Date obj) throws ConversionException { 231 Calendar cal = Calendar.getInstance(); 232 cal.setTimeInMillis(obj.getTime()); 233 return new java.sql.Date(cal.get(Calendar.YEAR) - 1900, cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); 234 } 235 } 236 237 /** 238 * An object that converts a <code>java.util.Date</code> to a 239 * <code>java.sql.Time</code>. 240 */ 241 public static class DateToSqlTime extends AbstractConverter<java.util.Date, java.sql.Time> { 242 public DateToSqlTime() { 243 super(Date.class, java.sql.Time.class); 244 } 245 246 @Override 247 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 248 return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass(); 249 } 250 251 @SuppressWarnings("deprecation") 252 public java.sql.Time convert(Date obj) throws ConversionException { 253 Calendar cal = Calendar.getInstance(); 254 cal.setTimeInMillis(obj.getTime()); 255 return new java.sql.Time(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)); 256 } 257 } 258 259 /** 260 * An object that converts a <code>java.util.Date</code> to a 261 * <code>String</code>. 262 */ 263 public static class DateToString extends AbstractLocalizedConverter<Date, String> { 264 public DateToString() { 265 super(Date.class, String.class); 266 } 267 268 @Override 269 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 270 return Date.class.equals(sourceClass) && String.class.equals(targetClass); 271 } 272 273 /** 274 * Converts <code>obj</code> to a <code>String</code> formatted as 275 * {@link DateTimeConverters#CALENDAR_FORMAT}. The returned string is 276 * referenced to the default time zone. 277 */ 278 public String convert(Date obj) throws ConversionException { 279 DateFormat df = new SimpleDateFormat(CALENDAR_FORMAT); 280 return df.format(obj); 281 } 282 283 /** 284 * Converts <code>obj</code> to a <code>String</code> using the supplied 285 * locale, time zone, and format string. If <code>formatString</code> is 286 * <code>null</code>, the string is formatted as 287 * {@link DateTimeConverters#CALENDAR_FORMAT}. 288 */ 289 public String convert(Date obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 290 DateFormat df = toDateTimeFormat(formatString == null ? CALENDAR_FORMAT : formatString, timeZone, locale); 291 return df.format(obj); 292 } 293 } 294 295 /** 296 * An object that converts a <code>java.util.Date</code> to a 297 * <code>java.sql.Timestamp</code>. 298 */ 299 public static class DateToTimestamp extends AbstractConverter<Date, java.sql.Timestamp> { 300 public DateToTimestamp() { 301 super(Date.class, java.sql.Timestamp.class); 302 } 303 304 @Override 305 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 306 return (java.util.Date.class.equals(sourceClass) || java.sql.Timestamp.class.equals(sourceClass)) && java.sql.Timestamp.class.equals(targetClass); 307 } 308 309 /** 310 * Returns <code>obj</code> converted to a <code>java.sql.Timestamp</code>. 311 */ 312 public java.sql.Timestamp convert(Date obj) throws ConversionException { 313 return new java.sql.Timestamp(obj.getTime()); 314 } 315 } 316 317 /** 318 * An object that converts a <code>java.util.Date</code> (and its subclasses) to a 319 * <code>Long</code>. 320 */ 321 public static class GenericDateToLong<S extends Date> extends AbstractConverter<S, Long> { 322 public GenericDateToLong(Class<S> source) { 323 super(source, Long.class); 324 } 325 326 /** 327 * Returns the millisecond value of <code>obj</code>. 328 */ 329 public Long convert(S obj) throws ConversionException { 330 return obj.getTime(); 331 } 332 } 333 334 public static abstract class GenericLocalizedConverter<S, T> extends AbstractLocalizedConverter<S, T> { 335 protected GenericLocalizedConverter(Class<S> sourceClass, Class<T> targetClass) { 336 super(sourceClass, targetClass); 337 } 338 339 public T convert(S obj) throws ConversionException { 340 return convert(obj, Locale.getDefault(), TimeZone.getDefault(), null); 341 } 342 343 public T convert(S obj, Locale locale, TimeZone timeZone) throws ConversionException { 344 return convert(obj, locale, timeZone, null); 345 } 346 } 347 348 /** 349 * An object that converts a <code>Long</code> to a 350 * <code>Calendar</code>. 351 */ 352 public static class LongToCalendar extends AbstractLocalizedConverter<Long, Calendar> { 353 public LongToCalendar() { 354 super(Long.class, Calendar.class); 355 } 356 357 /** 358 * Returns <code>obj</code> converted to a <code>Calendar</code>, 359 * initialized with the default locale and time zone. 360 */ 361 public Calendar convert(Long obj) throws ConversionException { 362 Calendar cal = Calendar.getInstance(); 363 cal.setTimeInMillis(obj); 364 return cal; 365 } 366 367 /** 368 * Returns <code>obj</code> converted to a <code>Calendar</code>, 369 * initialized with the specified locale and time zone. The 370 * <code>formatString</code> parameter is ignored. 371 */ 372 public Calendar convert(Long obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 373 Calendar cal = Calendar.getInstance(timeZone, locale); 374 cal.setTimeInMillis(obj); 375 return cal; 376 } 377 } 378 379 /** 380 * An object that converts a <code>Long</code> to a 381 * <code>java.util.Date</code>. 382 */ 383 public static class LongToDate extends AbstractConverter<Long, Date> { 384 public LongToDate() { 385 super(Long.class, Date.class); 386 } 387 388 @Override 389 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 390 return Long.class.equals(sourceClass) && Date.class.equals(targetClass); 391 } 392 393 /** 394 * Returns <code>obj</code> converted to a <code>java.util.Date</code>. 395 */ 396 public Date convert(Long obj) throws ConversionException { 397 return new Date(obj.longValue()); 398 } 399 } 400 401 /** 402 * An object that converts a <code>Long</code> to a 403 * <code>java.sql.Date</code>. 404 */ 405 public static class LongToSqlDate extends AbstractConverter<Long, java.sql.Date> { 406 public LongToSqlDate() { 407 super(Long.class, java.sql.Date.class); 408 } 409 410 @Override 411 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 412 return Long.class.equals(sourceClass) && java.sql.Date.class.equals(targetClass); 413 } 414 415 /** 416 * Returns <code>obj</code> converted to a <code>java.sql.Date</code>. 417 */ 418 public java.sql.Date convert(Long obj) throws ConversionException { 419 return new java.sql.Date(obj.longValue()); 420 } 421 } 422 423 /** 424 * An object that converts a <code>Long</code> to a 425 * <code>java.sql.Time</code>. 426 */ 427 public static class LongToSqlTime extends AbstractConverter<Long, java.sql.Time> { 428 public LongToSqlTime() { 429 super(Long.class, java.sql.Time.class); 430 } 431 432 @Override 433 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 434 return Long.class.equals(sourceClass) && java.sql.Time.class.equals(targetClass); 435 } 436 437 /** 438 * Returns <code>obj</code> converted to a <code>java.sql.Time</code>. 439 */ 440 public java.sql.Time convert(Long obj) throws ConversionException { 441 return new java.sql.Time(obj.longValue()); 442 } 443 } 444 445 /** 446 * An object that converts a <code>Long</code> to a 447 * <code>java.sql.Timestamp</code>. 448 */ 449 public static class LongToTimestamp extends AbstractConverter<Long, java.sql.Timestamp> { 450 public LongToTimestamp() { 451 super(Long.class, java.sql.Timestamp.class); 452 } 453 454 @Override 455 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 456 return Long.class.equals(sourceClass) && java.sql.Timestamp.class.equals(targetClass); 457 } 458 459 /** 460 * Returns <code>obj</code> converted to a <code>java.sql.Timestamp</code>. 461 */ 462 public java.sql.Timestamp convert(Long obj) throws ConversionException { 463 return new java.sql.Timestamp(obj.longValue()); 464 } 465 } 466 467 /** 468 * An object that converts a <code>java.sql.Date</code> to a 469 * <code>java.util.Date</code>. 470 */ 471 public static class SqlDateToDate extends AbstractConverter<java.sql.Date, Date> { 472 public SqlDateToDate() { 473 super(java.sql.Date.class, Date.class); 474 } 475 476 @Override 477 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 478 return java.sql.Date.class.equals(sourceClass) && java.util.Date.class.equals(targetClass); 479 } 480 481 /** 482 * Returns <code>obj</code> converted to a <code>java.util.Date</code>. 483 */ 484 public Date convert(java.sql.Date obj) throws ConversionException { 485 return new Date(obj.getTime()); 486 } 487 } 488 489 /** 490 * An object that converts a <code>java.sql.Date</code> to a 491 * <code>String</code>. 492 */ 493 public static class SqlDateToString extends AbstractLocalizedConverter<java.sql.Date, String> { 494 public SqlDateToString() { 495 super(java.sql.Date.class, String.class); 496 } 497 498 @Override 499 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 500 return java.sql.Date.class.equals(sourceClass) && String.class.equals(targetClass); 501 } 502 503 public String convert(java.sql.Date obj) throws ConversionException { 504 return obj.toString(); 505 } 506 507 /** 508 * Converts <code>obj</code> to a <code>String</code> using the supplied 509 * time zone. The <code>formatString</code> parameter is 510 * ignored. The returned string is formatted as 511 * {@link DateTimeConverters#JDBC_DATE_FORMAT}. 512 */ 513 public String convert(java.sql.Date obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 514 DateFormat df = toDateFormat(timeZone); 515 return df.format(obj); 516 } 517 } 518 519 /** 520 * An object that converts a <code>java.sql.Date</code> to a 521 * <code>java.sql.Timestamp</code>. 522 */ 523 public static class SqlDateToTimestamp extends AbstractConverter<java.sql.Date, java.sql.Timestamp> { 524 public SqlDateToTimestamp() { 525 super(java.sql.Date.class, java.sql.Timestamp.class); 526 } 527 528 @Override 529 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 530 return java.sql.Date.class.equals(sourceClass) && java.sql.Timestamp.class.equals(targetClass); 531 } 532 533 /** 534 * Returns <code>obj</code> converted to a <code>java.sql.Timestamp</code>. 535 */ 536 public java.sql.Timestamp convert(java.sql.Date obj) throws ConversionException { 537 return new java.sql.Timestamp(obj.getTime()); 538 } 539 } 540 541 /** 542 * An object that converts a <code>java.sql.Time</code> to a 543 * <code>String</code>. 544 */ 545 public static class SqlTimeToString extends AbstractLocalizedConverter<java.sql.Time, String> { 546 public SqlTimeToString() { 547 super(java.sql.Time.class, String.class); 548 } 549 550 @Override 551 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 552 return java.sql.Time.class.equals(sourceClass) && String.class.equals(targetClass); 553 } 554 555 public String convert(java.sql.Time obj) throws ConversionException { 556 return obj.toString(); 557 } 558 559 /** 560 * Converts <code>obj</code> to a <code>String</code> using the supplied 561 * time zone. The <code>formatString</code> parameter is 562 * ignored. The returned string is formatted as 563 * {@link DateTimeConverters#JDBC_TIME_FORMAT}. 564 */ 565 public String convert(java.sql.Time obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 566 DateFormat df = toTimeFormat(timeZone); 567 return df.format(obj); 568 } 569 } 570 571 /** 572 * An object that converts a <code>String</code> to a 573 * <code>java.util.Calendar</code>. 574 */ 575 public static class StringToCalendar extends AbstractLocalizedConverter<String, Calendar> { 576 public StringToCalendar() { 577 super(String.class, Calendar.class); 578 } 579 580 /** 581 * Converts <code>obj</code> to a <code>java.util.Calendar</code> initialized to 582 * the default locale and time zone. The string must be formatted as 583 * {@link DateTimeConverters#CALENDAR_FORMAT}. 584 */ 585 public Calendar convert(String obj) throws ConversionException { 586 try { 587 DateFormat df = new SimpleDateFormat(CALENDAR_FORMAT); 588 Calendar cal = Calendar.getInstance(); 589 cal.setTime(df.parse(obj)); 590 return cal; 591 } catch (ParseException e) { 592 throw new ConversionException(e); 593 } 594 } 595 596 /** 597 * Converts <code>obj</code> to a <code>java.util.Calendar</code> initialized to 598 * the supplied locale and time zone. If <code>formatString</code> is 599 * <code>null</code>, the string is formatted as 600 * {@link DateTimeConverters#CALENDAR_FORMAT}. 601 */ 602 public Calendar convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 603 DateFormat df = toDateTimeFormat(formatString == null ? CALENDAR_FORMAT : formatString, timeZone, locale); 604 try { 605 Date date = df.parse(obj); 606 Calendar cal = Calendar.getInstance(timeZone, locale); 607 cal.setTimeInMillis(date.getTime()); 608 return cal; 609 } catch (ParseException e) { 610 throw new ConversionException(e); 611 } 612 } 613 } 614 615 /** 616 * An object that converts a <code>String</code> to a 617 * <code>java.util.Date</code>. 618 */ 619 public static class StringToDate extends AbstractLocalizedConverter<String, Date> { 620 public StringToDate() { 621 super(String.class, Date.class); 622 } 623 624 @Override 625 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 626 return String.class.equals(sourceClass) && Date.class.equals(targetClass); 627 } 628 629 /** 630 * Converts <code>obj</code> to a <code>java.util.Date</code>. 631 * The string must be formatted as 632 * {@link DateTimeConverters#CALENDAR_FORMAT}. 633 */ 634 public Date convert(String obj) throws ConversionException { 635 try { 636 DateFormat df = new SimpleDateFormat(CALENDAR_FORMAT); 637 return df.parse(obj); 638 } catch (ParseException e) { 639 throw new ConversionException(e); 640 } 641 } 642 643 /** 644 * Converts <code>obj</code> to a <code>java.util.Date</code>. If 645 * <code>formatString</code> is <code>null</code>, the string is formatted as 646 * {@link DateTimeConverters#CALENDAR_FORMAT}. 647 */ 648 public Date convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 649 DateFormat df = toDateTimeFormat(formatString == null ? CALENDAR_FORMAT : formatString, timeZone, locale); 650 try { 651 return df.parse(obj); 652 } catch (ParseException e) { 653 throw new ConversionException(e); 654 } 655 } 656 } 657 658 /** 659 * An object that converts a <code>String</code> to a 660 * <code>java.sql.Date</code>. 661 */ 662 public static class StringToSqlDate extends AbstractLocalizedConverter<String, java.sql.Date> { 663 public StringToSqlDate() { 664 super(String.class, java.sql.Date.class); 665 } 666 667 @Override 668 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 669 return String.class.equals(sourceClass) && java.sql.Date.class.equals(targetClass); 670 } 671 672 public java.sql.Date convert(String obj) throws ConversionException { 673 return java.sql.Date.valueOf(obj); 674 } 675 676 /** 677 * Converts <code>obj</code> to a <code>java.sql.Date</code> using the supplied 678 * time zone. The <code>locale</code> and <code>formatString</code> parameters are 679 * ignored. The string must be formatted as 680 * {@link DateTimeConverters#JDBC_DATE_FORMAT}. 681 */ 682 public java.sql.Date convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 683 DateFormat df = toDateFormat(timeZone); 684 try { 685 return new java.sql.Date(df.parse(obj).getTime()); 686 } catch (ParseException e) { 687 throw new ConversionException(e); 688 } 689 } 690 } 691 692 /** 693 * An object that converts a <code>String</code> to a 694 * <code>java.sql.Time</code>. 695 */ 696 public static class StringToSqlTime extends AbstractLocalizedConverter<String, java.sql.Time> { 697 public StringToSqlTime() { 698 super(String.class, java.sql.Time.class); 699 } 700 701 @Override 702 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 703 return String.class.equals(sourceClass) && java.sql.Time.class.equals(targetClass); 704 } 705 706 public java.sql.Time convert(String obj) throws ConversionException { 707 return java.sql.Time.valueOf(obj); 708 } 709 710 /** 711 * Converts <code>obj</code> to a <code>java.sql.Time</code> using the supplied 712 * time zone. The <code>locale</code> and <code>formatString</code> parameters are 713 * ignored. The string must be formatted as 714 * {@link DateTimeConverters#JDBC_TIME_FORMAT}. 715 */ 716 public Time convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 717 DateFormat df = toTimeFormat(timeZone); 718 try { 719 return new java.sql.Time(df.parse(obj).getTime()); 720 } catch (ParseException e) { 721 throw new ConversionException(e); 722 } 723 } 724 } 725 726 /** 727 * An object that converts a <code>String</code> to a 728 * <code>java.sql.Timestamp</code>. 729 */ 730 public static class StringToTimestamp extends AbstractLocalizedConverter<String, java.sql.Timestamp> { 731 public StringToTimestamp() { 732 super(String.class, java.sql.Timestamp.class); 733 } 734 735 @Override 736 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 737 return String.class.equals(sourceClass) && java.sql.Timestamp.class.equals(targetClass); 738 } 739 740 public Timestamp convert(String obj) throws ConversionException { 741 return java.sql.Timestamp.valueOf(obj); 742 } 743 744 /** 745 * Converts <code>obj</code> to a <code>java.sql.Timestamp</code>. 746 * <p>Note that the string representation is referenced to the <code>timeZone</code> 747 * argument, not UTC. The <code>Timestamp</code> that is returned is adjusted to UTC. 748 * This behavior is intended to accommodate user-entered timestamps, where users are 749 * accustomed to using their own time zone.</p> 750 * </p> 751 */ 752 public java.sql.Timestamp convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 753 try { 754 // The String is referenced to the time zone represented by the timeZone 755 // argument, but the parsing code assumes a reference to UTC. So, we need 756 // to "adjust" the parsed Timestamp's value. 757 Timestamp parsedStamp = Timestamp.valueOf(obj); 758 Calendar cal = Calendar.getInstance(timeZone, locale); 759 cal.setTime(parsedStamp); 760 cal.add(Calendar.MILLISECOND, 0 - timeZone.getOffset(parsedStamp.getTime())); 761 Timestamp result = new Timestamp(cal.getTimeInMillis()); 762 result.setNanos(parsedStamp.getNanos()); 763 return result; 764 } catch (Exception e) { 765 throw new ConversionException(e); 766 } 767 } 768 } 769 770 /** 771 * An object that converts a <code>String</code> ID to a 772 * <code>java.util.TimeZone</code>. 773 */ 774 public static class StringToTimeZone extends AbstractConverter<String, TimeZone> { 775 public StringToTimeZone() { 776 super(String.class, TimeZone.class); 777 } 778 779 public TimeZone convert(String obj) throws ConversionException { 780 return TimeZone.getTimeZone(obj); 781 } 782 } 783 784 /** 785 * An object that converts a <code>java.sql.Timestamp</code> to a 786 * <code>java.util.Date</code>. 787 */ 788 public static class TimestampToDate extends AbstractConverter<java.sql.Timestamp, Date> { 789 public TimestampToDate() { 790 super(java.sql.Timestamp.class, Date.class); 791 } 792 793 @Override 794 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 795 return java.sql.Timestamp.class.equals(sourceClass) && java.util.Date.class.equals(targetClass); 796 } 797 798 public Date convert(java.sql.Timestamp obj) throws ConversionException { 799 return new Timestamp(obj.getTime()); 800 } 801 } 802 803 /** 804 * An object that converts a <code>java.sql.Timestamp</code> to a 805 * <code>java.sql.Date</code>. 806 */ 807 public static class TimestampToSqlDate extends AbstractConverter<java.sql.Timestamp, java.sql.Date> { 808 public TimestampToSqlDate() { 809 super(java.sql.Timestamp.class, java.sql.Date.class); 810 } 811 812 @Override 813 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 814 return java.sql.Timestamp.class.equals(sourceClass) && java.sql.Date.class.equals(targetClass); 815 } 816 817 public java.sql.Date convert(java.sql.Timestamp obj) throws ConversionException { 818 return new java.sql.Date(obj.getTime()); 819 } 820 } 821 822 /** 823 * An object that converts a <code>java.sql.Timestamp</code> to a 824 * <code>java.sql.Time</code>. 825 */ 826 public static class TimestampToSqlTime extends AbstractConverter<java.sql.Timestamp, java.sql.Time> { 827 public TimestampToSqlTime() { 828 super(java.sql.Timestamp.class, java.sql.Time.class); 829 } 830 831 @Override 832 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 833 return java.sql.Timestamp.class.equals(sourceClass) && java.sql.Time.class.equals(targetClass); 834 } 835 836 public java.sql.Time convert(java.sql.Timestamp obj) throws ConversionException { 837 return new java.sql.Time(obj.getTime()); 838 } 839 } 840 841 /** 842 * An object that converts a <code>java.sql.Timestamp</code> to a 843 * <code>String</code>. 844 */ 845 public static class TimestampToString extends AbstractLocalizedConverter<java.sql.Timestamp, String> { 846 public TimestampToString() { 847 super(java.sql.Timestamp.class, String.class); 848 } 849 850 @Override 851 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 852 return java.sql.Timestamp.class.equals(sourceClass) && String.class.equals(targetClass); 853 } 854 855 public String convert(java.sql.Timestamp obj) throws ConversionException { 856 return obj.toString(); 857 } 858 859 /** 860 * Converts <code>obj</code> to a <code>String</code> using the supplied 861 * time zone. 862 * <p>Note that the string representation is referenced to the <code>timeZone</code> 863 * argument, not UTC. The <code>Timestamp</code> is adjusted to the specified 864 * time zone before conversion. This behavior is intended to accommodate user interfaces, 865 * where users are accustomed to viewing timestamps in their own time zone.</p> 866 * </p> 867 */ 868 public String convert(Timestamp obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { 869 try { 870 // The Timestamp is referenced to UTC, but the String result needs to be 871 // referenced to the time zone represented by the timeZone argument. 872 // So, we need to "adjust" the Timestamp's value before conversion. 873 Calendar cal = Calendar.getInstance(timeZone, locale); 874 cal.setTime(obj); 875 cal.add(Calendar.MILLISECOND, timeZone.getOffset(obj.getTime())); 876 Timestamp result = new Timestamp(cal.getTimeInMillis()); 877 result.setNanos(obj.getNanos()); 878 return result.toString(); 879 } catch (Exception e) { 880 throw new ConversionException(e); 881 } 882 } 883 } 884 885 /** 886 * An object that converts a <code>java.util.TimeZone</code> to a 887 * <code>String</code> ID. 888 */ 889 public static class TimeZoneToString extends AbstractConverter<TimeZone, String> { 890 public TimeZoneToString() { 891 super(TimeZone.class, String.class); 892 } 893 894 public String convert(TimeZone obj) throws ConversionException { 895 return obj.getID(); 896 } 897 } 898 }