{"record":{"id":"28a7dfeea7848c98","repo":"apache/cassandra","slug":"timestamp-format-must-be-hh-mm-ss-fffffffff","errorCode":null,"errorMessage":"Timestamp format must be hh:mm:ss[.fffffffff]","messagePattern":"Timestamp format must be hh:mm:ss\\[\\.fffffffff\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/ParseUtils.java","lineNumber":399,"sourceCode":"     * @param str The string to parse.\n     * @return A long value representing the number of nanoseconds since midnight.\n     * @throws ParseException if the string cannot be parsed.\n     * @see <a href=\"https://cassandra.apache.org/doc/cql3/CQL-2.2.html#usingtime\">'Working with time'\n     * section of CQL specification</a>\n     */\n    static long parseTime(String str) throws ParseException\n    {\n        String nanos_s;\n\n        long hour;\n        long minute;\n        long second;\n        long a_nanos = 0;\n\n        String formatError = \"Timestamp format must be hh:mm:ss[.fffffffff]\";\n        String zeros = \"000000000\";\n\n        if (str == null) throw new IllegalArgumentException(formatError);\n        str = str.trim();\n\n        // Parse the time\n        int firstColon = str.indexOf(':');\n        int secondColon = str.indexOf(':', firstColon + 1);\n\n        // Convert the time; default missing nanos\n        if (firstColon > 0 && secondColon > 0 && secondColon < str.length() - 1)\n        {\n            int period = str.indexOf('.', secondColon + 1);\n            hour = Integer.parseInt(str.substring(0, firstColon));\n            if (hour < 0 || hour >= 24) throw new IllegalArgumentException(\"Hour out of bounds.\");\n\n            minute = Integer.parseInt(str.substring(firstColon + 1, secondColon));\n            if (minute < 0 || minute >= 60) throw new IllegalArgumentException(\"Minute out of bounds.\");\n\n            if (period > 0 && period < str.length() - 1)\n            {","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/ParseUtils.java#L381-L417","documentation":"parseTime parses a CQL `time` literal string into nanos-since-midnight. This IllegalArgumentException is the generic format failure: the input is null, has no two colons in the expected hh:mm:ss arrangement, or has a malformed fractional-seconds part. It mirrors the driver-side parser for CQL time values.","triggerScenarios":"Calling ParseUtils.parseTime(null); passing a string without colons (e.g. \"1230\"); only one colon (\"12:30\"); trailing colon with nothing after second colon (\"12:30:\"); a fractional part longer than 9 digits or starting with a non-digit; or a trailing dot like \"12:30:30.\" (parsed via the ParseException path at the same message).","commonSituations":"Reading `time` columns from user input, CSV/JSON imports, or config files where values like \"1:30\" (single leading digit is fine, but \"1h30m\" or \"01:30 PM\" are not), ISO-8601 durations (\"PT1H30M\"), or \"hh:mm\" without seconds are supplied instead of hh:mm:ss[.fffffffff].","solutions":["Normalize the input to hh:mm:ss before parsing, e.g. expand \"01:30\" to \"01:30:00\".","Strip/convert alternate formats (AM/PM, ISO-8601 durations) to hh:mm:ss[.fffffffff] with a pre-parser.","Validate with a regex ^\\d{1,2}:\\d{2}:\\d{2}(\\.\\d{1,9})?$ before calling parseTime.","Catch IllegalArgumentException and surface a user-friendly message naming the expected format."],"exampleFix":"// before\nlong nanos = ParseUtils.parseTime(\"01:30 PM\"); // throws\n// after\nString normalized = \"01:30 PM\".replace(\" PM\", \"\"); // better: convert to 24h\nlong nanos = ParseUtils.parseTime(normalized + \":00\"); // \"13:30:00\"","handlingStrategy":"validation","validationCode":"private static final Pattern TIME = Pattern.compile(\"^\\\\d{1,2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d{1,9})?$\");\nif (str == null || !TIME.matcher(str.trim()).matches())\n    throw new IllegalArgumentException(\"time must be hh:mm:ss[.fffffffff]: \" + str);","typeGuard":null,"tryCatchPattern":"try { return ParseUtils.parseTime(s); }\ncatch (IllegalArgumentException e) { throw new IllegalArgumentException(\"Invalid time literal '\" + s + \"': \" + e.getMessage(), e); }","preventionTips":["Validate time strings with a regex before parsing","Normalize user/CSV input (add :00 seconds, strip AM/PM) up front","Never pass null or untrimmed raw input to parseTime"],"tags":["parsing","time","illegal-argument","cql"],"backgroundTag":"invalid-date-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}