// #region Imports
// #endregion
/**
 * A utility class for formatting times using format strings.
 *
 * Supported time format specifiers:
 * - `h`   : Hour (1-12) in 12-hour format without leading zero.
 * - `hh`  : Hour (01-12) in 12-hour format with leading zero.
 * - `H`   : Hour (0-23) in 24-hour format without leading zero.
 * - `HH`  : Hour (00-23) in 24-hour format with leading zero.
 * - `m`   : Minute (0-59) without leading zero.
 * - `mm`  : Minute (00-59) with leading zero.
 * - `s`   : Second (0-59) without leading zero.
 * - `ss`  : Second (00-59) with leading zero.
 * - `t`   : First character of the AM/PM designator (e.g., A or P).
 * - `tt`  : Full AM/PM designator (e.g., AM or PM).
 * - `:`   : Time separator (e.g., colon).
 * - `-`   : Custom separator (e.g., hyphen).
 * - ` `   : Space separator.
 *
 * @public
 */
export class TimeFormatter {
    // #region Fields
    static _validSpecifiers = [
        'h', 'hh', 'H', 'HH', 'm', 'mm', 's', 'ss', 't', 'tt', ':', '-', ' '
    ];
    // #endregion
    // #region Methods
    /**
     * Formats a time using a time-specific format string.
     *
     * @remarks
     * This method uses raw numeric extraction from the Date object to ensure
     * consistent output across all locales. It does not rely on `Intl.DateTimeFormat`
     * for numeric values to avoid locale-specific suffixes (e.g., German "Uhr").
     *
     * @param date The date object containing the time to format.
     * @param format The format string.
     * @param locale The locale for AM/PM designator (default: 'en-US').
     * @returns The formatted time string.
     */
    static format(date, format, locale = 'en-US') {
        const segments = format.match(/h{1,2}|H{1,2}|m{1,2}|s{1,2}|t{1,2}|[-: ]+/g);
        if (!segments) {
            throw new Error(`Unable to parse format string: "${format}".`);
        }
        const hours24 = date.getHours();
        const hours12 = hours24 % 12 || 12; // Convert 0 to 12 for 12-hour format
        const minutes = date.getMinutes();
        const seconds = date.getSeconds();
        const result = segments
            .map((segment) => {
            switch (segment) {
                // 12-hour format
                case 'h':
                    return String(hours12);
                case 'hh':
                    return String(hours12).padStart(2, '0');
                // 24-hour format
                case 'H':
                    return String(hours24);
                case 'HH':
                    return String(hours24).padStart(2, '0');
                // Minutes
                case 'm':
                    return String(minutes);
                case 'mm':
                    return String(minutes).padStart(2, '0');
                // Seconds
                case 's':
                    return String(seconds);
                case 'ss':
                    return String(seconds).padStart(2, '0');
                // AM/PM designator
                case 't':
                    return this.getAmPmDesignator(date, locale).charAt(0);
                case 'tt':
                    return this.getAmPmDesignator(date, locale);
                // Separators (colon, hyphen, space, or combinations)
                default:
                    if ((/[-: ]+/).test(segment)) {
                        return segment;
                    }
                    throw new Error(`Unknown time format segment: "${segment}".`);
            }
        })
            .join('');
        return result;
    }
    /**
     * Resolves the locale-aware AM/PM designator for the given date.
     * Uses `Intl.DateTimeFormat.formatToParts` to extract the `dayPeriod` part.
     * Falls back to `"AM"` / `"PM"` if the locale does not provide a day period.
     *
     * @param date - The date whose hour determines AM or PM.
     * @param locale - The BCP 47 locale string used for formatting.
     * @returns The AM/PM designator string (e.g., `"AM"`, `"PM"`, or locale equivalent).
     */
    static getAmPmDesignator(date, locale) {
        const formatter = new Intl.DateTimeFormat(locale, {
            hour: 'numeric',
            hour12: true
        });
        const parts = formatter.formatToParts(date);
        const dayPeriod = parts.find((part) => part.type === 'dayPeriod');
        const isPm = date.getHours() >= 12;
        return dayPeriod?.value ?? (isPm ? 'PM' : 'AM');
    }
}
//# sourceMappingURL=TimeFormatter.js.map