--- old/src/java.base/share/classes/java/text/SimpleDateFormat.java 2016-05-31 10:35:53.458673999 +0530 +++ new/src/java.base/share/classes/java/text/SimpleDateFormat.java 2016-05-31 10:35:53.142515999 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1491,22 +1491,18 @@ if (i < compiledPattern.length) { int nextTag = compiledPattern[i] >>> 8; - if (!(nextTag == TAG_QUOTE_ASCII_CHAR || - nextTag == TAG_QUOTE_CHARS)) { - obeyCount = true; - } - + int nextCount = compiledPattern[i] & 0xff; + obeyCount = shouldObeyCount(nextTag, nextCount); + if (hasFollowingMinusSign && (nextTag == TAG_QUOTE_ASCII_CHAR || nextTag == TAG_QUOTE_CHARS)) { - int c; - if (nextTag == TAG_QUOTE_ASCII_CHAR) { - c = compiledPattern[i] & 0xff; - } else { - c = compiledPattern[i+1]; + + if (nextTag != TAG_QUOTE_ASCII_CHAR) { + nextCount = compiledPattern[i+1]; } - if (c == minusSign) { + if (nextCount == minusSign) { useFollowingMinusSignAsDelimiter = true; } } @@ -1549,6 +1545,36 @@ return parsedDate; } + /* If the next tag/pattern is a then the parser + * should consider the count of digits while parsing the contigous digits + * for the current tag/pattern + */ + private boolean shouldObeyCount(int tag, int count) { + switch (tag) { + case PATTERN_MONTH: + case PATTERN_MONTH_STANDALONE: + return count <= 2; + case PATTERN_YEAR: + case PATTERN_DAY_OF_MONTH: + case PATTERN_HOUR_OF_DAY1: + case PATTERN_HOUR_OF_DAY0: + case PATTERN_MINUTE: + case PATTERN_SECOND: + case PATTERN_MILLISECOND: + case PATTERN_DAY_OF_YEAR: + case PATTERN_DAY_OF_WEEK_IN_MONTH: + case PATTERN_WEEK_OF_YEAR: + case PATTERN_WEEK_OF_MONTH: + case PATTERN_HOUR1: + case PATTERN_HOUR0: + case PATTERN_WEEK_YEAR: + case PATTERN_ISO_DAY_OF_WEEK: + return true; + default: + return false; + } + } + /** * Private code-size reduction function used by subParse. * @param text the time text being parsed. --- /dev/null 2016-05-31 10:21:41.154160000 +0530 +++ new/test/java/text/Format/DateFormat/Bug8072099.java 2016-05-31 10:35:53.978934000 +0530 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8072099 + * @summary check the date time pattern for which should + * not throw ParseException + */ + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Locale; + +public class Bug8072099 { + + private static String[][] shouldPass = { + {"ha", "11AM"}, + {"hma", "33AM"}, + {"ka", "24AM"}, + {"yyyMMM", "2016May"}, + {"yyyyDDEEE", "2016366Sat"}, + {"ddmyyyyz", "22111980GMT+5:30"} + }; + + public static void main(String[] args) { + + Locale defaultLocale = Locale.getDefault(); + try { + Locale.setDefault(Locale.US); + // check the date time pattern which should pass + for (String[] pattern : shouldPass) { + SimpleDateFormat dateTimeFormat = new SimpleDateFormat(pattern[0]); + parseDateTimeInput(dateTimeFormat, pattern[1]); + } + } finally { + Locale.setDefault(defaultLocale); + } + } + + private static void parseDateTimeInput(SimpleDateFormat format, + String inputString) { + try { + format.parse(inputString); + } catch (ParseException ex) { + throw new RuntimeException("[FAILED: Unable to parse date time" + + " string " + inputString + "]"); + } + } + +}