Skip to content

Commit 88df176

Browse files
author
Davies Liu
committed
fallback to java.util.Date
1 parent 9df8c84 commit 88df176

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/DateTimeUtils.scala

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -856,18 +856,30 @@ object DateTimeUtils {
856856
private def getOffsetFromLocalMillis(millisLocal: Long, tz: TimeZone): Long = {
857857
var guess = tz.getRawOffset
858858
// the actual offset should be calculated based on milliseconds in UTC
859-
var actual = tz.getOffset(millisLocal - guess)
860-
if (actual != guess) {
861-
// try with the result as guess
862-
guess = actual
863-
actual = tz.getOffset(millisLocal - guess)
864-
// At the start of DST, the local time is forwarded by an hour, so it's OK to get the
865-
// local time bigger than current one after an round trip (local -> UTC -> local).
866-
// At the end of DST, the local time is backwarded by an hour, actual offset will be
867-
// less than guess, we should decrease the guess and try again.
868-
while (actual < guess) {
869-
guess = actual
870-
actual = tz.getOffset(millisLocal - guess)
859+
val offset = tz.getOffset(millisLocal - guess)
860+
if (offset != guess) {
861+
guess = tz.getOffset(millisLocal - offset)
862+
if (guess != offset) {
863+
// fallback to do the reverse lookup using java.sql.Timestamp
864+
// this should only happen near the start or end of DST
865+
val days = Math.floor(millisLocal.toDouble / MILLIS_PER_DAY).toInt
866+
val year = getYear(days)
867+
val month = getMonth(days)
868+
val day = getDayOfMonth(days)
869+
870+
var millisOfDay = (millisLocal % MILLIS_PER_DAY).toInt
871+
if (millisOfDay < 0) {
872+
millisOfDay += MILLIS_PER_DAY.toInt
873+
}
874+
val seconds = (millisOfDay / 1000L).toInt
875+
val hh = seconds / 3600
876+
val mm = seconds / 60 % 60
877+
val ss = seconds % 60
878+
val nano = millisOfDay % 1000 * 1000000
879+
880+
// create a Timestamp to get the unix timestamp (in UTC)
881+
val timestamp = new Timestamp(year - 1900, month - 1, day, hh, mm, ss, nano)
882+
guess = (millisLocal - timestamp.getTime).toInt
871883
}
872884
}
873885
guess

0 commit comments

Comments
 (0)