Optional parts in SimpleDateFormat

后端 未结 7 1646
挽巷
挽巷 2020-12-09 01:09

I\'m reading in date strings that could be with or without a time zone adjustment: yyyyMMddHHmmssz or yyyyMMddHHmmss. When a string is missing a z

7条回答
  •  被撕碎了的回忆
    2020-12-09 01:31

    I have solved a similar problem some time ago by extending SimpleDateFormat. Below an crude implementation to show the idea of my solution. It may not be fully complete/optimised.

    public class MySimpleDateFormat extends SimpleDateFormat {
        private static final long serialVersionUID = 1L;
        private static String FORMAT = "        
        private static int FORMAT_LEN = "yyyyMMddHHmmss".length();
        private static String TZ_ID = "GMT";
    
        public MySimpleDateFormat() {
                this(TimeZone.getTimeZone(TZ_ID));
        }
    
        public MySimpleDateFormat(TimeZone tz) {
                super(FORMAT);
                setTimeZone(tz);
        }
    
        @Override
        public Date parse(String source, ParsePosition pos) {
                // TODO: args validation
                int offset = pos.getIndex() + FORMAT_LEN;
                Date result;
                if (offset < source.length()) {
                        // there maybe is a timezone
                        result = super.parse(source, pos);
                        if (result != null) {
                                return result;
                        }
                        if (pos.getErrorIndex() >= offset) {
                                // there isn't a TZ after all
                                String part0 = source.substring(0, offset);
                                String part1 = source.substring(offset);
                                ParsePosition anotherPos = new ParsePosition(pos.getIndex());
                                result = super.parse(part0 + TZ_ID + part1, anotherPos);
                                if(result == null) {
                                        pos.setErrorIndex(anotherPos.getErrorIndex());
                                } else {
                                        // check SimpleDateFormat#parse javadoc to implement correctly the pos updates
                                        pos.setErrorIndex(-1);
                                        pos.setIndex(offset);
                                }
                                return result;
                        }
                        // there's something wrong with the first FORMAT_LEN chars
                        return null;
                }
                result = super.parse(source + TZ_ID, pos);
                if(result != null) {
                        pos.setIndex(pos.getIndex() - TZ_ID.length());
                }
                return result;
        }
    
        public static void main(String [] args) {
                ParsePosition pos = new ParsePosition(0);
                MySimpleDateFormat mySdf = new MySimpleDateFormat();
                System.out.println(mySdf.parse("20120622131415", pos) + " -- " + pos);
                pos = new ParsePosition(0);
                System.out.println(mySdf.parse("20120622131415GMT", pos) + " -- " + pos);
                pos = new ParsePosition(0);
                System.out.println(mySdf.parse("20120622131415xxx", pos) + " -- " + pos);
                pos = new ParsePosition(0);
                System.out.println(mySdf.parse("20120x22131415xxx", pos) + " -- " + pos);
        }
    }
    

    The gist is that you need to check the input string and "guess" somehow that the TZ field is missing, add it if so and then let the SimpleDateFormat#parse(String, ParsePosition) do the rest. The implementation above isn't updating ParsePosition according to the contract in javadoc in SimpleDateFormat#parse(String, ParsePosition)

    The class has a single default ctor as there's only one format allowed.

    The method MySimpleDateFormat#parse(String, ParsePosition) is invoked by SimpleDateFormat#parse(String) so it's sufficient to cover both cases.

    Running the main() this is the output (as expected)

    Fri Jun 22 14:14:15 BST 2012 -- java.text.ParsePosition[index=14,errorIndex=-1]
    Fri Jun 22 14:14:15 BST 2012 -- java.text.ParsePosition[index=17,errorIndex=-1]
    Fri Jun 22 14:14:15 BST 2012 -- java.text.ParsePosition[index=14,errorIndex=-1]
    null -- java.text.ParsePosition[index=0,errorIndex=5]
    

提交回复
热议问题