@@ -21,17 +21,24 @@ import org.apache.spark.sql.types.Decimal
2121import org .apache .spark .unsafe .types .CalendarInterval
2222
2323object IntervalUtils {
24- val MONTHS_PER_YEAR : Int = 12
25- val MONTHS_PER_QUARTER : Byte = 3
26- val YEARS_PER_MILLENNIUM : Int = 1000
27- val YEARS_PER_CENTURY : Int = 100
28- val YEARS_PER_DECADE : Int = 10
29- val MICROS_PER_HOUR : Long = DateTimeUtils .MILLIS_PER_HOUR * DateTimeUtils .MICROS_PER_MILLIS
30- val MICROS_PER_MINUTE : Long = DateTimeUtils .MILLIS_PER_MINUTE * DateTimeUtils .MICROS_PER_MILLIS
31- val DAYS_PER_MONTH : Byte = 30
32- val MICROS_PER_MONTH : Long = DAYS_PER_MONTH * DateTimeUtils .SECONDS_PER_DAY
33- /* 365.25 days per year assumes leap year every four years */
34- val MICROS_PER_YEAR : Long = (36525L * DateTimeUtils .MICROS_PER_DAY ) / 100
24+ final val MONTHS_PER_YEAR : Int = 12
25+ final val MONTHS_PER_QUARTER : Byte = 3
26+ final val YEARS_PER_MILLENNIUM : Int = 1000
27+ final val YEARS_PER_CENTURY : Int = 100
28+ final val YEARS_PER_DECADE : Int = 10
29+ final val MICROS_PER_HOUR : Long = DateTimeUtils .MILLIS_PER_HOUR * DateTimeUtils .MICROS_PER_MILLIS
30+ final val MICROS_PER_MINUTE : Long = {
31+ DateTimeUtils .MILLIS_PER_MINUTE * DateTimeUtils .MICROS_PER_MILLIS
32+ }
33+ // The average year of the Gregorian calendar 365.2425 days long, see
34+ // https://en.wikipedia.org/wiki/Gregorian_calendar
35+ // Leap year occurs every 4 years, except for years that are divisible by 100
36+ // and not divisible by 400. So, the mean length of of the Gregorian calendar year is:
37+ // 1 mean year = (365 + 1/4 - 1/100 + 1/400) days = 365.2425 days
38+ // The mean year length in seconds is:
39+ // 60 * 60 * 24 * 365.2425 = 31556952.0 = 12 * 2629746
40+ final val SECONDS_PER_MONTH : Int = 2629746
41+ final val MICROS_PER_MONTH : Long = SECONDS_PER_MONTH * DateTimeUtils .MICROS_PER_SECOND
3542
3643 def getYears (interval : CalendarInterval ): Int = {
3744 interval.months / MONTHS_PER_YEAR
@@ -83,9 +90,8 @@ object IntervalUtils {
8390
8491 // Returns total number of seconds with microseconds fractional part in the given interval.
8592 def getEpoch (interval : CalendarInterval ): Decimal = {
86- var result = interval.microseconds
87- result += MICROS_PER_YEAR * (interval.months / MONTHS_PER_YEAR )
88- result += MICROS_PER_MONTH * (interval.months % MONTHS_PER_YEAR )
93+ val monthsDurationUs = Math .multiplyExact(interval.months, MICROS_PER_MONTH )
94+ val result = Math .addExact(interval.microseconds, monthsDurationUs)
8995 Decimal (result, 18 , 6 )
9096 }
9197}
0 commit comments