{"record":{"id":"7bcbf23af0906d88","repo":"jackwener/OpenCLI","slug":"2","errorCode":null,"errorMessage":"定时发布时间必须在至少 2 小时后","messagePattern":"定时发布时间必须在至少 2 小时后","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/douyin/_shared/timing.js","lineNumber":8,"sourceCode":"const MIN_OFFSET = 7200; // 2 hours\nconst MAX_OFFSET = 14 * 86400; // 14 days\nexport function validateTiming(unixSeconds) {\n    if (!Number.isFinite(unixSeconds))\n        throw new Error(`无效的时间戳: ${unixSeconds}`);\n    const now = Math.floor(Date.now() / 1000);\n    if (unixSeconds < now + MIN_OFFSET)\n        throw new Error(`定时发布时间必须在至少 2 小时后`);\n    if (unixSeconds > now + MAX_OFFSET)\n        throw new Error(`定时发布时间不能超过 14 天`);\n}\nexport function toUnixSeconds(input) {\n    if (typeof input === 'number')\n        return input;\n    if (/^\\d+$/.test(input)) {\n        return Number(input);\n    }\n    const ms = new Date(input).getTime();\n    if (isNaN(ms))\n        throw new Error(`无效的时间格式: \"${input}\"`);\n    return Math.floor(ms / 1000);\n}\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/_shared/timing.js#L1-L23","documentation":"validateTiming requires scheduled publish time to be at least 2 hours in the future (MIN_OFFSET = 7200). If unixSeconds is finite but earlier than now + 7200, it throws this Error meaning 'scheduled publish time must be at least 2 hours from now' — matching Douyin's scheduling constraints.","triggerScenarios":"Timestamp 0–2 hours ahead of the current time, any timestamp in the past, or a timestamp computed with a wrong unit (milliseconds instead of seconds, which lands far in the past after division confusion).","commonSituations":"Users scheduling 'later today' within 2 hours; forgetting timezone conversion so local time is passed as UTC (or vice versa) shifting the value; passing Date.now() (milliseconds) instead of seconds; immediate-publish calls that accidentally include a near-now timing.","solutions":["Pick a time at least 2 hours (and within 14 days) in the future and recompute the timestamp.","Use Math.floor(Date.now() / 1000) + offset to build seconds-based timestamps, never Date.now() directly.","Check timezone handling: construct the target time in the correct zone before converting to unix seconds.","Validate the timing in UI/CLI code before invoking publish, using the same MIN_OFFSET rule."],"exampleFix":"// before: 30 minutes ahead — rejected\nconst ts = Math.floor(Date.now() / 1000) + 1800;\n// after: 3 hours ahead\nconst ts = Math.floor(Date.now() / 1000) + 3 * 3600;\nvalidateTiming(ts);","handlingStrategy":"validation","validationCode":"const MIN_OFFSET = 7200;\nconst now = Math.floor(Date.now() / 1000);\nif (ts < now + MIN_OFFSET) {\n  ts = now + MIN_OFFSET + 60; // push to just past the 2-hour minimum\n}","typeGuard":"null","tryCatchPattern":"try {\n  validateTiming(ts);\n} catch (e) {\n  if (e.message === '定时发布时间必须在至少 2 小时后') {\n    ts = Math.floor(Date.now() / 1000) + 3 * 3600; // fall back to +3h\n    validateTiming(ts);\n  } else throw e;\n}","preventionTips":["Schedule at least 2h (safely 3h) in the future","Compute timestamps in seconds: Math.floor(Date.now()/1000), never Date.now() directly","Convert local times through the correct timezone before deriving unix seconds","Validate timing in the UI/CLI before submitting the publish request"],"tags":["douyin","validation","scheduling","timezone"],"backgroundTag":"scheduled-time-out-of-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}