java.lang.Object
org.rrd4j.core.timespec.TimeParser

public class TimeParserextends Object
Parser for at-style time specifications used in RRDTool commands.

This class parses human-readable time specifications in the format described in detail on the rrdfetch man page. It is primarily a Java port of Tobi Oetiker's parsetime.c code, adapted for Java conventions.

Supported time specification formats include:
- Absolute times: "Jan 1 2023", "12:30", "2023/01/01 12:30:45"
- Relative times: "now-2hours", "tomorrow", "noon yesterday"
- Natural language: "midnight", "teatime", "start of week"
- Time ranges: "start+1week", "end-2days"

Special parsing rules:
- Two-digit years before 38 are interpreted as post-2000
- Ambiguous "m" token resolved based on context (months vs minutes)
- Supports both 12-hour (AM/PM) and 24-hour time formats
- Multiple date separators accepted: "/", ".", "-"

The parser uses a two-phase approach:
1. Lexical scanning (TimeScanner) breaks input into tokens
2. Grammar parsing interprets tokens according to at-style syntax rules

Example usage:

TimeParser parser = new TimeParser("now-1day+2hours");
TimeSpec spec = parser.parse();
long timestamp = spec.getTimestamp();
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) int
    Current operation (PLUS/MINUS)
    (package private) int
    Previous multiplier for months-minutes disambiguation
    private static final int
    Operator for "previous", used in place of + or -.
    (package private) final TimeScanner
    Input scanner
    (package private) final TimeSpec
    Parsed time spec
    (package private) TimeToken
    Current token
  • Constructor Summary

    Constructors
    Constructor
    Description
    TimeParser(String dateString)
    Constructs TimeParser instance from the given input string.
  • Method Summary

    Modifier and Type
    Method
    Description
    private void
    assignDate(long mday, long mon, long year)
    Sets the day, month and year of the result.
    private void
    day()
    Parses a day: a name, a month-day, or a full date.
    private void
    expectToken(int desired, String errorMessage)
    Expects a specific token type and throws exception if not found.
    Parses the input string specified in the constructor.
    private void
    plusMinus(int doop)
    Handles plus/minus operations for relative time adjustments.
    private void
    Attempts to parse time-of-day specification from current token.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • PREVIOUS_OP

      private static final int PREVIOUS_OP
      Operator for "previous", used in place of + or -.
      See Also:
    • token

      TimeToken token
      Current token
    • scanner

      final TimeScanner scanner
      Input scanner
    • spec

      final TimeSpec spec
      Parsed time spec
    • op

      int op
      Current operation (PLUS/MINUS)
    • prev_multiplier

      int prev_multiplier
      Previous multiplier for months-minutes disambiguation
  • Constructor Details

    • TimeParser

      public TimeParser(String dateString)
      Constructs TimeParser instance from the given input string.
      Parameters:
      dateString - at-style time specification (read rrdfetch man page for the complete explanation)
  • Method Details

    • expectToken

      private void expectToken(int desired, String errorMessage)
      Expects a specific token type and throws exception if not found.

      This helper method advances the scanner and validates that the next token matches the expected type. If the token type doesn't match, it throws an IllegalArgumentException with the provided error message.

      Parameters:
      desired - the expected token type identifier
      errorMessage - error message to throw if token doesn't match
      Throws:
      IllegalArgumentException - if the next token is not of the desired type
    • plusMinus

      private void plusMinus(int doop)
      Handles plus/minus operations for relative time adjustments.

      This method processes time adjustments like "+2 hours" or "-5 days". It handles the ambiguous "m" token (months vs minutes) by using context from the previous multiplier to make an educated guess.

      Ambiguity resolution logic:
      - After days/weeks/months/years: "m" means months
      - After seconds/minutes/hours: "m" means minutes
      - Otherwise: numbers < 6 mean months, >= 6 mean minutes

      Parameters:
      doop - the operation type (PLUS or MINUS), or -1 to skip processing
    • timeOfDay

      private void timeOfDay()
      Attempts to parse time-of-day specification from current token.

      This method is called when a plain number is encountered at the start of a time specification, which could represent either a time (HH:MM) or a date. The method tries to parse it as a time first, and if that fails, it restores scanner state and returns without modifying the time spec.

      Supported time formats:
      - HH (hour only)
      - HH:MM or HH.MM (hour and minute)
      - Optional AM/PM suffix for 12-hour format

      The method uses backtracking to restore scanner state if parsing fails, allowing the parser to try alternative interpretations (like treating the number as a date instead).

    • assignDate

      private void assignDate(long mday, long mon, long year)
      Sets the day, month and year of the result.
      Parameters:
      mday - day of the month
      mon - the month number, 1 to 12
      year - the year, with the century
    • day

      private void day()
      Parses a day: a name, a month-day, or a full date.
    • parse

      public TimeSpec parse()
      Parses the input string specified in the constructor.
      Returns:
      Object representing parsed date/time.