class SyslogParser {

  protected long parseRfc5424Date(String msg) {

    Long ts = null;
    int curPos = 0;

    int msgLen = msg.length();
    Preconditions.checkArgument(msgLen > RFC5424_PREFIX_LEN,
        "Bad format: Not a valid RFC5424 timestamp: %s", msg);
    String timestampPrefix = msg.substring(curPos, RFC5424_PREFIX_LEN);

    try {
      ts = timestampCache.get(timestampPrefix);
    } catch (ExecutionException ex) {
      throw new IllegalArgumentException("bad timestamp format", ex);
    }

    curPos += RFC5424_PREFIX_LEN;

    Preconditions.checkArgument(ts != null, "Parsing error: timestamp is null");

    // look for the optional fractional seconds
    if (msg.charAt(curPos) == '.') {
      // figure out how many numeric digits
      boolean foundEnd = false;
      int endMillisPos = curPos + 1;

      if (msgLen <= endMillisPos) {
        throw new IllegalArgumentException("bad timestamp format (no TZ)");
      }

      // FIXME: TODO: ensure we handle all bad formatting cases
      while (!foundEnd) {
        char curDigit = msg.charAt(endMillisPos);
        if (curDigit >= '0' && curDigit <= '9') {
          endMillisPos++;
        } else {
          foundEnd = true;
        }
      }

      // if they had a valid fractional second, append it rounded to millis
      final int fractionalPositions = endMillisPos - (curPos + 1);
      if (fractionalPositions > 0) {
        long milliseconds = Long.parseLong(msg.substring(curPos + 1, endMillisPos));
        if (fractionalPositions > 3) {
          milliseconds /= Math.pow(10, (fractionalPositions - 3));
        } else if (fractionalPositions < 3) {
          milliseconds *= Math.pow(10, (3 - fractionalPositions));
        }
        ts += milliseconds;
      } else {
        throw new IllegalArgumentException(
            "Bad format: Invalid timestamp (fractional portion): " + msg);
      }

      curPos = endMillisPos;
    }

    // look for timezone
    char tzFirst = msg.charAt(curPos);

    // UTC
    if (tzFirst == 'Z') {
      // no-op
    } else if (tzFirst == '+' || tzFirst == '-') {

      Preconditions.checkArgument(msgLen > curPos + 5,
          "Bad format: Invalid timezone (%s)", msg);

      int polarity;
      if (tzFirst == '+') {
        polarity = +1;
      } else {
        polarity = -1;
      }

      char[] h = new char[5];
      for (int i = 0; i < 5; i++) {
        h[i] = msg.charAt(curPos + 1 + i);
      }

      if (h[0] >= '0' && h[0] <= '9'
          && h[1] >= '0' && h[1] <= '9'
          && h[2] == ':'
          && h[3] >= '0' && h[3] <= '9'
          && h[4] >= '0' && h[4] <= '9') {
        int hourOffset = Integer.parseInt(msg.substring(curPos + 1, curPos + 3));
        int minOffset = Integer.parseInt(msg.substring(curPos + 4, curPos + 6));
        ts -= polarity * ((hourOffset * 60) + minOffset) * 60000;
      } else {
        throw new IllegalArgumentException(
            "Bad format: Invalid timezone: " + msg);
      }

    }


    return ts;
  }

  public  SyslogParser();

}