import { Zone } from "luxon";
import { CapturedAtTagNames } from "./CapturedAtTagNames";
import { ExifToolOptions } from "./ExifToolOptions";
import { Maybe } from "./Maybe";
import { Tags } from "./Tags";
/**
 * Archaic timezone offsets that have not been in use since 1982 or earlier
 */
export declare const ArchaicTimezoneOffsets: readonly ["-10:30", "-04:30", "-00:44", "-00:25:21", "+00:20", "+00:30", "+01:24", "+01:30", "+02:30", "+04:51", "+05:40", "+07:20", "+07:30"];
/**
 * Valid timezone offsets that are currently in use, or used after 1982
 */
export declare const ValidTimezoneOffsets: readonly ["-11:00", "-10:00", "-09:30", "-09:00", "-08:30", "-08:00", "-07:00", "-06:00", "-05:00", "-04:00", "-03:30", "-03:00", "-02:30", "-02:00", "-01:00", "+00:00", "+01:00", "+02:00", "+03:00", "+03:30", "+04:00", "+04:30", "+05:00", "+05:30", "+05:45", "+06:00", "+06:30", "+07:00", "+08:00", "+08:30", "+08:45", "+09:00", "+09:30", "+09:45", "+10:00", "+10:30", "+11:00", "+12:00", "+12:45", "+13:00", "+13:45", "+14:00"];
export type TimezoneOffset = (typeof ValidTimezoneOffsets | typeof ArchaicTimezoneOffsets)[number];
/**
 * Zone instances with this offset are a placeholder for being "unset".
 */
export declare const UnsetZoneOffsetMinutes = -1;
/**
 * This is a placeholder for dates where the zone is unknown/unset, because
 * Luxon doesn't officially support "unset" zones.
 */
export declare const UnsetZone: Zone<boolean>;
/**
 * Zone instances with this name are a placeholder for being "unset".
 */
export declare const UnsetZoneName: string;
/**
 * Check if a timezone value represents UTC.
 *
 * Handles multiple UTC representations including Zone instances, strings, and
 * numeric offsets. Recognizes common UTC aliases like "GMT", "Z", "Zulu",
 * "+0", "+00:00", etc.
 *
 * @param zone - Timezone to check (Zone, string, or number)
 * @returns true if the zone represents UTC/GMT/Zulu
 *
 * @example
 * ```typescript
 * isUTC("UTC")              // true
 * isUTC("GMT")              // true
 * isUTC("Z")                // true
 * isUTC("Zulu")             // true
 * isUTC(0)                  // true
 * isUTC("+00:00")           // true
 * isUTC("UTC+0")            // true
 * isUTC("America/New_York") // false
 * isUTC("+08:00")           // false
 * ```
 */
export declare function isUTC(zone: unknown): boolean;
/**
 * Check if a Zone is the library's sentinel "unset" value.
 *
 * The library uses a special Zone instance to represent unknown/unset
 * timezones since Luxon doesn't officially support unset zones.
 *
 * @param zone - Zone instance to check
 * @returns true if the zone is the UnsetZone sentinel value
 *
 * @see {@link UnsetZone}
 * @see {@link UnsetZoneName}
 * @see {@link UnsetZoneOffsetMinutes}
 *
 * @example
 * ```typescript
 * isZoneUnset(UnsetZone)                    // true
 * isZoneUnset(Info.normalizeZone("UTC"))    // false
 * isZoneUnset(Info.normalizeZone("UTC+8"))  // false
 * ```
 */
export declare function isZoneUnset(zone: unknown): boolean;
/**
 * Type guard to check if a Zone is valid and usable.
 *
 * A zone is considered valid if it:
 * - Is not null/undefined
 * - Has `isValid === true` (Luxon requirement)
 * - Is not the library's UnsetZone sentinel
 * - Has an offset within ±14 hours (the valid range for real-world timezones)
 *
 * This is the canonical validation check used throughout the library.
 *
 * @param zone - Zone to validate
 * @returns true if the zone is valid and usable (type guard)
 *
 * @example
 * ```typescript
 * const zone = Info.normalizeZone("America/Los_Angeles")
 * if (isZoneValid(zone)) {
 *   // TypeScript knows zone is Zone (not Zone | undefined)
 *   console.log(zone.name)
 * }
 *
 * isZoneValid(Info.normalizeZone("invalid"))  // false
 * isZoneValid(Info.normalizeZone("UTC+8"))    // true
 * isZoneValid(UnsetZone)                      // false
 * isZoneValid(Info.normalizeZone("UTC+20"))   // false (beyond ±14 hours)
 * ```
 */
export declare function isZoneValid(zone: Maybe<Zone>): zone is Zone<true>;
/**
 * Type guard to check if a value is a **valid** Luxon Zone instance.
 *
 * Note that this **includes** the {@link UnsetZone} sentinel value.
 *
 * Checks both `instanceof Zone` and constructor name to handle cross-module
 * Zone instances that may not pass instanceof checks.
 *
 * @param value - Value to check
 * @returns true if the value is a Zone instance (type guard)
 *
 * @example
 * ```typescript
 * import { Info } from "luxon"
 *
 * const zone = Info.normalizeZone("UTC+8")
 * if (isZone(zone)) {
 *   // TypeScript knows zone is Zone (not unknown)
 *   console.log(zone.offset(Date.now()))
 * }
 *
 * isZone(Info.normalizeZone("UTC"))  // true
 * isZone("UTC")                      // false
 * isZone(480)                        // false
 * isZone(null)                       // false
 * ```
 */
export declare function isZone(value: unknown): value is Zone<true>;
/**
 * If `tzSource` matches this value, the tags are from a video, and we had to
 * resort to assuming time fields are in UTC.
 * @see https://github.com/photostructure/exiftool-vendored.js/issues/113
 */
export declare const defaultVideosToUTC = "defaultVideosToUTC";
/**
 * Composable regex pattern for matching timezone offsets.
 *
 * Designed for embedding in larger patterns (no ^ or $ anchors).
 * Matches UTC/GMT/Z or signed offsets in both ISO 8601 extended format
 * (+08:00, -05:30) and basic format (+0800, -0530).
 *
 * Named capture groups:
 * - `tz_utc`: Matches "Z", "UTC", or "GMT"
 * - `tz_sign`: The sign character (+, -, or Unicode minus −)
 * - `tz_hours`: Hour offset (1-2 digits)
 * - `tz_minutes`: Optional minute offset (2 digits)
 *
 * @example
 * ```typescript
 * // Concatenate with other patterns
 * const dateTimeRE = new RegExp(
 *   `(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})${TimezoneOffsetRE.source}`
 * )
 *
 * // Use standalone
 * const match = TimezoneOffsetRE.exec("2023-01-15T10:30:00-08:00")
 * if (match?.groups) {
 *   const { tz_sign, tz_hours, tz_minutes } = match.groups
 *   // tz_sign = "-", tz_hours = "08", tz_minutes = "00"
 * }
 * ```
 */
export declare const TimezoneOffsetRE: RegExp;
/**
 * Result of parsing a timezone offset regex match.
 */
export interface TimezoneOffsetMatch {
    /** Offset in minutes (e.g., 480 for UTC+8, -300 for UTC-5) */
    offsetMinutes: number;
    /** Whether this was a UTC/GMT/Z match */
    isUtc: boolean;
}
/**
 * Parse timezone offset from a regex match result.
 *
 * Use with {@link TimezoneOffsetRE} to extract offset minutes from a match.
 *
 * @param match - RegExp exec result from TimezoneOffsetRE
 * @returns Parsed offset info, or undefined if match is invalid
 *
 * @example
 * ```typescript
 * const match = TimezoneOffsetRE.exec("2023-01-15T10:30:00-08:00")
 * const result = parseTimezoneOffsetMatch(match)
 * // { offsetMinutes: -480, isUtc: false }
 * ```
 */
export declare function parseTimezoneOffsetMatch(match: RegExpExecArray | null): Maybe<TimezoneOffsetMatch>;
/**
 * Parse a timezone offset string to offset minutes.
 *
 * Accepts multiple formats:
 * - ISO 8601: "+08:00", "-05:30", "Z"
 * - Luxon format: "UTC+8", "GMT-5"
 * - UTC variants: "UTC", "GMT", "Zulu"
 *
 * Supports seconds for archaic offsets like "-00:25:21" (Ireland 1880-1916).
 *
 * **Note:** Does NOT validate that the offset is a real-world timezone offset.
 * Use {@link validTzOffsetMinutes} for validation.
 *
 * @param str - Timezone offset string
 * @returns Offset in minutes, or undefined if invalid
 *
 * @example
 * ```typescript
 * parseTimezoneOffsetToMinutes("+08:00")     // 480
 * parseTimezoneOffsetToMinutes("UTC-5")      // -300
 * parseTimezoneOffsetToMinutes("Z")          // 0
 * parseTimezoneOffsetToMinutes("-00:25:21")  // -25.35 (archaic Ireland)
 * parseTimezoneOffsetToMinutes("invalid")   // undefined
 * ```
 */
export declare function parseTimezoneOffsetToMinutes(str: string): Maybe<number>;
/**
 * Normalize a timezone input to a valid Luxon Zone.
 *
 * Accepts multiple input formats and returns a validated Zone instance, or
 * undefined if the input cannot be normalized to a valid timezone.
 *
 * Supported input formats:
 * - **Numbers**: Timezone offset in minutes (e.g., 480 = UTC+8, -300 = UTC-5)
 * - **Strings**: ISO offsets ("+08:00", "-05:00"), IANA zones
 *   ("America/Los_Angeles"), UTC variants ("UTC", "GMT", "Z", "Zulu")
 * - **Zone instances**: Validated and returned if valid
 *
 * The function respects Settings:
 * - {@link Settings.allowArchaicTimezoneOffsets} for pre-1982 offsets
 * - {@link Settings.allowBakerIslandTime} for UTC-12:00
 *
 * @param input - Timezone in various formats
 * @returns Valid Zone instance, or undefined if invalid
 *
 * @example
 * ```typescript
 * // Numbers (offset in minutes)
 * normalizeZone(480)?.name     // "UTC+8"
 * normalizeZone(-300)?.name    // "UTC-5"
 * normalizeZone(0)?.name       // "UTC"
 *
 * // ISO offset strings
 * normalizeZone("+08:00")?.name      // "UTC+8"
 * normalizeZone("-05:30")?.name      // "UTC-5:30"
 * normalizeZone("UTC+7")?.name       // "UTC+7"
 *
 * // IANA timezone names
 * normalizeZone("America/Los_Angeles")?.name  // "America/Los_Angeles"
 * normalizeZone("Asia/Tokyo")?.name           // "Asia/Tokyo"
 *
 * // UTC aliases
 * normalizeZone("UTC")?.name   // "UTC"
 * normalizeZone("GMT")?.name   // "UTC"
 * normalizeZone("Z")?.name     // "UTC"
 * normalizeZone("Zulu")?.name  // "UTC"
 *
 * // Invalid inputs return undefined
 * normalizeZone("invalid")     // undefined
 * normalizeZone("+25:00")      // undefined (beyond ±14 hours)
 * normalizeZone(1200)          // undefined (20 hours, beyond ±14 hours)
 * normalizeZone(100)           // undefined (not a valid timezone offset)
 * normalizeZone(-1)            // undefined (UnsetZone sentinel)
 * normalizeZone(null)          // undefined
 * ```
 */
export declare function normalizeZone(input: unknown): Maybe<Zone>;
/**
 * Convert a timezone to its short offset format (e.g., "+08:00", "-05:00").
 *
 * Useful for displaying timezone offsets in a standardized format. For IANA
 * zones with daylight saving time, provide a timestamp to get the correct
 * offset for that moment.
 *
 * @param zone - Timezone as Zone, string, or offset in minutes
 * @param ts - Optional timestamp (milliseconds) for IANA zone offset calculation.
 *             Defaults to current time if not provided.
 * @returns Zone offset in "+HH:MM" format, or "" if zone is invalid
 *
 * @example
 * ```typescript
 * // Fixed offsets
 * zoneToShortOffset("UTC+8")      // "+08:00"
 * zoneToShortOffset(480)          // "+08:00"
 * zoneToShortOffset("UTC-5:30")   // "-05:30"
 *
 * // IANA zones (offset depends on DST)
 * const winter = new Date("2023-01-15").getTime()
 * const summer = new Date("2023-07-15").getTime()
 * zoneToShortOffset("America/Los_Angeles", winter)  // "-08:00" (PST)
 * zoneToShortOffset("America/Los_Angeles", summer)  // "-07:00" (PDT)
 *
 * // Invalid zones return empty string
 * zoneToShortOffset("invalid")  // ""
 * zoneToShortOffset(null)       // ""
 * ```
 */
export declare function zoneToShortOffset(zone: Maybe<string | number | Zone>, ts?: number): string;
/**
 * Type guard to check if a numeric offset (in minutes) represents a valid timezone.
 *
 * Validates that the offset:
 * - Is a number (not null/undefined)
 * - Is not the UnsetZone sentinel value (-1)
 * - Matches a real-world timezone offset (respects Settings for archaic offsets)
 *
 * Use this for exact validation without rounding. For error-tolerant rounding to
 * the nearest valid offset, use {@link inferLikelyOffsetMinutes} instead.
 *
 * @param tzOffsetMinutes - Offset in minutes to validate (e.g., 480 for UTC+8)
 * @returns true if the offset is exactly valid (type guard)
 *
 * @see {@link inferLikelyOffsetMinutes} for error-tolerant rounding
 *
 * @example
 * ```typescript
 * validTzOffsetMinutes(480)    // true (UTC+8)
 * validTzOffsetMinutes(-300)   // true (UTC-5)
 * validTzOffsetMinutes(330)    // true (UTC+5:30, India)
 * validTzOffsetMinutes(345)    // true (UTC+5:45, Nepal)
 *
 * validTzOffsetMinutes(481)    // false (not a valid timezone)
 * validTzOffsetMinutes(-1)     // false (UnsetZone sentinel)
 * validTzOffsetMinutes(null)   // false
 *
 * // Archaic offsets require Settings
 * Settings.allowArchaicTimezoneOffsets.value = false
 * validTzOffsetMinutes(-630)   // false (Hawaii -10:30, archaic)
 *
 * Settings.allowArchaicTimezoneOffsets.value = true
 * validTzOffsetMinutes(-630)   // true (Hawaii -10:30, archaic)
 * ```
 */
export declare function validTzOffsetMinutes(tzOffsetMinutes: Maybe<number>): tzOffsetMinutes is number;
/**
 * Returns a "zone name" (used by `luxon`) that encodes the given offset.
 * @param offsetMinutes - The timezone offset in minutes from UTC
 * @returns The zone name (e.g., "UTC", "UTC+8", "UTC-5:30") or undefined if invalid
 */
export declare function offsetMinutesToZoneName(offsetMinutes: Maybe<number>): Maybe<string>;
export interface TzSrc {
    /**
     * The timezone name, e.g. "America/New_York", "UTC+2", or "Z"
     * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
     */
    zone: string;
    /**
     * The timezone name, e.g. "America/New_York", "UTC+2", or "Z"
     * @deprecated use `zone` instead
     * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
     */
    tz: string;
    /**
     * If given a string, this is the remaining string left after extracting the
     * timezone
     */
    leftovers?: string;
    src: string;
}
/**
 * Extract timezone information from various value types.
 *
 * Handles multiple input formats and performs intelligent parsing:
 * - **Strings**: ISO offsets ("+08:00"), IANA zones, UTC variants, timestamps
 *   with embedded timezones ("2023:01:15 10:30:00-08:00")
 * - **Numbers**: Hour offsets (e.g., -8 for UTC-8)
 * - **Arrays**: Uses first non-null value
 * - **ExifDateTime/ExifTime instances**: Extracts their zone property
 *
 * By default, strips timezone abbreviations (PST, PDT, etc.) as they are
 * ambiguous. Returns provenance information indicating which parsing method
 * succeeded.
 *
 * Supports Unicode minus signs (−, U+2212) and plus-minus signs (±, U+00B1)
 * in addition to ASCII +/-.
 *
 * @param value - Value to extract timezone from
 * @param opts.stripTZA - Whether to strip timezone abbreviations (default: true).
 *                        TZAs like "PST" are ambiguous and usually stripped.
 * @returns TzSrc with zone name and provenance, or undefined if no timezone found
 *
 * @example
 * ```typescript
 * // ISO offset strings
 * extractZone("+08:00")
 * // { zone: "UTC+8", tz: "UTC+8", src: "offsetMinutesToZoneName" }
 *
 * extractZone("UTC-5:30")
 * // { zone: "UTC-5:30", tz: "UTC-5:30", src: "normalizeZone" }
 *
 * // IANA zone names
 * extractZone("America/Los_Angeles")
 * // { zone: "America/Los_Angeles", tz: "America/Los_Angeles", src: "normalizeZone" }
 *
 * // Timestamps with embedded timezones
 * extractZone("2023:01:15 10:30:00-08:00")
 * // { zone: "UTC-8", tz: "UTC-8", src: "offsetMinutesToZoneName",
 * //   leftovers: "2023:01:15 10:30:00" }
 *
 * // Unicode minus signs
 * extractZone("−08:00")  // Unicode minus (U+2212)
 * // { zone: "UTC-8", tz: "UTC-8", src: "offsetMinutesToZoneName" }
 *
 * // Numeric hour offsets
 * extractZone(-8)
 * // { zone: "UTC-8", tz: "UTC-8", src: "hourOffset" }
 *
 * // Arrays (uses first non-null)
 * extractZone([null, "+05:30", undefined])
 * // { zone: "UTC+5:30", tz: "UTC+5:30", src: "offsetMinutesToZoneName" }
 *
 * // Strips timezone abbreviations by default
 * extractZone("2023:01:15 10:30:00-08:00 PST")
 * // { zone: "UTC-8", tz: "UTC-8", src: "offsetMinutesToZoneName",
 * //   leftovers: "2023:01:15 10:30:00" }
 *
 * // Invalid inputs return undefined
 * extractZone("invalid")  // undefined
 * extractZone(null)       // undefined
 * ```
 */
export declare function extractZone(value: unknown, opts?: {
    stripTZA?: boolean;
}): Maybe<TzSrc>;
export declare const TimezoneOffsetTagnames: readonly ["TimeZone", "OffsetTimeOriginal", "OffsetTimeDigitized", "TimeZoneOffset"];
export declare function incrementZone(z: string | Zone | number, minutes: number): Maybe<Zone>;
/**
 * Extract timezone offset from standard EXIF timezone tags.
 *
 * Checks timezone tags in priority order:
 * 1. TimeZone
 * 2. OffsetTimeOriginal (for DateTimeOriginal)
 * 3. OffsetTimeDigitized (for CreateDate)
 * 4. TimeZoneOffset
 *
 * Handles camera-specific quirks like Nikon's DaylightSavings tag, which
 * requires adjusting the TimeZone offset forward by one hour during DST.
 *
 * @param t - EXIF tags object
 * @param opts.adjustTimeZoneIfDaylightSavings - Optional function to adjust
 *        timezone for DST. Defaults to handling Nikon's DaylightSavings quirk.
 * @returns TzSrc with zone and provenance, or undefined if no timezone found
 *
 * @see {@link TimezoneOffsetTagnames} for the list of tags checked
 * @see https://github.com/photostructure/exiftool-vendored.js/issues/215
 *
 * @example
 * ```typescript
 * const tags = await exiftool.read("photo.jpg")
 *
 * const tzSrc = extractTzOffsetFromTags(tags)
 * if (tzSrc) {
 *   console.log(`Timezone: ${tzSrc.zone}`)
 *   console.log(`Source: ${tzSrc.src}`)  // e.g., "OffsetTimeOriginal"
 * }
 *
 * // Nikon DST handling
 * const nikonTags = {
 *   TimeZone: "-08:00",
 *   DaylightSavings: "Yes",
 *   Make: "NIKON CORPORATION"
 * }
 * extractTzOffsetFromTags(nikonTags)
 * // { zone: "UTC-7", tz: "UTC-7",
 * //   src: "TimeZone (adjusted for DaylightSavings)" }
 * ```
 */
export declare function extractTzOffsetFromTags(t: Tags, opts?: Pick<ExifToolOptions, "adjustTimeZoneIfDaylightSavings">): Maybe<TzSrc>;
export declare function extractTzOffsetFromDatestamps(t: Tags, opts: Partial<Pick<ExifToolOptions, "inferTimezoneFromDatestamps" | "inferTimezoneFromDatestampTags">>): Maybe<TzSrc>;
export declare function extractTzOffsetFromTimeStamp(t: Tags, opts: Partial<Pick<ExifToolOptions, "inferTimezoneFromTimeStamp" | "inferTimezoneFromDatestampTags">>): Maybe<TzSrc>;
/**
 * Round an arbitrary offset to the nearest valid timezone offset.
 *
 * This is error-tolerant timezone inference, useful for:
 * - GPS-based timezone calculation (where GPS time drift may cause errors)
 * - Handling clock drift in timestamp comparisons
 * - Fuzzy timezone matching
 *
 * By default, uses {@link Settings.maxValidOffsetMinutes} (30 minutes) as the
 * maximum distance from a valid timezone. This threshold handles GPS acquisition
 * lag and clock drift while preventing false matches.
 *
 * Respects Settings for archaic offsets, Baker Island time, and max offset tolerance.
 *
 * @param deltaMinutes - Offset in minutes to round (can be fractional)
 * @param maxValidOffsetMinutes - Maximum distance (in minutes) from a valid
 *        timezone to accept. Defaults to {@link Settings.maxValidOffsetMinutes}.
 * @returns Nearest valid offset in minutes, or undefined if too far from any
 *          valid timezone
 *
 * @see {@link validTzOffsetMinutes} for exact validation without rounding
 * @see {@link Settings.maxValidOffsetMinutes} to configure the default threshold
 *
 * @example
 * ```typescript
 * // Exact matches
 * inferLikelyOffsetMinutes(480)      // 480 (UTC+8, exact)
 * inferLikelyOffsetMinutes(-300)     // -300 (UTC-5, exact)
 *
 * // Rounding within default threshold (30 minutes)
 * inferLikelyOffsetMinutes(485)      // 480 (UTC+8, rounded from 485)
 * inferLikelyOffsetMinutes(-295)     // -300 (UTC-5, rounded from -295)
 * inferLikelyOffsetMinutes(330.5)    // 330 (UTC+5:30, rounded)
 *
 * // GPS-based inference with clock drift (within 30 min default)
 * const gpsTime = "2023:01:15 19:30:45"  // UTC
 * const localTime = "2023:01:15 11:32:12"  // Local with 1.5min drift
 * const deltaMinutes = 480 + 1.5  // ~481.5 minutes
 * inferLikelyOffsetMinutes(deltaMinutes)  // 480 (UTC+8)
 *
 * // GPS lag up to 23 minutes still works (within 30 min threshold)
 * inferLikelyOffsetMinutes(443)      // 420 (UTC-7, ~23 min from actual)
 *
 * // Beyond threshold returns undefined
 * inferLikelyOffsetMinutes(100)      // undefined (not near any valid offset)
 *
 * // Custom threshold
 * inferLikelyOffsetMinutes(495, 30)  // 480 (UTC+8 with 30min threshold)
 * inferLikelyOffsetMinutes(495, 15)  // undefined (beyond 15min threshold)
 *
 * // Adjust global default
 * Settings.maxValidOffsetMinutes.value = 15  // Stricter matching
 * inferLikelyOffsetMinutes(443)      // undefined (beyond 15min threshold)
 * ```
 */
export declare function inferLikelyOffsetMinutes(deltaMinutes: Maybe<number>, maxValidOffsetMinutes?: number): Maybe<number>;
/**
 * Infer timezone offset by comparing local time with GPS/UTC time.
 *
 * Calculates the timezone by finding the difference between:
 * - A "captured at" timestamp (DateTimeOriginal, CreateDate, etc.) assumed to
 *   be in local time
 * - A UTC timestamp (GPSDateTime, DateTimeUTC, or combined GPSDateStamp +
 *   GPSTimeStamp)
 *
 * Uses {@link inferLikelyOffsetMinutes} to handle minor clock drift and round
 * to the nearest valid timezone offset.
 *
 * This is a fallback when explicit timezone tags are not available.
 *
 * @param t - Tags object with timestamp fields
 * @returns TzSrc with inferred timezone and provenance, or undefined if
 *          inference is not possible
 *
 * @see {@link extractTzOffsetFromTags} to check explicit timezone tags first
 *
 * @example
 * ```typescript
 * // GPS-based inference
 * const tags = {
 *   DateTimeOriginal: "2023:01:15 11:30:00",  // Local time (PST)
 *   GPSDateTime: "2023:01:15 19:30:00"        // UTC
 * }
 * extractTzOffsetFromUTCOffset(tags)
 * // { zone: "UTC-8", tz: "UTC-8",
 * //   src: "offset between DateTimeOriginal and GPSDateTime" }
 *
 * // DateTimeUTC-based inference
 * const tags2 = {
 *   CreateDate: "2023:07:20 14:15:30",  // Local time (JST)
 *   DateTimeUTC: "2023:07:20 05:15:30"  // UTC
 * }
 * extractTzOffsetFromUTCOffset(tags2)
 * // { zone: "UTC+9", tz: "UTC+9",
 * //   src: "offset between CreateDate and DateTimeUTC" }
 *
 * // Handles clock drift
 * const tags3 = {
 *   DateTimeOriginal: "2023:01:15 11:30:45",  // Local with drift
 *   GPSDateTime: "2023:01:15 19:29:58"        // UTC (old GPS fix)
 * }
 * extractTzOffsetFromUTCOffset(tags3)
 * // Still infers UTC-8 despite ~1 minute drift
 *
 * // No UTC timestamp available
 * const tags4 = {
 *   DateTimeOriginal: "2023:01:15 11:30:00"
 *   // No GPS or UTC timestamp
 * }
 * extractTzOffsetFromUTCOffset(tags4)  // undefined
 * ```
 */
export declare function extractTzOffsetFromUTCOffset(t: Pick<Tags, (typeof CapturedAtTagNames)[number] | "GPSDateTime" | "DateTimeUTC" | "GPSDateStamp" | "GPSTimeStamp" | "SonyDateTime2">): Maybe<TzSrc>;
/**
 * Check if two timezone values are equivalent at a specific point in time.
 *
 * Two zones are considered equivalent if they:
 * - Are the same zone (via Luxon's Zone.equals()), OR
 * - Have the same offset at the specified timestamp
 *
 * This is useful for:
 * - De-duplicating timezone records
 * - Comparing zones in different formats ("UTC+5" vs "UTC+05:00")
 * - Matching IANA zones to their offset at a specific time
 *
 * For IANA zones with DST, you can specify a timestamp to evaluate equivalence
 * at that moment. This is important when comparing historical records or future
 * events where DST transitions matter.
 *
 * @param a - First timezone (Zone, string, or offset in minutes)
 * @param b - Second timezone (Zone, string, or offset in minutes)
 * @param at - Timestamp in milliseconds to evaluate zone offsets.
 *             Defaults to current time (Date.now()).
 * @returns true if zones are equivalent at the specified time
 *
 * @example
 * ```typescript
 * // Same zone, different formats
 * equivalentZones("UTC+5", "UTC+05:00")     // true
 * equivalentZones("UTC-8", -480)            // true (480 minutes = 8 hours)
 * equivalentZones("GMT", "UTC")             // true
 * equivalentZones("Z", 0)                   // true
 *
 * // IANA zones matched by current offset (default behavior)
 * equivalentZones("America/New_York", "UTC-5")  // true in winter (EST)
 * equivalentZones("America/New_York", "UTC-4")  // true in summer (EDT)
 *
 * // IANA zones at specific times
 * const winter = new Date("2023-01-15").getTime()
 * const summer = new Date("2023-07-15").getTime()
 * equivalentZones("America/New_York", "UTC-5", winter)  // true (EST)
 * equivalentZones("America/New_York", "UTC-4", winter)  // false (not EDT in winter)
 * equivalentZones("America/New_York", "UTC-4", summer)  // true (EDT)
 * equivalentZones("America/New_York", "UTC-5", summer)  // false (not EST in summer)
 *
 * // Compare two IANA zones at a specific time
 * equivalentZones("America/New_York", "America/Toronto", winter)  // true (both EST)
 * equivalentZones("America/New_York", "America/Los_Angeles", winter)  // false (EST vs PST)
 *
 * // Different zones
 * equivalentZones("UTC+8", "UTC+9")         // false
 *
 * // Invalid zones return false
 * equivalentZones("invalid", "UTC")         // false
 * equivalentZones(null, "UTC")              // false
 * ```
 */
export declare function equivalentZones(a: Maybe<string | number | Zone>, b: Maybe<string | number | Zone>, at?: number): boolean;
export declare function getZoneName(args?: {
    zone?: Zone;
    zoneName?: Maybe<string>;
    tzoffsetMinutes?: Maybe<number>;
}): Maybe<string>;
