NAME Time::Str - Parse and format date/time strings in multiple standard formats SYNOPSIS use Time::Str qw( str2time str2date time2str ); # Parse to Unix timestamp my $time = str2time('2024-12-24T15:30:45Z'); my $time = str2time('Mon, 24 Dec 2012 15:30:45 +0100', format => 'RFC2822'); # Parse to components my %date = str2date('2024-12-24T15:30:45.500+01:00'); # (year => 2024, month => 12, day => 24, hour => 15, # minute => 30, second => 45, nanosecond => 500000000, # tz_offset => 60) # Format Unix timestamp my $str = time2str(1735052445); # '2024-12-24T15:30:45Z' my $str = time2str(1735052445, format => 'RFC2822', offset => 60); # 'Tue, 24 Dec 2024 16:30:45 +0100' DESCRIPTION Time::Str parses date/time strings from various standard formats into Unix timestamps or component key-value pairs, and formats Unix timestamps back into strings. Supported standards include ISO 8601, RFC 3339, RFC 2822, RFC 2616 (HTTP), ISO 9075 (SQL), ASN.1, and others. A permissive generic parser handles most real-world date/time representations that can be parsed without ambiguity. FUNCTIONS str2time my $time = str2time($string); my $time = str2time($string, format => $format); my $time = str2time($string, format => $format, precision => $precision); my $time = str2time($string, format => 'ASN1UT', pivot_year => 2000); Parses a date/time string and returns a Unix timestamp (seconds since 1970-01-01T00:00:00Z). The timestamp may include fractional seconds. The input must include a UTC designator ("Z", "UTC", "GMT") or a numeric timezone offset. Strings with only an unresolved timezone abbreviation (e.g., "EST", "IST") will croak. See "TIMEZONE ABBREVIATIONS". Parameters * $string (required) The date/time string to parse. * "format" (optional, default: 'RFC3339') The format specification. See "SUPPORTED FORMATS". * "precision" (optional, default: 6 or 9 depending on float size) Number of decimal places to preserve for fractional seconds (0-9). Fractional digits beyond the specified precision are truncated, not rounded. See "PRECISION HANDLING". * "pivot_year" (optional, default: 1950) For formats with two-digit years ("ASN1UT", RFC 850 within "RFC2616"), sets the pivot year for century expansion. Two-digit years less than "(pivot_year % 100)" map to the next century; others map to the current century. With the default pivot of 1950: 49 becomes 2049, 50 becomes 1950, 99 becomes 1999. Returns A numeric Unix timestamp, possibly with a fractional part. The supported range is 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z. Errors Croaks if: * The string cannot be parsed in the specified format * Date or time components are out of valid ranges * No timezone offset or UTC designator is present Examples # RFC 3339 (default) my $t = str2time('2024-12-24T15:30:45Z'); # 1735052445 my $t = str2time('2024-12-24T15:30:45.500+01:00'); # 1735048845.5 # RFC 2822 my $t = str2time('Mon, 24 Dec 2012 15:30:45 +0100', format => 'RFC2822'); # HTTP my $t = str2time('Mon, 24 Dec 2012 15:30:45 GMT', format => 'RFC2616'); # Precision (truncation, not rounding) my $t = str2time('2024-12-24T15:30:45.123456789Z', precision => 3); # 1735052445.123 my $t = str2time('2024-12-24T15:30:45.999999Z', precision => 3); # 1735052445.999 (NOT 1735052446.000) str2date my %date = str2date($string); my %date = str2date($string, format => $format); my %date = str2date($string, format => 'ASN1UT', pivot_year => 2000); Parses a date/time string and returns the parsed components. Unlike "str2time", this does not require a timezone and preserves all parsed information without converting to a timestamp. Parameters * $string (required) The date/time string to parse. * "format" (optional, default: 'RFC3339') The format specification. See "SUPPORTED FORMATS". * "pivot_year" (optional, default: 1950) For formats with two-digit years, sets the pivot year for century expansion. Returns In list context, returns key-value pairs. In scalar context, returns a hash reference. All values are numeric except "tz_utc", "tz_abbrev", and "tz_annotation". The following components may be present: * "year" - Four-digit year (1-9999) * "month" - Month (1-12) * "day" - Day of month (1-31) * "hour" - Hour in 24-hour format (0-23) * "minute" - Minute (0-59) * "second" - Second (0-60; 60 allows for leap seconds) * "nanosecond" - Fractional seconds as nanoseconds (0-999999999) * "tz_offset" - Timezone offset in minutes from UTC (e.g., 60 for +01:00). Present when a numeric offset or UTC designator was parsed. * "tz_utc" - The matched UTC designator ("Z", "UTC", "GMT") if one was present. When followed by a numeric offset (e.g., "UTC+05:30"), "tz_offset" reflects that offset rather than zero. * "tz_abbrev" - The timezone abbreviation as it appeared in the input, if present and not a UTC designator. "tz_offset" will not be present when "tz_abbrev" is set. See "TIMEZONE ABBREVIATIONS". * "tz_annotation" - Bracketed timezone tag from the input, if present (RFC 9557 IXDTF or Java "ZoneId" format, e.g., "[Europe/Stockholm]"). Informational only; does not affect "tz_offset". Errors Croaks if: * The string cannot be parsed in the specified format * Date or time components are out of valid ranges Examples # Full RFC 3339 timestamp my %d = str2date('2024-12-24T15:30:45.500+01:00'); # (year => 2024, # month => 12, # day => 24, # hour => 15, # minute => 30, # second => 45, # nanosecond => 500000000, # tz_offset => 60) # Partial dates my %d = str2date('2024-12-24', format => 'W3CDTF'); # (year => 2024, month => 12, day => 24) my %d = str2date('2024', format => 'W3CDTF'); # (year => 2024) # 12-hour clock my %d = str2date('December 24, 2024, 3:30 PM', format => 'generic'); # (..., hour => 15) # UTC designator my %d = str2date('24 Dec 2012 15:30:45 GMT', format => 'RFC2822'); # (..., tz_utc => 'GMT', tz_offset => 0) # UTC designator with offset my %d = str2date('December 24, 2024 at 3:30 pm UTC+05:30', format => 'generic'); # (..., tz_utc => 'UTC', tz_offset => 330) # Timezone abbreviation (unresolved) my %d = str2date('24 Dec 2012 15:30:45 IST', format => 'RFC2822'); # (..., tz_abbrev => 'IST') # no tz_offset # RFC 9557 annotation my %d = str2date('2024-12-24T15:30:45.500+01:00[Europe/Stockholm]', format => 'generic'); # (..., tz_offset => 60, tz_annotation => '[Europe/Stockholm]') time2str my $str = time2str($time); my $str = time2str($time, format => $format); my $str = time2str($time, format => $format, offset => $offset); my $str = time2str($time, nanosecond => $ns, precision => $prec); Formats a Unix timestamp into a date/time string. Parameters * $time (required) Unix timestamp (seconds since 1970-01-01T00:00:00Z). May be an integer or floating-point number. Supported range: 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z. * "format" (optional, default: 'RFC3339') The output format. See "SUPPORTED FORMATS". Not all formats support fractional seconds or timezone offsets. * "offset" (optional, default: 0) Timezone offset in minutes from UTC. Positive is east, negative is west. Valid range: -1439 to +1439 (-23:59 to +23:59). * "precision" (optional) Number of decimal places for fractional seconds (0-9). Fractional seconds are rounded to this precision, which may carry into the seconds field (e.g., rounding .999 at precision 0 yields the next whole second). When omitted and the timestamp has fractional seconds, precision is auto-detected: 3 if the fractional part is divisible by 0.001, 6 if divisible by 0.000001, or 9 otherwise. When specified as 0, fractional seconds are omitted after rounding. See "PRECISION HANDLING". * "nanosecond" (optional) Explicit nanosecond value (0-999999999) for fractional seconds. Overrides any fractional part of $time and bypasses rounding. Use this for exact control over fractional output or to preserve nanosecond precision that floating-point cannot represent. Can be combined with "precision" to control zero-padding. Returns A formatted date/time string. Errors Croaks if: * $time is outside the supported range * "format" is unknown * "offset" is out of range (-1439 to 1439) * "precision" is out of range (0-9) * "nanosecond" is out of range (0-999999999) Examples # RFC 3339 (default) my $str = time2str(1735052445); # '2024-12-24T15:30:45Z' # Timezone offset my $str = time2str(1735052445, offset => 60); # '2024-12-24T16:30:45+01:00' # Fractional seconds (auto-detected precision) my $str = time2str(1735052445.123456); # '2024-12-24T15:30:45.123456Z' # Explicit precision (rounded) my $str = time2str(1735052445.123456, precision => 3); # '2024-12-24T15:30:45.123Z' # Rounding carries into seconds my $str = time2str(1735052445.999999, precision => 3); # '2024-12-24T15:30:46.000Z' # Nanosecond override (no rounding) my $str = time2str(1735052445, nanosecond => 500_000_000, precision => 9); # '2024-12-24T15:30:45.500000000Z' # Zero-padding with nanosecond my $str = time2str(1735052445, nanosecond => 0, precision => 3); # '2024-12-24T15:30:45.000Z' # RFC 2822 my $str = time2str(1735052445, format => 'RFC2822', offset => 60); # 'Tue, 24 Dec 2024 16:30:45 +0100' # HTTP (always GMT) my $str = time2str(1735052445, format => 'RFC2616'); # 'Tue, 24 Dec 2024 15:30:45 GMT' # SQL with timezone my $str = time2str(1735052445.5, format => 'ISO9075', offset => 60); # '2024-12-24 16:30:45.500 +01:00' # Common Log Format my $str = time2str(1735052445, format => 'CLF', offset => 60); # '24/Dec/2024:16:30:45 +0100' PRECISION HANDLING The module handles fractional seconds differently when parsing versus formatting. Parsing (str2time) Fractional seconds beyond the specified precision are truncated, not rounded. This preserves the exact digits provided in the input up to the requested precision: str2time('2024-12-24T15:30:45.123456Z', precision => 3) # Returns: 1735052445.123 (digits beyond 3rd truncated) str2time('2024-12-24T15:30:45.999999Z', precision => 3) # Returns: 1735052445.999 (NOT .000 of next second) Note: "str2date" does not accept a precision parameter. It always preserves fractional seconds at full nanosecond resolution in the "nanosecond" component. Formatting (time2str) Fractional seconds are rounded to the specified precision. Rounding prevents floating-point artifacts from appearing in formatted output: time2str(1735052445.123456, precision => 3) # '2024-12-24T15:30:45.123Z' time2str(1735052445.999999, precision => 3) # '2024-12-24T15:30:46.000Z' (rounds up to next second) time2str(1735052445.999999, precision => 0) # '2024-12-24T15:30:46Z' (rounds up, fraction omitted) Bypassing Rounding The "nanosecond" parameter overrides the fractional part of $time and is not subject to rounding, giving exact control over the output: time2str(1735052445, nanosecond => 999_999_000, precision => 6) # '2024-12-24T15:30:45.999999Z' (exact, no rounding) time2str(1735052445, nanosecond => 0) # '2024-12-24T15:30:45Z' (no fractional part) FLOATING-POINT PRECISION Perl typically uses IEEE 754 double-precision (64-bit) floating-point, providing approximately 15-17 significant decimal digits shared between the integer and fractional parts of a number. Implications for Timestamps Whole seconds are always represented exactly within the supported date range (0001-01-01 to 9999-12-31). Fractional precision depends on the magnitude of the timestamp: * Millisecond precision ("precision => 3") is exact and stable across the entire supported date range. * Microsecond precision ("precision => 6") is reliable for timestamps within roughly ±140 years of the Unix epoch (1830-2110). Beyond this range, values may shift by ±1 microsecond due to floating-point spacing. * Nanosecond precision cannot be represented faithfully in a floating-point timestamp. Use the "nanosecond" parameter for exact sub-microsecond values. Default Precision When "time2str" formats a timestamp with fractional seconds and neither "precision" nor "nanosecond" is specified, it uses a system-dependent default determined at compile time: * 6 decimal places on standard 64-bit double-precision systems * 9 decimal places on platforms with extended floating-point (e.g., long double) This default prevents spurious trailing digits caused by floating-point representation. For explicit control, always specify "precision" or "nanosecond". SUPPORTED FORMATS The following format specifiers are recognized (case-insensitive). The default format is "RFC3339". ANSIC (alias: ctime) ANSI C asctime() / ctime() format. DDD MMM _D HH:MM:SS YYYY DDD MMM DD HH:MM:SS YYYY Where "_D" is a space-padded single-digit day. Parsing: Mon Dec 1 03:04:05 2024 Tue Dec 24 15:30:45 2024 Formatting: time2str(1735052445, format => 'ANSIC') # 'Tue Dec 24 15:30:45 2024' Limitations: Always UTC. Fractional seconds and timezone offsets are not supported; the "offset" parameter is ignored. ASN1GT ASN.1 GeneralizedTime as defined in ITU-T X.680. YYYYMMDDhh[mm[ss]][(.|,)fraction][Z|±hh[mm]] Parsing: Hours are required; minutes and seconds are optional. The fractional part may use a period or comma and applies to the least significant time component present: 2024122415Z # hour only 2024122415,5Z # decimal hour (30 minutes) 201212241530Z # hour and minute 201212241530,5Z # decimal minute (30 seconds) 20121224153045Z # full time 20121224153045.500Z # with fractional seconds 20121224153045,123456789Z # nanoseconds, comma separator 20121224153045+0100 # with numeric offset Timezone offset format: "±HHMM" or "±HH" Formatting: time2str(1735052445, format => 'ASN1GT') # '20241224153045Z' time2str(1735052445, format => 'ASN1GT', precision => 3) # '20241224153045.500Z' time2str(1735052445, format => 'ASN1GT', offset => 60) # '20241224163045+0100' Limitations: Formatting always outputs hours, minutes, and seconds. Decimal hours and decimal minutes are not produced. ASN1UT ASN.1 UTCTime as defined in ITU-T X.680. YYMMDDhhmm[ss](Z|±hhmm) Parsing: Two-digit year; seconds are optional. A timezone designator is required. 9412211010Z # without seconds 241224153045Z # with seconds 241224153045+0100 # with numeric offset Timezone offset format: "±HHMM" Formatting: time2str(1735052445, format => 'ASN1UT') # '241224153045Z' time2str(1735052445, format => 'ASN1UT', offset => 60) # '241224163045+0100' Limitations: Fractional seconds are not supported. CLF Common Log Format. DD/MMM/YYYY:HH:MM:SS[.fraction] ±HHMM Parsing: 24/Dec/2024:15:30:45 +0100 24/Dec/2024:15:30:45.500 +0100 24/Dec/2024:15:30:45.123456789 -0500 Timezone offset format: "±HHMM" Formatting: time2str(1735052445, format => 'CLF') # '24/Dec/2024:15:30:45 +0000' time2str(1735052445, format => 'CLF', offset => 60) # '24/Dec/2024:16:30:45 +0100' time2str(1735052445.5, format => 'CLF', precision => 3, offset => 60) # '24/Dec/2024:16:30:45.500 +0100' Generic A permissive parser that accepts a wide variety of real-world date/time representations, restricted to those that can be parsed deterministically. Parsing only; cannot be used with "time2str". See "GENERIC FORMAT PARSING" for the full grammar, rules, and examples. Git Default date format used by Git. DDD MMM D HH:MM:SS YYYY ±HHMM Parsing: Mon Dec 24 15:30:45 2012 +0100 Timezone offset format: "±HHMM" Formatting: time2str(1735052445, format => 'Git') # 'Tue Dec 24 15:30:45 2024 +0000' time2str(1735052445, format => 'Git', offset => 60) # 'Tue Dec 24 16:30:45 2024 +0100' Limitations: Fractional seconds are not supported. ISO9075 (alias: SQL) ISO 9075 Database Language SQL timestamp format. YYYY-MM-DD YYYY-MM-DD HH:MM:SS[.fraction] YYYY-MM-DD HH:MM:SS[.fraction] ±HH:MM Parsing: 2024-12-24 2024-12-24 15:30:45 2024-12-24 15:30:45.500 2024-12-24 15:30:45.123456789 2024-12-24 15:30:45 +01:00 2024-12-24 15:30:45.500 +01:00 Timezone offset format: "±HH:MM" Formatting: time2str(1735052445, format => 'ISO9075') # '2024-12-24 15:30:45 +00:00' time2str(1735052445, format => 'ISO9075', offset => 60) # '2024-12-24 16:30:45 +01:00' time2str(1735052445.5, format => 'ISO9075', precision => 3, offset => 60) # '2024-12-24 16:30:45.500 +01:00' Limitations: Formatting always includes a timezone offset. Date-only parsing is supported but date-only output is not. RFC2616 (aliases: RFC7231, HTTP) HTTP-date as defined in RFC 2616 / RFC 7231. Parses three sub-formats: DDD, DD MMM YYYY HH:MM:SS GMT # IMF-fixdate (preferred) DDDD, DD-MMM-YY HH:MM:SS GMT # RFC 850 (obsolete) DDD MMM _D HH:MM:SS YYYY # ANSI C asctime Parsing: Mon, 24 Dec 2012 15:30:45 GMT # IMF-fixdate Monday, 24-Dec-12 15:30:45 GMT # RFC 850 Mon Dec 24 15:30:45 2012 # asctime Formatting: Always produces IMF-fixdate in GMT: time2str(1735052445, format => 'RFC2616') # 'Tue, 24 Dec 2024 15:30:45 GMT' Limitations: Always GMT. The "offset" parameter is ignored. Fractional seconds are not supported. RFC2822 (aliases: RFC5322, IMF, EMAIL) Internet Message Format date as defined in RFC 2822 / RFC 5322. [DDD,] D MMM YYYY HH:MM[:SS] (±HHMM|UT|UTC|GMT|abbrev) Parsing: Day name and seconds are optional. Accepts numeric offsets, UTC designators ("UT", "UTC", "GMT"), and timezone abbreviations. Abbreviations are returned in "tz_abbrev" without resolution. Mon, 24 Dec 2012 15:30:45 +0100 # tz_offset => 60 Mon, 24 Dec 2012 15:30 +0100 24 Dec 2012 15:30:45 +0100 24 Dec 2012 15:30:45 GMT # tz_utc => 'GMT', tz_offset => 0 24 Dec 2012 15:30:45 CET # tz_abbrev => 'CET' Timezone offset format: "±HHMM" See "TIMEZONE ABBREVIATIONS". Formatting: Always produces a numeric offset: time2str(1735052445, format => 'RFC2822') # 'Tue, 24 Dec 2024 15:30:45 +0000' time2str(1735052445, format => 'RFC2822', offset => 60) # 'Tue, 24 Dec 2024 16:30:45 +0100' Limitations: Fractional seconds are not supported. RFC3339 Internet timestamp as defined in RFC 3339, a profile of ISO 8601. YYYY-MM-DD(T|t| )HH:MM:SS[.fraction](Z|z|±HH:MM) Parsing: The date/time separator may be "T", "t", or a space. The UTC designator may be "Z" or "z". 2024-12-24T15:30:45Z 2024-12-24t15:30:45z 2024-12-24 15:30:45Z 2024-12-24T15:30:45.500Z 2024-12-24T15:30:45.123456789Z 2024-12-24T15:30:45+01:00 2024-12-24T15:30:45-05:00 Timezone offset format: "±HH:MM" Formatting: Always produces uppercase "T" and "Z" (or "±HH:MM"): time2str(1735052445, format => 'RFC3339') # '2024-12-24T15:30:45Z' time2str(1735052445, format => 'RFC3339', offset => 60) # '2024-12-24T16:30:45+01:00' time2str(1735052445.5, format => 'RFC3339', precision => 3) # '2024-12-24T15:30:45.500Z' RFC4287 (alias: ATOM) Atom feed timestamp as defined in RFC 4287. Stricter than RFC 3339: requires uppercase "T" and "Z", no space separator, no lowercase designators. YYYY-MM-DDTHH:MM:SS[.fraction](Z|±HH:MM) Parsing: 2024-12-24T15:30:45Z 2024-12-24T15:30:45.500Z 2024-12-24T15:30:45.123456789Z 2024-12-24T15:30:45+01:00 Timezone offset format: "±HH:MM" Formatting: Identical to RFC3339. Ruby Date format popularized by Ruby on Rails and Twitter. DDD MMM DD HH:MM:SS ±HHMM YYYY Parsing: Mon Dec 24 15:30:45 +0100 2012 Timezone offset format: "±HHMM" Formatting: time2str(1735052445, format => 'Ruby') # 'Tue Dec 24 15:30:45 +0000 2024' time2str(1735052445, format => 'Ruby', offset => 60) # 'Tue Dec 24 16:30:45 +0100 2024' Limitations: Fractional seconds are not supported. Unix The date(1) command output format as defined by POSIX. DDD MMM _D HH:MM:SS (±HHMM|UTC|GMT|abbrev) YYYY DDD MMM DD HH:MM:SS (±HHMM|UTC|GMT|abbrev) YYYY DDD MMM _D HH:MM:SS YYYY (±HHMM|UTC|GMT|abbrev) DDD MMM DD HH:MM:SS YYYY (±HHMM|UTC|GMT|abbrev) Where "_D" is a space-padded single-digit day. Parsing: Accepts the timezone before or after the year. Accepts numeric offsets, UTC designators ("UTC", "GMT"), and timezone abbreviations. Abbreviations are returned in "tz_abbrev" without resolution. Mon Dec 24 15:30:45 2012 UTC Mon Dec 24 15:30:45 UTC 2012 Timezone offset format: "±HHMM" See "TIMEZONE ABBREVIATIONS". Formatting: Always produces the zone-before-year. Uses "UTC" for zero offset and a numeric offset otherwise. time2str(1735052445, format => 'Unix') # 'Tue Dec 24 15:30:45 UTC 2024' time2str(1735052445, format => 'Unix', offset => 60) # 'Tue Dec 24 16:30:45 +0100 2024' Limitations: Fractional seconds are not supported. W3CDTF (alias: W3C) W3C Date and Time Format, a profile of ISO 8601. YYYY YYYY-MM YYYY-MM-DD YYYY-MM-DDTHH:MM:SS[.fraction](Z|±HH:MM) Parsing: Supports partial dates. A timezone designator is required when a time component is present. 2024 # year only 2024-12 # year and month 2024-12-24 # date only 2024-12-24T15:30:45Z # full datetime 2024-12-24T15:30:45.500Z 2024-12-24T15:30:45.123456789Z 2024-12-24T15:30:45+01:00 Timezone offset format: "±HH:MM" Formatting: Identical to RFC3339. GENERIC FORMAT PARSING The "generic" format parser accepts a wide variety of real-world date/time representations, restricted to those that can be parsed deterministically. Parsing only; cannot be used with "time2str". A date is always required. Time and timezone are optional, but a timezone may only appear when a time is present. Date Three categories of date format are accepted. Numeric Dates (Y-M-D only) When all three components are numeric, they must appear in year-month-day order to avoid the ambiguity between American (M/D/Y) and European (D/M/Y) conventions. The separator must be a hyphen, slash, or period, and must be consistent within the date. 2024-12-24 2024/12/24 2024.12.24 These are rejected: 12-24-2024 # M-D-Y not accepted 24-12-2024 # D-M-Y not accepted 2024-12/24 # mixed separators Dates with Textual Months When the month is a name or Roman numeral it is unambiguous, so the day and year may appear in any order relative to the month. Month names may be abbreviated ("Jan", "Feb", ...) or written in full ("January", "February", ...). Roman numerals "I" through "XII" are accepted. Separators follow the same rules as numeric dates, or spaces may be used. Separator-based: 2024-Dec-24 24-Dec-2024 Dec-24-2024 2024/December/24 24.XII.2024 Space-separated: 24 December 2024 24th December 2024 December 24, 2024 December 24th, 2024 24. XII. 2024 Compact Dates (No Separators) Accepted only when the month is textual: 24DEC2024 24Dec2024 2024DEC24 2024Dec24 Day Names and Ordinal Suffixes An optional day name prefix (e.g., "Monday," or "Mon,") is accepted before the date but not validated against the actual date. Ordinal suffixes ("st", "nd", "rd", "th") are accepted after a numeric day but not validated. Monday, 24 December 2024 Mon, 24 Dec 2024 December 24th, 2024 Year A four-digit year is always required. Two-digit years are not accepted. Time of Day Optional. When present, it must be separated from the date by "T", a comma and space, the word "at" surrounded by spaces, or a plain space. 2024-12-24T15:30:45 2024-12-24 15:30:45 December 24, 2024, 15:30 Monday, 24th December 2024 at 3:30 pm Hours and Minutes Separated by a colon. Hours may be one or two digits; minutes are always two digits. 9:05 15:30 Seconds Optional, separated from minutes by a colon, always two digits. 15:30:45 Fractional Seconds An optional fractional part may follow the seconds, separated by a period or comma. Up to nine digits (nanosecond precision) are accepted. 15:30:45.5 15:30:45.500 15:30:45.123456789 15:30:45,500 12-Hour Clock An AM/PM indicator may follow the time with or without a space: 3 PM 3PM 3:30 PM 3:30:45 PM 3:30:45.500 PM 3:30 pm 3:30 P.M. 3:30 p.m. When present, the hour must be 1-12. Midnight is "12:00 AM", noon is "12:00 PM". Timezone Optional; may only appear when a time is present. UTC Designators "Z", "UTC", and "GMT" set "tz_utc" to the matched designator and "tz_offset" to 0, unless followed by a numeric offset (e.g., "UTC+05:30"), in which case "tz_offset" reflects that offset. Numeric Offsets ±1 ±01 ±0100 ±01:00 ±05:30 Combined UTC and Offset "UTC" or "GMT" followed immediately by a numeric offset. "tz_utc" is set to the designator; "tz_offset" reflects the numeric part: UTC+1 UTC+01:00 GMT+5:30 Timezone Abbreviations Abbreviations matching "[A-Z][A-Za-z][A-Z]{1,4}" are accepted. UTC designators are handled as above; all others (e.g., "EST", "CET", "IST") are returned in "tz_abbrev" without resolution. See "TIMEZONE ABBREVIATIONS". Timezone Annotations RFC 9557 (IXDTF) bracketed tags and Java "ZoneId" annotations are captured in "tz_annotation". Parenthesized comments are accepted but discarded. +01:00[Europe/Stockholm] +01:00[u-ca=hebrew] +0100[Europe/Stockholm] +0100 (CET) +0100 (Central European Time) Validation * Dates must be valid for the Gregorian calendar, including leap years * Hours: 0-23 (24-hour) or 1-12 (12-hour with AM/PM) * Minutes: 0-59 * Seconds: 0-60 (60 allows for leap seconds) Examples # ISO 8601 2024-12-24 2024-12-24T15:30 2024-12-24T15:30+01 2024-12-24T15:30:45,500+01 # RFC 3339 2024-12-24T15:30:45+01:00 2024-12-24T15:30:45.500+01:00 # RFC 9557 2024-12-24T15:30:45.500+01:00[Europe/Stockholm] # RFC 2822 Mon, 24 Dec 2024 15:30:45 +0100 24 Dec 2024 15:30 +0100 # RFC 2616 (HTTP) Mon, 24 Dec 2024 15:30:45 GMT # RFC 9051 (IMAP) 24-Dec-2024 15:30:45 +0100 # ISO 9075 (SQL) 2024-12-24 15:30:45 2024-12-24 15:30:45.500 +01:00 # ECMAScript Date.prototype.toString Mon Dec 24 2024 15:30:45 GMT+0100 (Central European Time) # Long-form textual Monday, 24 December 2024, 15:30 GMT+1 Monday, 24th December 2024 at 3:30 pm UTC+1 December 24th, 2024 at 3:30 PM # Short-form variations Dec/24/2024 03:30:45 PM 24. XII. 2024 12PM UTC+1 24DEC2024 12:30:45.500 24.Dec.2024 15:30:45 TIMEZONE ABBREVIATIONS The "Generic", "RFC2822", and "Unix" parsers accept timezone abbreviations. * UTC designators ("UTC", "GMT", "UT", "Z") Unambiguous. Set "tz_utc" to the matched designator and "tz_offset" to 0, unless followed by a numeric offset. * All other abbreviations Returned as-is in "tz_abbrev". "tz_offset" will not be present. This module intentionally does not resolve abbreviations like "EST", "CET", or "IST" to numeric offsets, as many are ambiguous (e.g., "IST" could mean India Standard Time UTC+5:30, Israel Standard Time UTC+2, or Irish Standard Time UTC+1). "str2time" requires a resolved offset and will croak if only an unresolved abbreviation is present. Use "str2date" to retrieve the components including "tz_abbrev", then resolve externally: my %d = str2date('24 Dec 2012 15:30:45 IST', format => 'RFC2822'); # (..., tz_abbrev => 'IST') # no tz_offset my %d = str2date('24 Dec 2012 15:30:45 GMT', format => 'RFC2822'); # (..., tz_utc => 'GMT', tz_offset => 0) SEE ALSO Time::Moment, DateTime, Time::Piece STANDARDS * ISO 8601:2004 - Data elements and interchange formats * RFC 3339 - Date and Time on the Internet: Timestamps * RFC 2822 / RFC 5322 - Internet Message Format * RFC 2616 / RFC 7231 - HTTP/1.1 * RFC 4287 - The Atom Syndication Format * RFC 9051 - Internet Message Access Protocol (IMAP) * RFC 9557 - Date and Time on the Internet: Timestamps with Additional Information * ISO 9075 - SQL Database Language * ITU-T X.680 (ISO/IEC 8824-1) - ASN.1 * W3C Date and Time Formats AUTHOR Christian Hansen COPYRIGHT AND LICENSE Copyright (C) 2026 by Christian Hansen This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.