prestodb/presto · error · ArithmeticException
TimestampWithTimeZone overflow: %s ms
Error message
TimestampWithTimeZone overflow: %s ms
What it means
DateTimeEncoding.pack encodes a timestamp as (millisUtc << shift) | timeZoneKey inside a single long, reserving only 51 bits for millis (MAX_MILLIS = 0x7FFFFFFFFFFFF ≈ ±1.4e16 ms ≈ ±450k years). If millisUtc is outside [MIN_MILLIS, MAX_MILLIS] an ArithmeticException is thrown because the value cannot be bit-packed without overflow corrupting the timezone bits.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/type/DateTimeEncoding.java:35
import static com.facebook.presto.common.type.TimeZoneKey.getTimeZoneKeyForOffset;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
public final class DateTimeEncoding
{
private DateTimeEncoding()
{
}
private static final int TIME_ZONE_MASK = 0xFFF;
private static final int MILLIS_SHIFT = 12;
private static final long MAX_MILLIS = 0x7FFFFFFFFFFFFL;
private static final long MIN_MILLIS = (MAX_MILLIS + 1) * -1;
private static long pack(long millisUtc, short timeZoneKey)
{
if (millisUtc > MAX_MILLIS || millisUtc < MIN_MILLIS) {
throw new ArithmeticException(format("TimestampWithTimeZone overflow: %s ms", millisUtc));
}
return (millisUtc << MILLIS_SHIFT) | (timeZoneKey & TIME_ZONE_MASK);
}
public static long packDateTimeWithZone(long millisUtc, String zoneId)
{
return packDateTimeWithZone(millisUtc, getTimeZoneKey(zoneId));
}
public static long packDateTimeWithZone(long millisUtc, int offsetMinutes)
{
return packDateTimeWithZone(millisUtc, getTimeZoneKeyForOffset(offsetMinutes));
}
public static long packDateTimeWithZone(long millisUtc, TimeZoneKey timeZoneKey)
{
requireNonNull(timeZoneKey, "timeZoneKey is null");
return pack(millisUtc, timeZoneKey.getKey());View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the input unit is milliseconds since epoch; divide by 1000 if microseconds
- Clamp/validate millisUtc against MIN_MILLIS/MAX_MILLIS before packing
- Sanitize source data; treat absurd epochs as NULL or recompute
- If legitimately needing a bigger range, use a different timestamp representation (e.g. long nanos type or BigDecimal)
Example fix
// before
long packed = DateTimeEncoding.packDateTimeWithZone(microsSinceEpoch, zoneId); // wrong unit
// after
long millisUtc = microsSinceEpoch / 1000;
if (millisUtc > DateTimeEncoding.MAX_MILLIS || millisUtc < -DateTimeEncoding.MAX_MILLIS - 1) {
throw new IllegalArgumentException("timestamp out of representable range");
}
long packed = DateTimeEncoding.packDateTimeWithZone(millisUtc, zoneId); Defensive patterns
Strategy: validation
Validate before calling
public static boolean isPackableMillis(long millisUtc) {
return millisUtc <= 0x7FFFFFFFFFFFFL && millisUtc >= -0x8000000000000L;
}
// also confirm the input unit is milliseconds, not micros/nanos Type guard
public static boolean isPlausibleEpochMillis(Long millis) {
return millis != null && millis > -62135596800000L && millis < 253402300799999L; // year 1..9999
} Try / catch
try {
long packed = DateTimeEncoding.packDateTimeWithZone(millisUtc, zoneId);
} catch (ArithmeticException e) {
// value out of packing range: sanitize source or use alternate representation
} Prevention
- Double-check time unit (ms vs µs vs ns) before packing
- Validate year is in a sane calendar range before encoding
- Treat absurd epochs from corrupted data as NULL
When it happens
Trigger: Calling packDateTimeWithZone(millisUtc, zoneId) or updateMillisUtc with a millisecond epoch beyond ±0x7FFFFFFFFFFFF; year values far beyond the representable range (astronomical dates), or a corrupted/erroneous epoch such as microseconds fed as millis multiplied further.
Common situations: Unit confusion: passing microseconds or nanoseconds where millis are expected, blowing past the range; corrupted data producing absurd epoch values; computations like epoch*1000*1000 by accident.
Related errors
- seconds field of timestamp exceeds maximum supported value,
- Timestamp exceeds maximum supported value, value: %s truncat
- Value %d exceeds MAX_INT
- toEpochMillis is not supported for TIMESTAMP(
- toEpochMicros is not supported for TIMESTAMP(
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5dad0edec79f93c0.
Report an issue: GitHub.