jackwener/OpenCLI · error · ArgumentError
weibo user-posts ${name} must be a valid calendar date
Error message
weibo user-posts ${name} must be a valid calendar date What it means
After the format check passes, readDate() parses the value as a Shanghai (+08:00) midnight timestamp and round-trips it through formatShanghaiDate. If the parse is non-finite or the round-trip differs from the input (e.g. 2024-02-30), the string was format-valid but not a real calendar date, so this ArgumentError is thrown.
Source
Thrown at clis/weibo/user-posts.js:36
}
function readLimit(raw) {
const value = raw === undefined || raw === null || raw === '' ? DEFAULT_LIMIT : Number(raw);
if (!Number.isInteger(value) || value < 1 || value > MAX_LIMIT) {
throw new ArgumentError(`weibo user-posts limit must be an integer between 1 and ${MAX_LIMIT}`);
}
return value;
}
function readDate(raw, name) {
if (raw === undefined || raw === null || raw === '') return null;
const value = String(raw).trim();
if (!DATE_RE.test(value)) {
throw new ArgumentError(`weibo user-posts ${name} must use YYYY-MM-DD`);
}
const date = new Date(`${value}T00:00:00+08:00`);
if (!Number.isFinite(date.getTime()) || value !== formatShanghaiDate(date)) {
throw new ArgumentError(`weibo user-posts ${name} must be a valid calendar date`);
}
return value;
}
function formatShanghaiDate(date) {
const parts = new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).formatToParts(date);
const get = (type) => parts.find((part) => part.type === type)?.value;
return `${get('year')}-${get('month')}-${get('day')}`;
}
function dateToTimestamp(date) {
return Math.floor(new Date(`${date}T00:00:00+08:00`).getTime() / 1000);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Replace with a real calendar date, e.g. '2023-02-28' or '2024-02-29' for a leap year.
- Validate the date in your script with a Date round-trip before invoking the command.
- If generating ranges programmatically, use date arithmetic instead of string concatenation for the day component.
Example fix
// before
const start = `${year}-02-29`; // throws for non-leap 2023
// after
const start = isLeapYear(year) ? `${year}-02-29` : `${year}-02-28`; Defensive patterns
Strategy: validation
Validate before calling
function isRealCalendarDate(s) {
if (typeof s !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(s)) return false;
const d = new Date(`${s}T00:00:00Z`);
return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
}
if (start && !isRealCalendarDate(start)) throw new Error(`not a real date: ${start}`); Type guard
function isCalendarDate(v) {
if (typeof v !== 'string') return false;
const [y, m, d] = v.split('-').map(Number);
const dt = new Date(Date.UTC(y, m - 1, d));
return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;
} Prevention
- Round-trip generated dates through Date before use.
- Never construct day components by adding to strings; use date arithmetic.
- Watch February 29 handling in leap years.
When it happens
Trigger: Calling start/end with syntactically valid but nonexistent dates such as '2023-02-29' (non-leap year), '2024-04-31', '2024-13-00', or any value where formatting the parsed date back does not reproduce the input.
Common situations: Hand-computed date arithmetic overflowing month ends, template strings like `${year}-02-30`, or dates typed manually with typos in day numbers.
Related errors
- --${name} is not a real calendar date: ${value}
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
- --seat-types must contain only 12306 seat letters/digits (A-
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e84ef0dce8dc9f52.
Report an issue: GitHub.