The above wasn't quite right. You don't need to go through the roundTime method, as you know you're only dealing with MILLISECONDS here. So like this:

    int nanos = PDataType.INTEGER.getCodec().decodeInt(ptr.getBuffer(),ptr.getOffset()+PDataType.LONG.getMaxLength()); // Skip ms part
    if (nanos > 0) {
        // Get millisecond timestamp value using codec to prevent object allocation
        long ts = (getDataType() == PDataType.TIMESTAMP ? PDataType.LONG : PDataType.UNSIGNED_LONG).getCodec().decodeLong(ptr.getBuffer(),ptr.getOffset());
        Timestamp roundedTs = new Timestamp(ts.getTime() + 1);
        byte[] byteValue = getDataType().toBytes(roundedTs);
        ptr.set(byteValue);
    }
    return true; // Otherwise, just return with the eval of the first child, as this is the correct value