UNPKG

subforge

Version:

High-performance subtitle toolkit for parsing, converting, and authoring across 20+ formats.

68 lines (59 loc) 2.23 kB
/** * Parses an SBV timestamp string to milliseconds. * * SBV format allows variable-length hours (H:MM:SS.mmm or HH:MM:SS.mmm). * * @param s - Timestamp string in SBV format (H:MM:SS.mmm) * @returns Time in milliseconds * @throws {Error} If the timestamp format is invalid or milliseconds aren't exactly 3 digits * * @example * ```ts * parseTime('0:01:23.456') // 83456 * parseTime('1:30:15.000') // 5415000 * ``` */ export function parseTime(s: string): number { // SBV format: H:MM:SS.mmm or HH:MM:SS.mmm (variable length hours) // Find the separators const firstColon = s.indexOf(':') if (firstColon === -1) throw new Error(`Invalid SBV timestamp: ${s}`) const secondColon = s.indexOf(':', firstColon + 1) if (secondColon === -1) throw new Error(`Invalid SBV timestamp: ${s}`) const dot = s.indexOf('.', secondColon + 1) if (dot === -1) throw new Error(`Invalid SBV timestamp: ${s}`) // Validate milliseconds are exactly 3 digits const msStr = s.substring(dot + 1) if (msStr.length !== 3) throw new Error(`Invalid SBV timestamp: ${s}`) // Parse each component const h = parseInt(s.substring(0, firstColon), 10) const m = parseInt(s.substring(firstColon + 1, secondColon), 10) const ss = parseInt(s.substring(secondColon + 1, dot), 10) const ms = parseInt(msStr, 10) if (isNaN(h) || isNaN(m) || isNaN(ss) || isNaN(ms)) { throw new Error(`Invalid SBV timestamp: ${s}`) } return h * 3600000 + m * 60000 + ss * 1000 + ms } /** * Formats milliseconds to SBV timestamp format. * * SBV uses single-digit hours (no leading zero) and period as decimal separator. * * @param ms - Time in milliseconds * @returns Formatted timestamp string (H:MM:SS.mmm) * * @example * ```ts * formatTime(83456) // "0:01:23.456" * formatTime(5415000) // "1:30:15.000" * ``` */ export function formatTime(ms: number): string { const h = Math.floor(ms / 3600000) const m = Math.floor((ms % 3600000) / 60000) const s = Math.floor((ms % 60000) / 1000) const millis = ms % 1000 // SBV uses single-digit hours (no leading zero), period instead of comma return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}.${millis.toString().padStart(3, '0')}` }