{"record":{"id":"313bb083db0b5c0c","repo":"pentaho/pentaho-kettle","slug":"tostring-couldn-t-convert-string-string-to-a-date-using","errorCode":null,"errorMessage":"<toString()> : couldn't convert string [<string>] to a date using format [<dateFormat>] on offset location <e.getErrorOffset()>","messagePattern":"<toString\\(\\)> : couldn't convert string \\[<string>\\] to a date using format \\[<dateFormat>\\] on offset location <e\\.getErrorOffset\\(\\)>","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java","lineNumber":936,"sourceCode":"\n    if ( Utils.isEmpty( string ) ) {\n      return null;\n    }\n\n    try {\n      ParsePosition pp = new ParsePosition( 0 );\n      Date result = getDateFormat( TYPE_DATE ).parse( string, pp );\n      if ( pp.getErrorIndex() >= 0 ) {\n        // error happen\n        throw new ParseException( string, pp.getErrorIndex() );\n      }\n      // some chars can be after pp.getIndex(). That means, not full value was parsed. For example, for value\n      // \"25-03-1918 11:54\" and format \"dd-MM-yyyy\", value will be \"25-03-1918 00:00\" without any exception.\n      // If there are only spaces after pp.getIndex() - that means full values was parsed\n      return result;\n    } catch ( ParseException e ) {\n      String dateFormat = ( getDateFormat() != null ) ? getDateFormat().toPattern() : \"null\";\n      throw new KettleValueException( toString() + \" : couldn't convert string [\" + string\n          + \"] to a date using format [\" + dateFormat + \"] on offset location \" + e.getErrorOffset(), e );\n    }\n  }\n\n  // DATE + NUMBER\n\n  protected Double convertDateToNumber( Date date ) {\n    return new Double( date.getTime() );\n  }\n\n  protected Date convertNumberToDate( Double number ) {\n    return new Date( number.longValue() );\n  }\n\n  // DATE + INTEGER\n\n  protected Long convertDateToInteger( Date date ) {\n    return new Long( date.getTime() );","sourceCodeStart":918,"sourceCodeEnd":954,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java#L918-L954","documentation":"Thrown by ValueMetaBase.convertStringToDate when SimpleDateFormat.parse fails to parse the string using the value meta's date format. The message includes the value meta name, the offending string, the format pattern, and the character offset where parsing failed.","triggerScenarios":"Calling getDate()/convertStringToDate() on a String value that does not match getDateFormat().toPattern(); a null format (shown as 'null') with a non-default-parseable string; locale-sensitive patterns applied to strings produced under a different locale/timezone.","commonSituations":"Missing or wrong conversion mask (e.g. 'yyyy-MM-dd' vs 'dd/MM/yyyy'); data files changing date format after an upstream change; strings with trailing characters or empty input; parsing '25-03-1918 11:54' with a date-only format.","solutions":["Set the correct conversion mask with setConversionDateFormat or getDateFormat matching the actual string (e.g. 'dd/MM/yyyy HH:mm:ss')","Check the sample string against the pattern at the reported error offset","Set the correct locale/timezone on the value meta (setDateFormatLocale/setDateFormatTimeZone)","Pre-validate the string with a DateTimeFormatter before calling getDate"],"exampleFix":"// before\nvalueMeta.setConversionMask(\"yyyy-MM-dd\"); // data is 25/03/1918 11:54\n// after\nvalueMeta.setConversionMask(\"dd/MM/yyyy HH:mm\");","handlingStrategy":"validation","validationCode":"import java.time.format.DateTimeFormatter;\nimport java.time.format.DateTimeParseException;\nimport java.time.LocalDateTime;\nstatic boolean isParseableDate(String s, String pattern) {\n  try {\n    DateTimeFormatter.ofPattern(pattern).parse(s);\n    return true;\n  } catch (DateTimeParseException | NullPointerException e) {\n    return false;\n  }\n}","typeGuard":"static boolean looksLikeDate(String s, String patternRegex) {\n  return s != null && !s.trim().isEmpty() && s.matches(patternRegex);\n}","tryCatchPattern":"try {\n  Date d = valueMeta.getDate(str);\n} catch (KettleValueException e) {\n  log.error(\"Date parse failed: \" + e.getMessage());\n  putRowToErrorRow(str, e.getMessage());\n}","preventionTips":["Always set an explicit conversion mask matching the source data format","Set matching DateFormatLocale and DateFormatTimeZone on the value meta","Sample-validate date columns from new data sources before loading","Watch for date-only masks applied to datetime strings (trailing chars)"],"tags":["date","format","parsing","kettle"],"backgroundTag":"invalid-date-format","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}