diff --git common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java index 1a0d7e6a27..031a0d1081 100644 --- common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java +++ common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java @@ -1186,7 +1186,13 @@ private String getNextNumericSubstring(String s, int begin, int end, Token token } /** - * Get the integer value of a temporal substring. + * Get the integer value of a numeric temporal substring. + * + * @param substring the next parseable substring of the input string + * @param token Token representing the next element of the pattern + * @return int value of temporal + * @throws IllegalArgumentException if substring is not parseable or if its value is outside of + * token's allowed range (e.g. token is hh/hh12 (range: 1-12) and substring is "0") */ private int parseNumericTemporal(String substring, Token token) { checkFormatExact(substring, token); @@ -1194,11 +1200,17 @@ private int parseNumericTemporal(String substring, Token token) { // exceptions to the rule if (token.temporalField == ChronoField.AMPM_OF_DAY) { return substring.toLowerCase().startsWith("a") ? AM : PM; - - } else if (token.temporalField == ChronoField.HOUR_OF_AMPM && "12".equals(substring)) { - substring = "0"; - - } else if (token.temporalField == ChronoField.YEAR + } + if (token.temporalField == ChronoField.HOUR_OF_AMPM) { + if ("12".equals(substring)) { + return 0; + } + if ("0".equals(substring)) { + throw new IllegalArgumentException("Value of hour of day (hh/hh12) in input is 0. " + + "The value should be between 1 and 12."); + } + } + if (token.temporalField == ChronoField.YEAR || token.temporalField == IsoFields.WEEK_BASED_YEAR) { String currentYearString; diff --git common/src/test/org/apache/hadoop/hive/common/format/datetime/TestHiveSqlDateTimeFormatter.java common/src/test/org/apache/hadoop/hive/common/format/datetime/TestHiveSqlDateTimeFormatter.java index 9c9b0bedcf..ff47655a15 100644 --- common/src/test/org/apache/hadoop/hive/common/format/datetime/TestHiveSqlDateTimeFormatter.java +++ common/src/test/org/apache/hadoop/hive/common/format/datetime/TestHiveSqlDateTimeFormatter.java @@ -367,6 +367,7 @@ public void testParseTimestampError() { verifyBadParseString("yyyy-mm-dd tzh:tzm", "2019-01-01 +16:00"); //tzh out of range verifyBadParseString("yyyy-mm-dd tzh:tzm", "2019-01-01 +14:60"); //tzm out of range verifyBadParseString("YYYY DDD", "2000 367"); //ddd out of range + verifyBadParseString("yyyy-mm-dd hh12 p.m. ss", "2020-01-01 0 am 00"); //hh12 range is 1-12 verifyBadParseString("yyyy-month-dd", "2019-merch-23"); //invalid month of year verifyBadParseString("yyyy-mon-dd", "2019-mer-23"); //invalid month of year verifyBadParseString("yyyy-MON-dd", "2018-FEBRUARY-28"); // can't mix and match mon and month