mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-31 00:24:38 +00:00
fix(frontend): parse local expiry datetimes strictly
This commit is contained in:
@@ -201,9 +201,63 @@ export function formatDateTimeLocalInput(timestampSeconds: number | null): strin
|
||||
*/
|
||||
export function parseDateTimeLocalInput(value: string): number | null {
|
||||
if (!value) return null
|
||||
const date = new Date(value)
|
||||
if (isNaN(date.getTime())) return null
|
||||
return Math.floor(date.getTime() / 1000)
|
||||
|
||||
// datetime-local intentionally has no timezone. Parse its components explicitly
|
||||
// so malformed values or timezone-bearing strings are not reinterpreted by Date.parse.
|
||||
const match = /^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?$/.exec(value)
|
||||
if (!match) return null
|
||||
|
||||
const year = Number(match[1])
|
||||
const month = Number(match[2])
|
||||
const day = Number(match[3])
|
||||
const hours = Number(match[4])
|
||||
const minutes = Number(match[5])
|
||||
const seconds = match[6] ? Number(match[6]) : 0
|
||||
const milliseconds = match[7]
|
||||
? Number(match[7].slice(0, 3).padEnd(3, '0'))
|
||||
: 0
|
||||
|
||||
if (
|
||||
!Number.isSafeInteger(year) ||
|
||||
year < 1 ||
|
||||
month < 1 ||
|
||||
month > 12 ||
|
||||
day < 1 ||
|
||||
day > 31 ||
|
||||
hours > 23 ||
|
||||
minutes > 59 ||
|
||||
seconds > 59
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const date = new Date(0)
|
||||
date.setFullYear(year, month - 1, day)
|
||||
date.setHours(hours, minutes, seconds, milliseconds)
|
||||
|
||||
// Date setters normalize calendar overflows (for example, February 30). Keep
|
||||
// the platform's existing DST disambiguation for otherwise valid local times.
|
||||
if (
|
||||
date.getFullYear() !== year ||
|
||||
date.getMonth() !== month - 1 ||
|
||||
date.getDate() !== day
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const timestamp = date.getTime()
|
||||
return Number.isFinite(timestamp) ? Math.floor(timestamp / 1000) : null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取浏览器当前使用的 IANA 时区
|
||||
*/
|
||||
export function getBrowserTimeZone(): string {
|
||||
try {
|
||||
return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'
|
||||
} catch {
|
||||
return 'UTC'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user