Repository: hive Updated Branches: refs/heads/master c9bb5d389 -> fb675ce74
HIVE-18925 : Hive doesn't work when JVM is America/Bahia_Banderas time zone (Piotr Findeisen via Rui Li) Signed-off-by: Ashutosh Chauhan <hashut...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/fb675ce7 Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/fb675ce7 Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/fb675ce7 Branch: refs/heads/master Commit: fb675ce743a8e3f5805f2c3bcb6e8206febcf7a2 Parents: c9bb5d3 Author: Piotr Findeisen <piotr.findei...@gmail.com> Authored: Wed Mar 14 01:10:00 2018 -0700 Committer: Ashutosh Chauhan <hashut...@apache.org> Committed: Mon Mar 26 22:37:48 2018 -0700 ---------------------------------------------------------------------- .../hive/common/util/TimestampParser.java | 50 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/fb675ce7/common/src/java/org/apache/hive/common/util/TimestampParser.java ---------------------------------------------------------------------- diff --git a/common/src/java/org/apache/hive/common/util/TimestampParser.java b/common/src/java/org/apache/hive/common/util/TimestampParser.java index 14b9ca0..f674b5d 100644 --- a/common/src/java/org/apache/hive/common/util/TimestampParser.java +++ b/common/src/java/org/apache/hive/common/util/TimestampParser.java @@ -23,10 +23,12 @@ import java.sql.Timestamp; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.joda.time.DateTime; +import org.joda.time.IllegalInstantException; import org.joda.time.MutableDateTime; import org.joda.time.DateTimeFieldType; import org.joda.time.format.DateTimeFormat; @@ -35,6 +37,10 @@ import org.joda.time.format.DateTimeFormatterBuilder; import org.joda.time.format.DateTimeParser; import org.joda.time.format.DateTimeParserBucket; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkState; + /** * Timestamp parser using Joda DateTimeFormatter. Parser accepts 0 or more date time format * patterns. If no format patterns are provided it will default to the normal Timestamp parsing. @@ -46,7 +52,19 @@ public class TimestampParser { protected final static String[] stringArray = new String[] {}; protected final static String millisFormatString = "millis"; - protected final static DateTime startingDateValue = new DateTime(1970, 1, 1, 0, 0, 0, 0); + @Nullable + private final static DateTime startingDateValue = makeStartingDateValue(); + + @Nullable + private static DateTime makeStartingDateValue() { + try { + return new DateTime(1970, 1, 1, 0, 0, 0, 0); + } catch (IllegalInstantException e) { + // 1970-01-01 00:00:00 did not exist in some zones. In these zones, we need to take different, + // less optimal parsing route. + return null; + } + } protected String[] formatStrings = null; protected DateTimeFormatter fmt = null; @@ -78,7 +96,10 @@ public class TimestampParser { parsers[idx] = DateTimeFormat.forPattern(formatString).getParser(); } } - fmt = new DateTimeFormatterBuilder().append(null, parsers).toFormatter(); + fmt = new DateTimeFormatterBuilder() + .append(null, parsers) + .toFormatter() + .withDefaultYear(1970); } } @@ -90,6 +111,20 @@ public class TimestampParser { */ public Timestamp parseTimestamp(String strValue) throws IllegalArgumentException { if (fmt != null) { + Optional<Timestamp> parsed = tryParseWithFormat(strValue); + if (parsed.isPresent()) { + return parsed.get(); + } + } + + // Otherwise try default timestamp parsing + return Timestamp.valueOf(strValue); + } + + private Optional<Timestamp> tryParseWithFormat(String strValue) { + checkState(fmt != null); + + if (startingDateValue != null) { // reset value in case any date fields are missing from the date pattern MutableDateTime mdt = new MutableDateTime(startingDateValue); @@ -98,12 +133,17 @@ public class TimestampParser { int ret = fmt.parseInto(mdt, strValue, 0); // Only accept parse results if we parsed the entire string if (ret == strValue.length()) { - return new Timestamp(mdt.getMillis()); + return Optional.of(new Timestamp(mdt.getMillis())); } + return Optional.empty(); } - // Otherwise try default timestamp parsing - return Timestamp.valueOf(strValue); + try { + DateTime dt = fmt.parseDateTime(strValue); + return Optional.of(new Timestamp(dt.getMillis())); + } catch (IllegalArgumentException e) { + return Optional.empty(); + } } /**