net-commonlib/src/main/java/com/streamsets/pipeline/lib/parser/net/syslog/SyslogDecoder.java
public static long parseRfc3164Time(String ts) throws OnRecordErrorException {
    LocalDateTime now = LocalDateTime.now();
    int year = now.getYear();
    ts = TWO_SPACES.matcher(ts).replaceFirst(" ");
    LocalDateTime date;
    try {
      MonthDay monthDay = MonthDay.parse(ts, rfc3164Format);
      LocalTime time = LocalTime.parse(ts, rfc3164Format);
      // this is overly complicated because of the way Java 8 Time API works, as compared to Joda
      // essentially, we just want to pull year out of "now" and set all other fields based on
      // what was parsed
      date = now;
      // zero out millis since we aren't actually parsing those
      date = date.with(ChronoField.MILLI_OF_SECOND, 0);
      // set month and day of month from parsed
      date = date.withMonth(monthDay.getMonthValue()).withDayOfMonth(monthDay.getDayOfMonth());
      // set time fields from parsed
      date = date.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(time.getSecond());
    } catch (DateTimeParseException e) {
      throw new OnRecordErrorException(Errors.SYSLOG_10, ts, e);
    }
    // The RFC3164 is a bit weird date format - it contains day and month, but no year. So we have to somehow guess
    // the year. The current logic is to provide a sliding window - going 11 months to the past and 1 month to the
    // future. If the message is outside of this window, it will have incorrectly guessed year. We go 11 months to the
    // past as we're expecting that more messages will be from the past (syslog usually contains historical data).
    LocalDateTime fixed = date;
    if (fixed.isAfter(now) && fixed.minusMonths(1).isAfter(now)) {
      fixed = date.withYear(year - 1);
    } else if (fixed.isBefore(now) && fixed.plusMonths(11).isBefore(now)) {
      fixed = date.withYear(year + 1);
    }
    date = fixed;
    return date.toInstant(ZoneOffset.UTC).toEpochMilli();
  }
public static long parseRfc3164Time(String ts) throws OnRecordErrorException {
    LocalDateTime now = LocalDateTime.now();
    int year = now.getYear();
    ts = TWO_SPACES.matcher(ts).replaceFirst(" ");
    LocalDateTime date;
    try {
      MonthDay monthDay = MonthDay.parse(ts, rfc3164Format);
      LocalTime time = LocalTime.parse(ts, rfc3164Format);
      // this is overly complicated because of the way Java 8 Time API works, as compared to Joda
      // essentially, we just want to pull year out of "now" and set all other fields based on
      // what was parsed
      date = now;
      // zero out millis since we aren't actually parsing those
      date = date.with(ChronoField.MILLI_OF_SECOND, 0);
      // set month and day of month from parsed
      date = date.withMonth(monthDay.getMonthValue()).withDayOfMonth(monthDay.getDayOfMonth());
      // set time fields from parsed
      date = date.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(time.getSecond());
    } catch (DateTimeParseException e) {
      throw new OnRecordErrorException(Errors.SYSLOG_10, ts, e);
    }
    // The RFC3164 is a bit weird date format - it contains day and month, but no year. So we have to somehow guess
    // the year. The current logic is to provide a sliding window - going 11 months to the past and 1 month to the
    // future. If the message is outside of this window, it will have incorrectly guessed year. We go 11 months to the
    // past as we're expecting that more messages will be from the past (syslog usually contains historical data).
    LocalDateTime fixed = date;
    if (fixed.isAfter(now) && fixed.minusMonths(1).isAfter(now)) {
      fixed = date.withYear(year - 1);
    } else if (fixed.isBefore(now) && fixed.plusMonths(11).isBefore(now)) {
      fixed = date.withYear(year + 1);
    }
    date = fixed;
    return date.toInstant(ZoneOffset.UTC).toEpochMilli();
  }
Parse the RFC3164 date format. This is trickier than it sounds because this
format does not specify a year so we get weird edge cases at year
boundaries. This implementation tries to "do what I mean".
@param ts RFC3164-compatible timestamp to be parsed
@return Typical (for Java) milliseconds since the UNIX epoch