| /* |
| * Copyright 1999,2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.catalina.util; |
| |
| import java.util.Date; |
| |
| import java.text.DateFormat; |
| import java.text.FieldPosition; |
| import java.text.ParsePosition; |
| import java.text.SimpleDateFormat; |
| |
| /** |
| * Fast date formatter that caches recently formatted date information |
| * and uses it to avoid too-frequent calls to the underlying |
| * formatter. Note: breaks fieldPosition param of format(Date, |
| * StringBuffer, FieldPosition). If you care about the field |
| * position, call the underlying DateFormat directly. |
| * |
| * @author Stan Bailes |
| * @author Alex Chaffee |
| **/ |
| public class FastDateFormat extends DateFormat { |
| DateFormat df; |
| long lastSec = -1; |
| StringBuffer sb = new StringBuffer(); |
| FieldPosition fp = new FieldPosition(DateFormat.MILLISECOND_FIELD); |
| |
| public FastDateFormat(DateFormat df) { |
| this.df = df; |
| } |
| |
| public Date parse(String text, ParsePosition pos) { |
| return df.parse(text, pos); |
| } |
| |
| /** |
| * Note: breaks functionality of fieldPosition param. Also: |
| * there's a bug in SimpleDateFormat with "S" and "SS", use "SSS" |
| * instead if you want a msec field. |
| **/ |
| public StringBuffer format(Date date, StringBuffer toAppendTo, |
| FieldPosition fieldPosition) { |
| long dt = date.getTime(); |
| long ds = dt / 1000; |
| if (ds != lastSec) { |
| sb.setLength(0); |
| df.format(date, sb, fp); |
| lastSec = ds; |
| } else { |
| // munge current msec into existing string |
| int ms = (int)(dt % 1000); |
| int pos = fp.getEndIndex(); |
| int begin = fp.getBeginIndex(); |
| if (pos > 0) { |
| if (pos > begin) |
| sb.setCharAt(--pos, Character.forDigit(ms % 10, 10)); |
| ms /= 10; |
| if (pos > begin) |
| sb.setCharAt(--pos, Character.forDigit(ms % 10, 10)); |
| ms /= 10; |
| if (pos > begin) |
| sb.setCharAt(--pos, Character.forDigit(ms % 10, 10)); |
| } |
| } |
| toAppendTo.append(sb.toString()); |
| return toAppendTo; |
| } |
| |
| public static void main(String[] args) { |
| String format = "yyyy-MM-dd HH:mm:ss.SSS"; |
| if (args.length > 0) |
| format = args[0]; |
| SimpleDateFormat sdf = new SimpleDateFormat(format); |
| FastDateFormat fdf = new FastDateFormat(sdf); |
| Date d = new Date(); |
| |
| d.setTime(1); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(20); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(500); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(543); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(999); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(1050); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(2543); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(12345); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| d.setTime(12340); System.out.println(fdf.format(d) + "\t" + sdf.format(d)); |
| |
| final int reps = 100000; |
| { |
| long start = System.currentTimeMillis(); |
| for (int i = 0; i < reps; i++) { |
| d.setTime(System.currentTimeMillis()); |
| fdf.format(d); |
| } |
| long elap = System.currentTimeMillis() - start; |
| System.out.println("fast: " + elap + " elapsed"); |
| System.out.println(fdf.format(d)); |
| } |
| { |
| long start = System.currentTimeMillis(); |
| for (int i = 0; i < reps; i++) { |
| d.setTime(System.currentTimeMillis()); |
| sdf.format(d); |
| } |
| long elap = System.currentTimeMillis() - start; |
| System.out.println("slow: " + elap + " elapsed"); |
| System.out.println(sdf.format(d)); |
| } |
| } |
| } |