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

  1. Verify the input unit is milliseconds since epoch; divide by 1000 if microseconds
  2. Clamp/validate millisUtc against MIN_MILLIS/MAX_MILLIS before packing
  3. Sanitize source data; treat absurd epochs as NULL or recompute
  4. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/5dad0edec79f93c0. Report an issue: GitHub.