Repository: mermaid-js/mermaid
File: packages/mermaid/src/diagrams/gantt/ganttDb.js (JavaScript)

Code before:
      }
    }

    if (latestTask) {
      return latestTask.endTime;
    }
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return today;
  }

  // Check for actual date set
  let mDate = dayjs(str, dateFormat.trim(), true);
  if (mDate.isValid()) {
    return mDate.toDate();
  } else {
    log.debug('Invalid date:' + str);
    log.debug('With date format:' + dateFormat.trim());

    // Only allow fallback for formats that are simple timestamps (x, X)
    // which represent Unix timestamps. For all other formats, if dayjs
    // strict parsing fails - throws an error.
    const isTimestampFormat = dateFormat.trim() === 'x' || dateFormat.trim() === 'X';

    if (!isTimestampFormat) {
      log.debug(`Invalid date: "${str}" does not match format "${dateFormat.trim()}".`);
    }

    const d = new Date(str);
    if (
      d === undefined ||
      isNaN(d.getTime()) ||
      // WebKit browsers can mis-parse invalid dates to be ridiculously
      // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304.
      // This can cause virtually infinite loops while rendering, so for the
      // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as
      // invalid.
      d.getFullYear() < -10000 ||
      d.getFullYear() > 10000
    ) {
      throw new Error('Invalid date:' + str);
    }
    return d;
  }
};

/**
 * Parse a string into the args for `dayjs.add()`.
 *
 * The string have to be compound by a value and a shorthand duration unit. For example `5d`
 * represents 5 days.

Review comment (bug):
This debug log statement is redundant - it duplicates the information already logged on lines 301-302. The additional detail about the format mismatch doesn't add significant value since the same information is already available in the preceding logs. Consider removing this redundant log or consolidating it with the earlier logs.
```suggestion
      // Redundant log removed: already logged above.
```

Code after:

  if (afterStatement !== null) {
    // check all after ids and take the latest
    let latestTask = null;
    for (const id of afterStatement.groups.ids.split(' ')) {
      let task = findTaskById(id);
      if (task !== undefined && (!latestTask || task.endTime > latestTask.endTime)) {
        latestTask = task;
      }
    }

    if (latestTask) {
      return latestTask.endTime;
    }
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return today;
  }

  // Check for actual date set using dayjs strict parsing
  let mDate = dayjs(str, dateFormat.trim(), true);
  if (mDate.isValid()) {
    return mDate.toDate();
  } else {
    log.debug('Invalid date:' + str);
    log.debug('With date format:' + dateFormat.trim());

    // Timestamp formats can fall back to new Date()
    const d = new Date(str);
    if (
      d === undefined ||
      isNaN(d.getTime()) ||
      // WebKit browsers can mis-parse invalid dates to be ridiculously
      // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304.
      // This can cause virtually infinite loops while rendering, so for the
      // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as
      // invalid.
      d.getFullYear() < -10000 ||
      d.getFullYear() > 10000
    ) {
      throw new Error('Invalid date:' + str);
    }
    return d;
  }
};

/**
 * Parse a string into the args for `dayjs.add()`.
 *
 * The string have to be compound by a value and a shorthand duration unit. For example `5d`
 * represents 5 days.