Date Format Cache. : Calendar Date « Development Class « Java






Date Format Cache.

     
// 
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.
// 

import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/* ------------------------------------------------------------ */
/**
 * Date Format Cache. Computes String representations of Dates and caches the
 * results so that subsequent requests within the same minute will be fast.
 * 
 * Only format strings that contain either "ss" or "ss.SSS" are handled.
 * 
 * The timezone of the date may be included as an ID with the "zzz" format
 * string or as an offset with the "ZZZ" format string.
 * 
 * If consecutive calls are frequently very different, then this may be a little
 * slower than a normal DateFormat.
 * 
 * @author Kent Johnson <KJohnson@transparent.com>
 * @author Greg Wilkins (gregw)
 */

public class DateCache {
  private static long __hitWindow = 60 * 60;

  private static long __MaxMisses = 10;

  private String _formatString;

  private String _tzFormatString;

  private SimpleDateFormat _tzFormat;

  private String _minFormatString;

  private SimpleDateFormat _minFormat;

  private String _secFormatString;

  private String _secFormatString0;

  private String _secFormatString1;

  private boolean _millis = false;

  private long _misses = 0;

  private long _lastMinutes = -1;

  private long _lastSeconds = -1;

  private String _lastResult = null;

  private Locale _locale = null;

  private DateFormatSymbols _dfs = null;

  /* ------------------------------------------------------------ */
  /**
   * Constructor. Make a DateCache that will use a default format. The default
   * format generates the same results as Date.toString().
   */
  public DateCache() {
    this("EEE MMM dd HH:mm:ss zzz yyyy");
    getFormat().setTimeZone(TimeZone.getDefault());
  }

  /* ------------------------------------------------------------ */
  /**
   * Constructor. Make a DateCache that will use the given format
   */
  public DateCache(String format) {
    _formatString = format;
    setTimeZone(TimeZone.getDefault());

  }

  /* ------------------------------------------------------------ */
  public DateCache(String format, Locale l) {
    _formatString = format;
    _locale = l;
    setTimeZone(TimeZone.getDefault());
  }

  /* ------------------------------------------------------------ */
  public DateCache(String format, DateFormatSymbols s) {
    _formatString = format;
    _dfs = s;
    setTimeZone(TimeZone.getDefault());
  }

  /* ------------------------------------------------------------ */
  /**
   * Set the timezone.
   * 
   * @param tz
   *          TimeZone
   */
  public void setTimeZone(TimeZone tz) {
    setTzFormatString(tz);
    if (_locale != null) {
      _tzFormat = new SimpleDateFormat(_tzFormatString, _locale);
      _minFormat = new SimpleDateFormat(_minFormatString, _locale);
    } else if (_dfs != null) {
      _tzFormat = new SimpleDateFormat(_tzFormatString, _dfs);
      _minFormat = new SimpleDateFormat(_minFormatString, _dfs);
    } else {
      _tzFormat = new SimpleDateFormat(_tzFormatString);
      _minFormat = new SimpleDateFormat(_minFormatString);
    }
    _tzFormat.setTimeZone(tz);
    _minFormat.setTimeZone(tz);
    _lastSeconds = -1;
    _lastMinutes = -1;
  }

  /* ------------------------------------------------------------ */
  public TimeZone getTimeZone() {
    return _tzFormat.getTimeZone();
  }

  /* ------------------------------------------------------------ */
  /**
   * Set the timezone.
   * 
   * @param timeZoneId
   *          TimeZoneId the ID of the zone as used by TimeZone.getTimeZone(id)
   */
  public void setTimeZoneID(String timeZoneId) {
    setTimeZone(TimeZone.getTimeZone(timeZoneId));
  }

  /* ------------------------------------------------------------ */
  private void setTzFormatString(final TimeZone tz) {
    int zIndex = _formatString.indexOf("ZZZ");
    if (zIndex >= 0) {
      String ss1 = _formatString.substring(0, zIndex);
      String ss2 = _formatString.substring(zIndex + 3);
      int tzOffset = tz.getRawOffset();

      StringBuffer sb = new StringBuffer(_formatString.length() + 10);
      sb.append(ss1);
      sb.append("'");
      if (tzOffset >= 0)
        sb.append('+');
      else {
        tzOffset = -tzOffset;
        sb.append('-');
      }

      int raw = tzOffset / (1000 * 60); // Convert to seconds
      int hr = raw / 60;
      int min = raw % 60;

      if (hr < 10)
        sb.append('0');
      sb.append(hr);
      if (min < 10)
        sb.append('0');
      sb.append(min);
      sb.append('\'');

      sb.append(ss2);
      _tzFormatString = sb.toString();
    } else
      _tzFormatString = _formatString;
    setMinFormatString();
  }

  /* ------------------------------------------------------------ */
  private void setMinFormatString() {
    int i = _tzFormatString.indexOf("ss.SSS");
    int l = 6;
    if (i >= 0)
      _millis = true;
    else {
      i = _tzFormatString.indexOf("ss");
      l = 2;
    }

    // Build a formatter that formats a second format string
    // Have to replace @ with ' later due to bug in SimpleDateFormat
    String ss1 = _tzFormatString.substring(0, i);
    String ss2 = _tzFormatString.substring(i + l);
    _minFormatString = ss1 + (_millis ? "'ss.SSS'" : "'ss'") + ss2;
  }

  /* ------------------------------------------------------------ */
  /**
   * Format a date according to our stored formatter.
   * 
   * @param inDate
   * @return Formatted date
   */
  public synchronized String format(Date inDate) {
    return format(inDate.getTime());
  }

  /* ------------------------------------------------------------ */
  /**
   * Format a date according to our stored formatter.
   * 
   * @param inDate
   * @return Formatted date
   */
  public synchronized String format(long inDate) {
    long seconds = inDate / 1000;

    // Is it not suitable to cache?
    if (seconds < _lastSeconds || _lastSeconds > 0 && seconds > _lastSeconds + __hitWindow) {
      // It's a cache miss
      _misses++;
      if (_misses < __MaxMisses) {
        Date d = new Date(inDate);
        return _tzFormat.format(d);
      }
    } else if (_misses > 0)
      _misses--;

    // Check if we are in the same second
    // and don't care about millis
    if (_lastSeconds == seconds && !_millis)
      return _lastResult;

    Date d = new Date(inDate);

    // Check if we need a new format string
    long minutes = seconds / 60;
    if (_lastMinutes != minutes) {
      _lastMinutes = minutes;
      _secFormatString = _minFormat.format(d);

      int i;
      int l;
      if (_millis) {
        i = _secFormatString.indexOf("ss.SSS");
        l = 6;
      } else {
        i = _secFormatString.indexOf("ss");
        l = 2;
      }
      _secFormatString0 = _secFormatString.substring(0, i);
      _secFormatString1 = _secFormatString.substring(i + l);
    }

    // Always format if we get here
    _lastSeconds = seconds;
    StringBuffer sb = new StringBuffer(_secFormatString.length());
    synchronized (sb) {
      sb.append(_secFormatString0);
      int s = (int) (seconds % 60);
      if (s < 10)
        sb.append('0');
      sb.append(s);
      if (_millis) {
        long millis = inDate % 1000;
        if (millis < 10)
          sb.append(".00");
        else if (millis < 100)
          sb.append(".0");
        else
          sb.append('.');
        sb.append(millis);
      }
      sb.append(_secFormatString1);
      _lastResult = sb.toString();
    }

    return _lastResult;
  }

  /* ------------------------------------------------------------ */
  /**
   * Format to string buffer.
   * 
   * @param inDate
   *          Date the format
   * @param buffer
   *          StringBuffer
   */
  public void format(long inDate, StringBuffer buffer) {
    buffer.append(format(inDate));
  }

  /* ------------------------------------------------------------ */
  /**
   * Get the format.
   */
  public SimpleDateFormat getFormat() {
    return _minFormat;
  }

  /* ------------------------------------------------------------ */
  public String getFormatString() {
    return _formatString;
  }

  /* ------------------------------------------------------------ */
  public String now() {
    return format(System.currentTimeMillis());
  }
}

   
    
    
    
    
  








Related examples in the same category

1.Create a Date object using the Calendar class
2.When does the UNIX date get into troubleWhen does the UNIX date get into trouble
3.Trivial class to show use of Date and Calendar objectsTrivial class to show use of Date and Calendar objects
4.Convert longs (time_t in UNIX terminology) to seconds
5.Show use of Calendar objectsShow use of Calendar objects
6.How quickly can you press return
7.Easter - compute the day on which Easter fallsEaster - compute the day on which Easter falls
8.Show use of Calendar get() method with various parameters
9.TimeComputation for processing sqrt and Input and Output operations.
10.Bean to display a month calendar in a JPanelBean to display a month calendar in a JPanel
11.Show some date uses 1
12.Show dates before 1970
13.Compare Dates
14.Compare File Dates
15.If a date is after another date
16.If a date is before another date
17.Compute days between 2 dates
18.Show some calendar calculations
19.The best way to format a date/time is to use
20.Create SimpleDateFormats from a string read from a file
21.DateCalAdd -- compute the difference between two dates
22.Show some date uses
23.Calendar DemoCalendar Demo
24.DateDiff -- compute the difference between two dates
25.DateAdd -- compute the difference between two dates
26.Increment and Decrement a Date Using the Calendar Class
27.Increment and Decrement Months Using the Calendar Class
28.Add or subtract days to current date using Java Calendar
29.Subtract days from current date using Calendar.add method
30.Add hours to current date using Calendar.add method
31.Subtract hours from current date using Calendar.add method
32.Add minutes to current date using Calendar.add method
33.Subtract minutes from current date using Calendar.add method
34.Add months to current date using Calendar.add method
35.Subtract months from current date using Calendar.add method
36.Add seconds to current date using Calendar.add method
37.Subtract seconds from current time using Calendar.add method
38.Add week to current date using Calendar.add method
39.Add hours, minutes or seconds to a date
40.Subtract week from current date
41.Add year to current date using Calendar.add method
42.Add 10 months to the calendar
43.Subtract 1 year from the calendar
44.Subtract year from current date
45.Calendar adjust date automatically
46.Display Day of Week using Java Calendar
47.Display Month of year using Java Calendar
48.Display full date time
49.Get a List of Month Names
50.Get current date, year and month
51.Get Week of month and year using Java Calendar
52.Get the number of days in that month
53.Get the current month name
54.Get day, month, year value from the current date
55.Convert day of the year to date
56.Pass the year information to the calendar object
57.Get the last date of a month
58.Convert day of year to day of month
59.Determine the day of the week
60.Set with GregorianCalendar.YEAR, MONTH and DATE
61.Determine if an hour is between an interval
62.Parse a String to obtain a Date/GregorianCalendar object
63.Try month in a leap year
64.Determining If a Year Is a Leap Year
65.Determining the Day-of-Week for a Particular Date
66.Subtract 30 days from the calendar
67.Date and time with month
68.Date and time with day and month fully spelled-out
69.Formatting the Time Using a Custom Format
70.Convert string date to long value
71.Display date with a short day and month name
72.Convert Date to String
73.Validate a date Using DateFormat
74.Get the day name
75.Use the SimpleDateFormat from the java.text package
76.Formatting date with full day and month name and show time up to milliseconds with AM/PM
77.Getting the Current Time
78.Output current time: %tc
79.Swing: Date Time EditorSwing: Date Time Editor
80.Get day of week
81.Convert milliseconds value to date
82.Calculate the age
83.Format a duration in ms into a string as "Days,Hours,minutes and seconds"
84.Formatting Symbols for SimpleDateFormat
85.Express a duration in term of HH:MM:SS
86.Match DateMatch Date
87.Checks if two calendar objects represent the same local time.
88.Checks if two date objects are on the same day ignoring time
89.Checks if two date objects represent the same instant in time
90.Calendar Comparator
91.Calendar To String
92.Formatter that caches formatted date information
93.Date and time formatting utilities and constants.
94.Formatting dates into Strings.
95.Monitored GregorianCalendar
96.RFC date format
97.Utilities for java.util.Date
98.Calendar operations
99.Calendar Util