Date Format Cache : Date Format « Data Type « 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.Date Era changeDate Era change
2.Date Format
3.The Time and Date Format Suffixes
4.Display standard 12-hour time format
5.Display complete time and date information
6.Display just hour and minute
7.Display month by name and number
8.DateFormat.getDateInstance(DateFormat.SHORT)
9.Use relative indexes to simplify the creation of a custom time and date format.
10.Date Format with LocaleDate Format with Locale
11.Date Format SymbolsDate Format Symbols
12.Decimal Format with different SymbolsDecimal Format with different Symbols
13.Date format: "dd.MM.yy", "yyyy.MM.dd G 'at' hh:mm:ss z","EEE, MMM d, ''yy", "h:mm a", "H:mm", "H:mm:ss:SSS", "K:mm a,z","yyyy.MMMMM.dd GGG hh:mm aaa"Date format:
14.SimpleDateFormat.getAvailableLocalesSimpleDateFormat.getAvailableLocales
15.DateFormat.SHORT
16.This is same as MEDIUM: DateFormat.getDateInstance().format(new Date())
17.This is same as MEDIUM: DateFormat.getDateInstance(DateFormat.DEFAULT).format(new Date())
18.DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.CANADA).format(new Date())
19.DateFormat.getTimeInstance(DateFormat.LONG, Locale.CANADA).format(new Date())
20.DateFormat.getTimeInstance(DateFormat.FULL, Locale.CANADA).format(new Date())
21.DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.CANADA).format(new Date())
22.DateFormat.getDateInstance(DateFormat.LONG)
23.DateFormat.getTimeInstance(DateFormat.SHORT)
24.DateFormat.getTimeInstance(DateFormat.LONG)
25.Parse date string input with DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.CANADA)
26.Simple Date Format DemoSimple Date Format Demo
27.Format date in Medium format
28.Format date in Long format
29.Format date in Full format
30.Format date in Default format
31.Formatting day of week using SimpleDateFormat
32.Formatting day of week in EEEE format like Sunday, Monday etc.
33.Formatting day in d format like 1,2 etc
34.Formatting day in dd format like 01, 02 etc.
35.Format hour in h (1-12 in AM/PM) format like 1, 2..12.
36.Format hour in hh (01-12 in AM/PM) format like 01, 02..12.
37.Format hour in H (0-23) format like 0, 1...23.
38.Format hour in HH (00-23) format like 00, 01..23.
39.Format hour in k (1-24) format like 1, 2..24.
40.Format hour in kk (01-24) format like 01, 02..24.
41.Format hour in K (0-11 in AM/PM) format like 0, 1..11.
42.Format hour in KK (00-11) format like 00, 01,..11.
43.Formatting minute in m format like 1,2 etc.
44.Format minutes in mm format like 01, 02 etc.
45.Format month in M format like 1,2 etc
46.Format Month in MM format like 01, 02 etc.
47.Format Month in MMM format like Jan, Feb etc.
48.Format Month in MMMM format like January, February etc.
49.Format seconds in s format like 1,2 etc.
50.Format seconds in ss format like 01, 02 etc.
51.Format date in dd/mm/yyyy format
52.Format date in mm-dd-yyyy hh:mm:ss format
53.Format year in yy format like 07, 08 etc
54.Format year in yyyy format like 2007, 2008 etc.
55.new SimpleDateFormat("hh")
56.new SimpleDateFormat("H") // The hour (0-23)
57.new SimpleDateFormat("m"): The minutes
58.new SimpleDateFormat("mm")
59.SimpleDateFormat("MM"): number based month value
60.new SimpleDateFormat("s"): The seconds
61.new SimpleDateFormat("ss")
62.new SimpleDateFormat("a"): The am/pm marker
63.new SimpleDateFormat("z"): The time zone
64.new SimpleDateFormat("zzzz")
65.new SimpleDateFormat("Z")
66.new SimpleDateFormat("hh:mm:ss a")
67.new SimpleDateFormat("HH.mm.ss")
68.new SimpleDateFormat("HH:mm:ss Z")
69.SimpleDateFormat("MM/dd/yy")
70.SimpleDateFormat("dd-MMM-yy")
71.SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z")
72.SimpleDateFormat("yyyy")
73.The month: SimpleDateFormat("M")
74.Three letter-month value: SimpleDateFormat("MMM")
75.Full length of month name: SimpleDateFormat("MMMM")
76.The day number: SimpleDateFormat("d")
77.Two digits day number: SimpleDateFormat("dd")
78.The day in week: SimpleDateFormat("E")
79.Full day name: SimpleDateFormat("EEEE")
80.Add AM PM to time using SimpleDateFormat
81.Simply format a date as "YYYYMMDD"
82.Java SimpleDateFormat Class Example("MM/dd/yyyy")
83.The format used is EEE, dd MMM yyyy HH:mm:ss Z in US locale.
84.Date Formatting and Localization
85.Get a List of Short Month Names
86.Get a List of Weekday Names
87.Get a List of Short Weekday Names
88.Change date formatting symbols
89.An alternate way to get week days symbols
90.ISO8601 formatter for date-time without time zone.The format used is yyyy-MM-dd'T'HH:mm:ss.
91.ISO8601 formatter for date-time with time zone. The format used is yyyy-MM-dd'T'HH:mm:ssZZ.
92.Parsing custom formatted date string into Date object using SimpleDateFormat
93.Parse with a custom format
94.Parsing the Time Using a Custom Format
95.Parse with a default format
96.Parse a date and time
97.Parse string date value input with SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z")
98.Parse string date value input with SimpleDateFormat("dd-MMM-yy")
99.Parse string date value with default format: DateFormat.getDateInstance(DateFormat.DEFAULT)
100.Find the current date format
101.Time format viewer
102.Date format viewer
103.Returns a String in the format Xhrs, Ymins, Z sec, for the time difference between two times
104.format Duration
105.Get Date Suffix
106.ISO8601 Date Format
107.Explode a date in 8 digit format into the three components.
108.Date To Iso Date Time
109.Iso Date Time To Date
110.Gets formatted time
111.Format Time To 2 Digits
112.Time formatting utility.
113.ISO 8601 BASIC date format
114.Format As MySQL Datetime
115.new SimpleDateFormat( "EEE MMM d HH:mm:ss z yyyy", Locale.UK )
116.Date parser for the ISO 8601 format.
117.Parse W3C Date format
118.Pack/Unpacks date stored in kdb format
119.Provides preset formatting for Dates. All dates are returned as GMT
120.Parse RSS date format to Date object.
121.Date format for face book
122.FastDateFormat is a fast and thread-safe version of java.text.SimpleDateFormat.
123.Date format and parse Util
124.XSD Date Time
125.Return a String value of Now() in a specify format
126.Format data to string with specified style.
127.extends Formatter