Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.databind.util;
  
  import java.util.*;
  
Default java.text.DateFormat implementation used by standard Date serializers and deserializers. For serialization defaults to using an ISO-8601 compliant format (format String "yyyy-MM-dd'T'HH:mm:ss.SSSZ") and for deserialization, both ISO-8601 and RFC-1123.
 
 @SuppressWarnings("serial")
 public class StdDateFormat
     extends DateFormat
 {
     /* TODO !!! 24-Nov-2009, tatu: Need to rewrite this class:
      * JDK date parsing is awfully brittle, and ISO-8601 is quite
      * permissive. The two don't mix, need to write a better one.
      */
     // Note: [JACKSON-697] is the issue for rewrite
 
    
Defines a commonly used date format that conforms to ISO-8601 date formatting standard, when it includes basic undecorated timezone definition
 
     protected final static String DATE_FORMAT_STR_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

    
Same as 'regular' 8601, but handles 'Z' as an alias for "+0000" (or "GMT")
 
     protected final static String DATE_FORMAT_STR_ISO8601_Z = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    
ISO-8601 with just the Date part, no time
 
     protected final static String DATE_FORMAT_STR_PLAIN = "yyyy-MM-dd";

    
This constant defines the date format specified by RFC 1123 / RFC 822.
 
     protected final static String DATE_FORMAT_STR_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";

    
For error messages we'll also need a list of all formats.
 
     protected final static String[] ALL_FORMATS = new String[] {
         ,
         ,
         ,
         
     };

    
By default we use GMT for everything.
 
     private final static TimeZone DEFAULT_TIMEZONE;
     static {
          = TimeZone.getTimeZone("GMT");
     }
     
     protected final static DateFormat DATE_FORMAT_RFC1123;
 
     protected final static DateFormat DATE_FORMAT_ISO8601;
     protected final static DateFormat DATE_FORMAT_ISO8601_Z;
 
     protected final static DateFormat DATE_FORMAT_PLAIN;
 
     /* Let's construct "blueprint" date format instances: can not be used
      * as is, due to thread-safety issues, but can be used for constructing
      * actual instances more cheaply (avoids re-parsing).
      */
     static {
         /* Another important thing: let's force use of GMT for
          * baseline DataFormat objects
          */
     }
    
    
A singleton instance can be used for cloning purposes.
 
     public final static StdDateFormat instance = new StdDateFormat();
    
    
Caller may want to explicitly override timezone to use; if so, we will have non-null value here.
    protected transient TimeZone _timezone;
    
    protected transient DateFormat _formatRFC1123;
    protected transient DateFormat _formatISO8601;
    protected transient DateFormat _formatISO8601_z;
    protected transient DateFormat _formatPlain;
    /*
    /**********************************************************
    /* Life cycle, accessing singleton "standard" formats
    /**********************************************************
     */
    public StdDateFormat() { }
    public StdDateFormat(TimeZone tz) {
         = tz;
    }
    public static TimeZone getDefaultTimeZone() {
        return ;
    }
    
    
Method used for creating a new instance with specified timezone; if no timezone specified, defaults to the default timezone (UTC).
    public StdDateFormat withTimeZone(TimeZone tz) {
        if (tz == null) {
            tz = ;
        }
        return new StdDateFormat(tz);
    }
    
    @Override
    public StdDateFormat clone() {
        /* Although there is that much state to share, we do need to
         * orchestrate a bit, mostly since timezones may be changed
         */
        return new StdDateFormat();
    }

    
Method for getting the globally shared DateFormat instance that uses GMT timezone and can handle simple ISO-8601 compliant date format.
    public static DateFormat getBlueprintISO8601Format() {
        return ;
    }

    
Method for getting a non-shared DateFormat instance that uses specified timezone and can handle simple ISO-8601 compliant date format.
    public static DateFormat getISO8601Format(TimeZone tz) {
        return _cloneFormat(tz);
    }

    
Method for getting the globally shared DateFormat instance that uses GMT timezone and can handle RFC-1123 compliant date format.
    public static DateFormat getBlueprintRFC1123Format() {
        return ;
    }


    
Method for getting a non-shared DateFormat instance that uses specific timezone and can handle RFC-1123 compliant date format.
    public static DateFormat getRFC1123Format(TimeZone tz) {
        return _cloneFormat(tz);
    }
    /*
    /**********************************************************
    /* Public API
    /**********************************************************
     */
    @Override
    public void setTimeZone(TimeZone tz)
    {
        /* DateFormats are timezone-specific (via Calendar contained),
         * so need to reset instances if timezone changes:
         */
        if (tz != ) {
             = null;
             = null;
             = null;
             = null;
             = tz;
        }
    }
    
    @Override
    public Date parse(String dateStrthrows ParseException
    {
        dateStr = dateStr.trim();
        ParsePosition pos = new ParsePosition(0);
        Date result = parse(dateStrpos);
        if (result != null) {
            return result;
        }
        StringBuilder sb = new StringBuilder();
        for (String f : ) {
            if (sb.length() > 0) {
                sb.append("\", \"");
            } else {
                sb.append('"');
            }
            sb.append(f);
        }
        sb.append('"');
        throw new ParseException
            (String.format("Can not parse date \"%s\": not compatible with any of standard forms (%s)",
                           dateStrsb.toString()), pos.getErrorIndex());
    }
    @Override
    public Date parse(String dateStrParsePosition pos)
    {
        if (looksLikeISO8601(dateStr)) { // also includes "plain"
            return parseAsISO8601(dateStrpos);
        }
        /* 14-Feb-2010, tatu: As per [JACKSON-236], better also
         *   consider "stringified" simple time stamp
         */
        int i = dateStr.length();
        while (--i >= 0) {
            char ch = dateStr.charAt(i);
            if (ch < '0' || ch > '9'break;
        }
        if (i < 0) { // all digits
            if (NumberInput.inLongRange(dateStrfalse)) {
                return new Date(Long.parseLong(dateStr));
            }
        }
        // Otherwise, fall back to using RFC 1123
        return parseAsRFC1123(dateStrpos);
    }
    @Override
    public StringBuffer format(Date dateStringBuffer toAppendTo,
            FieldPosition fieldPosition)
    {
        if ( == null) {
             = _cloneFormat();
        }
        return .format(datetoAppendTofieldPosition);
    }
    /*
    /**********************************************************
    /* Helper methods
    /**********************************************************
     */

    
Overridable helper method used to figure out which of supported formats is the likeliest match.
    protected boolean looksLikeISO8601(String dateStr)
    {
        if (dateStr.length() >= 5
            && Character.isDigit(dateStr.charAt(0))
            && Character.isDigit(dateStr.charAt(3))
            && dateStr.charAt(4) == '-'
            ) {
            return true;
        }
        return false;
    }
    protected Date parseAsISO8601(String dateStrParsePosition pos)
    {
        /* 21-May-2009, tatu: DateFormat has very strict handling of
         * timezone  modifiers for ISO-8601. So we need to do some scrubbing.
         */
        /* First: do we have "zulu" format ('Z' == "GMT")? If yes, that's
         * quite simple because we already set date format timezone to be
         * GMT, and hence can just strip out 'Z' altogether
         */
        int len = dateStr.length();
        char c = dateStr.charAt(len-1);
        DateFormat df;
        // [JACKSON-200]: need to support "plain" date...
        if (len <= 10 && Character.isDigit(c)) {
           df = ;
            if (df == null) {
                df =  = _cloneFormat();
            }
        } else if (c == 'Z') {
            df = ;
            if (df == null) {
                df =  = _cloneFormat();
            }
            // [JACKSON-334]: may be missing milliseconds... if so, add
            if (dateStr.charAt(len-4) == ':') {
                StringBuilder sb = new StringBuilder(dateStr);
                sb.insert(len-1, ".000");
                dateStr = sb.toString();
            }
        } else {
            // Let's see if we have timezone indicator or not...
            if (hasTimeZone(dateStr)) {
                c = dateStr.charAt(len-3);
                if (c == ':') { // remove optional colon
                    // remove colon
                    StringBuilder sb = new StringBuilder(dateStr);
                    sb.delete(len-3, len-2);
                    dateStr = sb.toString();
                } else if (c == '+' || c == '-') { // missing minutes
                    // let's just append '00'
                    dateStr += "00";
                }
                // [JACKSON-334]: may be missing milliseconds... if so, add
                len = dateStr.length();
                // '+0000' (5 chars); should come after '.000' (4 chars) of milliseconds, so:
                c = dateStr.charAt(len-9);
                if (Character.isDigit(c)) {
                    StringBuilder sb = new StringBuilder(dateStr);
                    sb.insert(len-5, ".000");
                    dateStr = sb.toString();
                }
                
                df = ;
                if ( == null) {
                    df =  = _cloneFormat();
                }
            } else {
                /* 24-Nov-2009, tatu: Ugh. This is getting pretty
                 *   ugly. Need to rewrite soon!
                 */
                // If not, plain date. Easiest to just patch 'Z' in the end?
                StringBuilder sb = new StringBuilder(dateStr);
                // And possible also millisecond part if missing
                int timeLen = len - dateStr.lastIndexOf('T') - 1;
                if (timeLen <= 8) {
                    sb.append(".000");
                }
                sb.append('Z');
                dateStr = sb.toString();
                df = ;
                if (df == null) {
                    df =  = _cloneFormat();
                }
            }
        }
        return df.parse(dateStrpos);
    }
    protected Date parseAsRFC1123(String dateStrParsePosition pos)
    {
        if ( == null) {
             = _cloneFormat();
        }
        return .parse(dateStrpos);
    }
    private final static boolean hasTimeZone(String str)
    {
        // Only accept "+hh", "+hhmm" and "+hh:mm" (and with minus), so
        int len = str.length();
        if (len >= 6) {
            char c = str.charAt(len-6);
            if (c == '+' || c == '-'return true;
            c = str.charAt(len-5);
            if (c == '+' || c == '-'return true;
            c = str.charAt(len-3);
            if (c == '+' || c == '-'return true;
        }
        return false;
    }
    private final DateFormat _cloneFormat(DateFormat df) {
        return _cloneFormat(df);
    }
    private final static DateFormat _cloneFormat(DateFormat dfTimeZone tz)
    {
        df = (DateFormatdf.clone();
        if (tz != null) {
            df.setTimeZone(tz);
        }
        return df;
    }
New to GrepCode? Check out our FAQ X