/** * 安静时段内的通知推迟到安静时段结束的整点;不在安静时段则立即发送。 * 起止相同表示没有安静时段。 * ponytail: 用「距结束还有几小时几分」推算,夏令时切换当晚会差一小时;要精确就换成按时区构造目标时刻。 * * @param {Date} now * @param {{ timezone: string, quiet_start_hour: number, quiet_end_hour: number }} settings * @returns {Date} */ export function nextAllowedSendTime(now, { timezone, quiet_start_hour, quiet_end_hour }) { const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: 'numeric', second: 'numeric', hourCycle: 'h23' }).formatToParts(now) const part = (/** @type {string} */ type) => Number(parts.find((item) => item.type === type).value) const hour = part('hour') const quiet = quiet_start_hour < quiet_end_hour ? hour >= quiet_start_hour && hour < quiet_end_hour : quiet_start_hour > quiet_end_hour && (hour >= quiet_start_hour || hour < quiet_end_hour) if (!quiet) return now const secondsLeft = ((quiet_end_hour - hour + 24) % 24) * 3600 - part('minute') * 60 - part('second') return new Date(now.getTime() - now.getMilliseconds() + secondsLeft * 1000) }