View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.scaffold.text;
18  
19  import java.text.DateFormat;
20  import java.text.DecimalFormat;
21  import java.text.DecimalFormatSymbols;
22  import java.text.NumberFormat;
23  import java.text.ParseException;
24  import java.text.SimpleDateFormat;
25  
26  import java.util.Date;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Locale;
30  import java.util.Map;
31  import java.util.Map.Entry;
32  import java.util.Set;
33  import java.util.StringTokenizer;
34  
35  import java.sql.Timestamp;
36  
37  /**
38   * An <b>experimental</b> class with some standard conversion
39   * utilities. Needs more proof of concept and unit testing.
40   *
41   * @author Ted Husted
42   * @author OK State DEQ
43   * @author WXXI Public Broadcasting Council
44   * @version $Revision: 155464 $ $Date: 2005-02-26 13:26:54 +0000 (Sat, 26 Feb 2005) $
45   */
46  public class ConvertUtils {
47  
48  /*
49      protected Locale[] availableLocales = null;
50      public static Locale[] getAvailableLocales() {
51          return availableLocales;
52      }
53      public static void setAvailableLocales(Locale[] _availableLocales) {
54          availableLocales = _availableLocales;
55      }
56  
57  */
58  
59  
60      /**
61       * This is an all-static utility class.
62       * A private constructor prevents inadvertent instantiation.
63       */
64      private ConvertUtils() { 
65          ; // empty 
66      }
67  
68  
69  // ---------------------------------------------------- Text Separators
70  
71      /**
72       * An empty string.
73       */
74      public static String STRING_EMPTY = "";
75  
76  
77      /**
78       * An empty string.
79       * @deprecated Use STRING_EMPTY
80       */
81      public static String EMPTY_STRING = STRING_EMPTY;
82  
83  
84      /**
85       * An single-space string.
86       */
87      public static final String STRING_SPACE = " ";
88  
89  
90      /**
91       * Space character.
92       */
93      public static final char SPACE                 = ' ';
94  
95  
96      /**
97       * Horizontal tab character.
98       */
99      public static final char HORIZONTAL_TABULATION = '\t';     // (aka u0009)
100 
101 
102     /**
103      * Line feed character.
104      */
105     public static final char LINE_FEED             = '\r';     // (aka u000A);
106 
107 
108     /**
109      * Vertical tab character.
110      */
111     public static final char VERTICAL_TABULATION   = '\u000B';
112 
113 
114     /**
115      * Form feed character.
116      */
117     public static final char FORM_FEED             = '\u000C';
118 
119 
120     /**
121      * Carriage return character.
122      */
123     public static final char CARRIAGE_RETURN       = '\n';     // (aka u000D)
124 
125 
126     /**
127      * File separator character.
128      */
129     public static final char FILE_SEPARATOR        = '\u001C';
130 
131 
132     /**
133      * Group separator character.
134      */
135     public static final char GROUP_SEPARATOR       = '\u001D';
136 
137 
138     /**
139      * Record separator character.
140      */
141     public static final char RECORD_SEPARATOR      = '\u001E';
142 
143 
144     /**
145      * Unit separator character.
146      */
147     public static final char UNIT_SEPARATOR        = '\u001F';
148 
149 
150     /**
151      * Array of line separator characters.
152      * http://java.sun.com/j2se/1.3/docs/api/java/lang/Character.html#isWhitespace(char)
153      */
154     public static final char[] SEPARATORS = {
155             HORIZONTAL_TABULATION,
156             LINE_FEED,
157             VERTICAL_TABULATION,
158             FORM_FEED,
159             CARRIAGE_RETURN,
160             FILE_SEPARATOR,
161             GROUP_SEPARATOR,
162             RECORD_SEPARATOR,
163             UNIT_SEPARATOR
164         };
165 
166 // --------------------------------------------------------- Tokenizers
167 
168 
169     /**
170      * Return array of tokens,
171      * using the result of <code>getTokeSep()</code> as the
172      * separator.
173      * Blanks are trimmed from tokens.
174      *
175      * @param parameter The string to tokenize into an array
176      */
177     public static String[] tokensToArray(String tokens, String separator) {
178 
179         StringTokenizer tokenizer =
180             new StringTokenizer(tokens,separator);
181         int i = 0;
182         String[] array = new String[tokenizer.countTokens()];
183         while (tokenizer.hasMoreTokens()) {
184             String token = tokenizer.nextToken().trim();
185             if ((token==null) || (token.length()==0)) continue;
186             array[i++] = token;
187         }
188         return array;
189         
190     } // end tokensToArray
191     
192 
193     /**
194      * Return list of tokens,
195      * using the result of <code>getTokeSep()</code> as the
196      * separator.
197      * Blanks are trimmed from tokens.
198      *
199      * @param parameter The string to tokenize into an array
200      */
201     public static List tokensToList(String tokens, String separator) {
202 
203         StringTokenizer tokenizer =
204             new StringTokenizer(tokens,separator);
205         List list = new java.util.ArrayList(tokenizer.countTokens());
206         while (tokenizer.hasMoreTokens()) {
207             String token = tokenizer.nextToken().trim();
208             if ((token==null) || (token.length()==0)) continue;
209             list.add(token);
210         }
211         return list;
212         
213     } // end tokensToList
214     
215 
216 // ------------------------------------------------------- Text Methods
217 
218 
219     /**
220      * Returns true if null or trims to an empty string.
221      * @deprecated Use blank instead.
222      */
223     public static boolean isBlank(String s) {
224         return blank(s);
225     }
226 
227 
228     /**
229      * Returns true if null or zero.
230      * @deprecated Use blank instead.
231      */
232     public static boolean isBlank(Integer key) {
233       return blank(key);
234     }
235 
236 
237     /**
238      * Returns true if null or trims to an empty string.
239      * @deprecated Use blankValue instead.
240      */
241     public static boolean isBlankValue(String s) {
242         return blankValue(s);
243     }
244 
245 
246     /**
247      * Returns true if null or trims to an empty string.
248      * @deprecated Use blank instead.
249      */
250     public static boolean blank(String s) {
251         return ((null==s) || (STRING_EMPTY.equals(s.trim())));
252     }
253 
254 
255     /**
256      * Returns true if null or zero.
257      * @deprecated Use blank instead.
258      */
259     public static boolean blank(Number key) {
260       return ((null==key) || (0==key.byteValue()));
261     }
262 
263 
264     /**
265      * Returns true if null, trims to an empty string,
266      * or to "0".
267      */
268     public static boolean blankValue(String s) {
269         if (null==s) return true;
270         String _s = s.trim();
271         return ((STRING_EMPTY.equals(_s)) || (STRING_ZERO.equals(_s)));
272     }
273 
274 
275     /**
276      * Return a trimmed or empty string (but not null).
277      */
278     public static String toTrimOrEmpty(String string) {
279         if (null==string) return STRING_EMPTY; 
280         return string.trim();
281     }
282 
283 
284     /**
285      * Returns null or a trimmed uppercase string.
286      */
287     public static String toUpperOrNull(String string) {
288         if (null!=string)
289             return string.toUpperCase().trim();
290         return null;
291     }
292 
293 
294     /**
295      * The token that signifies the begnning of a query string ["?"].
296      */
297     public static String QS_START = "?";
298 
299 
300     /**
301      * The token that delimits two or more attributes of a query string ["&amp;"].
302      */
303     public static String QS_DELIM = "&amp;";
304 
305 
306     /**
307      * The token that seperates an attribute name and value.
308      */
309     public static String QS_SEP = "=";
310 
311 
312     /**
313      * Appends name=value parameter.
314      */
315     public static String addParam(String path, String name, String value) {
316         StringBuffer uri = new StringBuffer(path);
317         boolean isQuery = (path.indexOf(QS_START)>=0);
318         if (isQuery)
319             uri.append(QS_DELIM);
320         else
321             uri.append(QS_START);
322         uri.append(name);
323         uri.append(QS_SEP);
324         uri.append(value);
325         return uri.toString();
326 
327      }
328 
329 
330     /**
331      * Appends name=value parameters to path from Map.
332      */
333     public static String addParams(String path, Map parameters) {
334 
335         if (null==path) path = new String();
336 
337         if ((null==parameters) || (parameters.isEmpty())) return path;
338 
339         StringBuffer uri = new StringBuffer(path);
340         boolean isQuery = (path.indexOf(QS_START)>=0);
341         if (isQuery)
342             uri.append(QS_DELIM);
343         else
344             uri.append(QS_START);
345 
346         Set entries = parameters.entrySet();
347         for (Iterator i = entries.iterator(); i.hasNext(); ) {
348             Entry e = (Entry) i.next();
349             uri.append(e.getKey());
350             uri.append(QS_SEP);
351             uri.append(e.getValue());
352         }
353         return uri.toString();
354 
355      }
356 
357 
358     /**
359      * Returns parameters as a series of hidden HTML fields.
360      */
361     public static String renderHiddenFields(Map parameters) {
362 
363         if ((null==parameters) || (parameters.isEmpty())) return new String();
364 
365         StringBuffer html = new StringBuffer();
366         Set entries = parameters.entrySet();
367         for (Iterator i = entries.iterator(); i.hasNext(); ) {
368             html.append("<input type='hidden' name='");
369             Entry e = (Entry) i.next();
370             html.append(e.getKey());
371             html.append("' value='");
372             html.append(e.getValue());
373             html.append("' />");
374         }
375         return html.toString();
376 
377      }
378 
379 
380     /**
381      * Replace line returns with spaces.
382      */
383     private static String stripLn(String string) {
384 
385         // :FIXME: Better way to buffer the interim strings?
386         for (int i=0; i<SEPARATORS.length; i++) {
387            string = string.replace(
388                 SEPARATORS[i],
389                 SPACE
390             );
391         }
392         return string;
393     }
394 
395 
396 
397 // ----------------------------------------------------- Numeric Values
398 
399 
400     /**
401      * An Double 0.
402      */
403     public static Double DOUBLE_ZERO = new Double(0);
404 
405 
406     /**
407      * An Double 1.
408      */
409     public static Double DOUBLE_ONE = new Double((double) 1.0);
410 
411 
412     /**
413      * An Integer 0.
414      */
415     public static Integer INTEGER_ZERO = new Integer(0);
416 
417 
418     /**
419      * An Integer 1.
420      */
421     public static Integer INTEGER_ONE = new Integer(1);
422 
423 
424     /**
425      * A Short 0.
426      */
427     public static Short SHORT_ZERO = new Short((short) 0);
428 
429 
430     /**
431      * A Short 1.
432      */
433     public static Short SHORT_ONE = new Short((short) 1);
434 
435 
436     /**
437      * A String 0.
438      */
439     public static String STRING_ZERO = "0";
440 
441 
442     /**
443      * A String 1.
444      */
445     public static String STRING_ONE = "1";
446 
447 
448 
449 
450 // ---------------------------------------------------- Numeric Methods
451 
452 
453     /**
454      * Return String with of digits only (0..9).
455      * http://java.sun.com/j2se/1.4/docs/api/java/lang/Character.html
456      */
457     public static String getDigits(String s) {
458         if (s==null) return null;
459         int n = s.length();
460         StringBuffer sb = new StringBuffer(n);
461         for (int i = 0; i < n; i++) {
462             char c = s.charAt(i);
463             if (Character.isDigit(c)) sb.append(c);
464         }
465         return (sb.toString());
466     }
467 
468 
469     /**
470      * Returns number formatted for default or given locale.
471      */
472     public static String getNumber(Number value, Locale locale) {
473         if (locale==null)
474             return (NumberFormat.getInstance().format(value));
475        return (NumberFormat.getInstance(locale).format(value));
476     }
477 
478 
479     /**
480      * Returns percent formatted for default or given locale.
481      */
482     public static String getPercent(Number value, Locale locale) {
483         if (locale==null)
484             return (NumberFormat.getPercentInstance().format(value));
485         return (NumberFormat.getPercentInstance(locale).format(value));
486     }
487 
488 
489     /* -- Is there a use case for this?
490 
491     public static String getInteger(Number value, Locale locale) {
492         if (locale==null)
493             return (NumberFormat.getIntegerInstance().format(value));
494         return (NumberFormat.getIntegerInstance(locale).format(value));
495     }
496 
497     */
498 
499 
500     /*
501      * Returns whether the last digit of numeric string is a parity
502      * check on the others per the "primes of nines" method.
503      * Reference: http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
504      * @param Number - Number to check.
505      * Must be all digits and not null.
506      */
507     public static boolean luhnCheck(String number) {
508         int no_digit = number.length();
509         int oddoeven = no_digit & 1;
510         long sum = 0;
511         for (int count = 0; count < no_digit; count++) {
512             int digit = Integer.parseInt(
513                 String.valueOf(number.charAt(count)));
514             if ( ( (count & 1) ^ oddoeven) ==0 ) { // not
515                 digit *= 2;
516                 if (digit > 9) digit -= 9;
517             };
518             sum += digit;
519         };
520         if (sum == 0) return false;
521         if (sum % 10 == 0) return true;
522         return false;
523     }
524 
525 
526     /**
527      * Returns number with the appropriate digit appended
528      * so that is passes a "luhnCheck".
529      * @param Number - Number to process.
530      * Must be all digits and not null.
531      */
532     public static String addLuhnDigit(String number) {
533         // I don't actually understand the alogorithm
534         // so we just use brute force to find the digit.
535         char[] digits = {'1','2','3','4','5','6','7','8','9','0'};
536         int c = number.length();
537         StringBuffer tryNumber = new StringBuffer(number + digits[0]);
538         int i;
539         for (i=0; i<10; i++) {
540             tryNumber.setCharAt(c,digits[i]);
541             if (luhnCheck(tryNumber.toString()))
542                 break;
543         }
544         return tryNumber.toString();
545     }
546 
547 
548 // ------------------------------------------------------------ Decimal
549 
550 
551     /**
552      * Default decimal pattern.
553      * http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
554      */
555     public static String DECIMAL_PATTERN ="###,###.###";
556 
557 
558     /**
559      * Symbols that can be used in a decimal pattern.
560      */
561     public static DecimalFormatSymbols getGenericDecimal(Locale locale) {
562         DecimalFormatSymbols symbols =
563             new DecimalFormatSymbols(locale);
564         symbols.setGroupingSeparator('`'); // :FIXME: Want apostrophe here
565         return symbols;
566     }
567 
568 
569     /**
570      * Return decimal number formatted for default or given locale.
571      */
572     public static String getDecimal(Number value, Locale locale) {
573         if (locale==null)
574             return (DecimalFormat.getInstance().format(value));
575         return (DecimalFormat.getInstance().format(value));
576     }
577 
578 
579     /**
580      * Return decimal number formatted for default or given locale
581      * using given pattern.
582      */
583     public static String getDecimal(Number value, Locale locale, String pattern) {
584         NumberFormat formatter;
585         if (locale==null)
586             formatter = new java.text.DecimalFormat(pattern);
587         else {
588             formatter = NumberFormat.getNumberInstance(locale);
589             DecimalFormat df = (DecimalFormat) formatter;
590             df.applyPattern(pattern);
591             return df.format(value);
592         }
593         return (formatter.format(value));
594     }
595 
596 
597     /**
598      *  Return decimal for default locale using standard pattern.
599      */
600     public static String getDecimal(Number value) {
601         return getDecimal(value,(Locale) null,DECIMAL_PATTERN);
602     }
603 
604 
605 // ----------------------------------------------------------- Currency
606 
607 
608     /**
609      * Standard currency pattern.
610      * http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
611      */
612     public static String CURRENCY_PATTERN ="$" + DECIMAL_PATTERN;
613 
614 
615     /**
616      *  Return currency for default locale using standard pattern.
617      */
618     public static String getCurrency(Number value) {
619         return getDecimal(value,null,CURRENCY_PATTERN);
620     }
621 
622 
623 // --------------------------------------------------------------- Date
624 
625 
626     /**
627      * Default style for dates and times.
628      */
629     public static int DEFAULT = DateFormat.DEFAULT;
630 
631 
632     /**
633      * Short style for dates and times.
634      */
635     public static int SHORT = DateFormat.SHORT;
636 
637 
638     /**
639      * Medium style for dates and times.
640      */
641     public static int MEDIUM = DateFormat.MEDIUM;
642 
643 
644     /**
645      * Long style for dates and times.
646      */
647     public static int LONG = DateFormat.LONG;
648 
649 
650     /**
651      * Full style for dates and times.
652      */
653     public static int FULL = DateFormat.FULL;
654 
655 
656     /**
657      * Default lenient setting for getDate.
658      */
659     private static boolean LENIENT_DATE = false;
660 
661 
662     /**
663      * A "default" date format.
664      */
665     public static String ESCAPE_DATE_PATTERN = "yyyy-mm-dd";
666 
667 
668     /**
669      * Convert String to Date using given format.
670      * Returns null if conversion fails.
671      * Set lenient=false to disallow dates like 2001-9-32.
672      * http://java.sun.com/j2se/1.4/docs/api/java/text/SimpleDateFormat.html
673      * @author Hal Deadman
674      */
675     public static Date getDate(String dateDisplay,
676             String format, boolean lenient) {
677         if (dateDisplay == null) {
678             return null;
679         }
680         DateFormat df = null;
681         try {
682             if (format==null) {
683                 df = new SimpleDateFormat();
684             }
685             else {
686                 df = new SimpleDateFormat(format);
687             }
688                 // setLenient avoids allowing dates like 9/32/2001
689                 // which would otherwise parse to 10/2/2001
690             df.setLenient(false);
691             return df.parse(dateDisplay);
692         }
693         catch(ParseException e) {
694             return null;
695         }
696     }
697 
698 
699     /**
700      * Convert String to Date using given format.
701      * Returns null if conversion fails.
702      * Uses "strict" coNversion (lenient=false).
703      * @author Hal Deadman
704      */
705     public static Date getDate(String dateDisplay, String format) {
706         return getDate(dateDisplay,format,LENIENT_DATE);
707     }
708 
709 
710     /**
711      * Convert String to Date using a medium (weekday day month year) format.
712      * Returns null if conversion fails.
713      * Uses "strict" coNversion (lenient=false).
714      * @author Hal Deadman
715      */
716     public static Date getDate(String dateDisplay) {
717         return getDate(dateDisplay,null,LENIENT_DATE);
718     }
719 
720 
721     /**
722      * Return Date value using a String.
723      * Null or conversion error returns null.
724      * @param String representing Date
725      */
726     public static Date toDate(String string) {
727         if (string==null)
728             return null;
729         else try {
730             return getDate(string);
731         } catch (Throwable t) {
732             return null;
733         }
734     }
735 
736 
737     /**
738      * Convert date to String for given locale in given style.
739      * A null locale will return the default locale.
740      */
741     public static String getDate(Date date, Locale locale, int style) {
742         if (locale==null)
743             return (DateFormat.getDateInstance(style).format(date));
744         return (DateFormat.getDateInstance(style,locale).format(date));
745     }
746 
747 
748     /**
749      * Convert date to String for default locale in given style.
750      * A null locale will return the default locale.
751      */
752     public static String getDate(Date date, int style) {
753        return getDate(date,(Locale) null,style);
754     }
755 
756 
757     /**
758      * Convert date to String for default locale in DEFAULT style.
759      * A null locale will return the default locale.
760      */
761     public static String getDate(Date date) {
762        return getDate(date,(Locale) null,DEFAULT);
763     }
764 
765 
766     /**
767      * Return String value representing Date.
768      * Null returns null.
769      * @param Date
770      */
771     public static String toString(Date date) {
772         if (date==null)
773             return null;
774         else
775             return getDate(date);
776     }
777 
778 
779     /**
780      * Return String value representing Date.
781      * Null returns null.
782      * @param Date
783      */
784     public static String toEscape(Date date) {
785         if (date==null)
786             return null;
787         DateFormat df = null;
788         try {
789             df = new SimpleDateFormat(ESCAPE_DATE_PATTERN);
790         } catch (Throwable t) {
791             return null;
792         }
793         df.setLenient(false);
794         return df.format(date);
795     }
796 
797 
798 // ---------------------------------------------------------- Timestamp
799 
800     /**
801      * Date separator ["-"].
802      */
803     public static final String DATE_SEPARATOR = "-";
804 
805 
806     /**
807      * Time separator [":"].
808      */
809     public static final String TIME_SEPARATOR = ":";
810 
811 
812     /**
813      * Date Time separator [" "].
814      */
815     public static final String DATE_TIME_SEPARATOR = STRING_SPACE;
816 
817 
818     /**
819      * String to prepend to time [HH:MM:SS.d] 
820      * to create a Timestamp escape string ["0002-11-30"].
821      */
822     public static final String TIMESTAMP_DATE_ZERO = "0002-11-30";
823 
824 
825     /**
826      * String to append to date [YEAR-MM-DD] 
827      * to create a Timestamp escape string [" 00:00:00.0"].
828      * Note: includes leading space.
829      */
830     public static final String TIMESTAMP_TIME_ZERO = " 00:00:00.0";
831     
832 
833     /**
834      * Escape string representing
835      * "November 30, 0002 00:00:00".
836      */    
837      public static String ZERO_TIMESTAMP_DISPLAY = "2-11-30 00:00:00";
838 
839 
840     /**
841      * Timestamp representing ""November 30, 0002 00:00:00".
842      */
843     public static Timestamp ZERO_TIMESTAMP = new Timestamp((long) 00000000000000);
844 
845 
846 
847     /**
848      * Escape string to create Timestamp representing
849      * "January 1, 1970 00:00:00".
850      */
851     public static String NULL_TIMESTAMP_DISPLAY = "1970-01-01 00:00:00";
852 
853 
854     /**
855      * @deprecated Use NULL_TIMESTAMP_DISPLAY.
856      */
857     public static String NULL_TIMESTAMP_TEXT = "NULL_TIMESTAMP_DISPLAY";
858 
859 
860     /**
861      * Value needed to create Timestamp representing
862      * "January 1, 1970 00:00:00".
863      * From the documentation, you would think this would be
864      * Timestamp(0), but empirical tests show it to be
865      * Timestamp(18000000).
866      */
867     public static long NULL_TIME = (long) 18000000;
868 
869 
870     /**
871      * Timestamp representing "January 1, 1970 00:00:00".
872      */
873     public static Timestamp NULL_TIMESTAMP = new Timestamp(NULL_TIME);
874     
875     
876     
877     /**
878      * Timestamp representing "December 31, 2029, 23:59:59.9"
879      */
880     public static Timestamp MAX_TIMESTAMP = Timestamp.valueOf("2029-12-31 23:59:59.999");
881 
882 
883     /**
884      * Return the String representing "January 1, 1970 00:00:00".
885      */
886     public static String getTimestampDisplayNull() {
887         return NULL_TIMESTAMP_DISPLAY;
888     }
889 
890 
891     /**
892      * Return the String representing the current timestamp;
893      */
894     public static String getTimestampDisplay() {
895         return getTimestamp(new Timestamp(System.currentTimeMillis()));
896     }
897 
898 
899     /**
900      * @deprecated Use getTimestampDisplay.
901      */
902     public static String getTimestampText() {
903         return getTimestampDisplay();
904     }
905 
906 
907     /**
908      * Return null if timestamp is null or equals
909      * "January 1, 1970 00:00:00".
910      */
911     public static boolean isNull(Timestamp timestamp) {
912         return ((timestamp==null) || (timestamp.getTime()==NULL_TIME));
913     }
914 
915 
916     /**
917      * Factory method to return timestamp initialized to
918      * current system time.
919      * For timestamp as a String in the default format,
920      * use <code>getTimestamp().toString()</code>.
921      */
922     public static Timestamp getTimestamp() {
923         return new Timestamp(System.currentTimeMillis());
924     }
925 
926 
927     /**
928      * Convert timestamp to String for given locale in given style.
929      * A null locale will return the default locale.
930      */
931     public static String getTimestamp(Timestamp timestamp,
932             Locale locale, int style) {
933         Date date = (Date) timestamp;
934         if (locale==null)
935             return (DateFormat.getDateTimeInstance(style,style).
936                 format(date));
937         return (DateFormat.getDateTimeInstance(style,style,locale).
938             format(date));
939     }
940 
941 
942     /**
943      * Convert date to String for default locale in given style.
944      * A null locale will return the default locale.
945      */
946     public static String getTimestamp(Timestamp timestamp,
947             int style) {
948        return getTimestamp(timestamp,(Locale) null,style);
949     }
950 
951 
952     /**
953      * Convert date to String for default locale in DEFAULT style.
954      * A null locale will return the default locale.
955      */
956     public static String getTimestamp(Timestamp timestamp) {
957        return getTimestamp(timestamp,(Locale) null,DEFAULT);
958     }
959 
960 
961     /**
962      * Return Timestamp value using a String.
963      * Null or conversion error returns null.
964      * @param String representing Timestamp
965      */
966     public static Timestamp toTimestamp(String string) {
967         if (string==null)
968             return null;
969         else try {
970             return Timestamp.valueOf(string);
971         } catch (Throwable t) {
972             return null;
973         }
974     }
975 
976 
977     /**
978      * Return a Timestamp based on the parameters.
979      * Any nulls or conversion error returns null.
980      * @param year The year
981      * @param month The month
982      * @param day The day   
983      * @returns Timestamp for year-month-day
984      */    
985     public static Timestamp toTimestamp(String year, String month, String day) {
986         
987         if ((null==year) || (null==month) || (null==day)) return null;
988         
989         StringBuffer sb = new StringBuffer();
990         // YEAR-MM-DD 00:00:00.0
991         sb.append(year);   sb.append(DATE_SEPARATOR); 
992         sb.append(month);  sb.append(DATE_SEPARATOR); 
993         sb.append(day); 
994         
995         sb.append(TIMESTAMP_TIME_ZERO);
996         
997         return toTimestamp(sb.toString());        
998     }
999 
1000 
1001     /**
1002      * Return String value representing Timestamp.
1003      * Null returns null.
1004      * @param Timestamp
1005      */
1006     public static String toString(Timestamp timestamp) {
1007         if (timestamp==null)
1008             return null;
1009         else
1010             return timestamp.toString();
1011     }
1012 
1013 
1014 // ----------------------------------------------------------- Internet
1015 
1016 
1017     /**
1018      * Return the integer value of an IP address in dotted octet form, 
1019      * like that returned by request.getRemotehost).
1020      * :FIXME: Needs to be implemented; just returns zero.
1021      * @param Timestamp
1022      */
1023     public static Integer ipNode(String ipAddress) { 
1024         return INTEGER_ZERO;
1025     }
1026 
1027 
1028 }
1029