NAME

Time::Str::Regexp - Precompiled regular expressions for date/time formats

SYNOPSIS

use Time::Str::Regexp qw( $RFC3339_Rx $RFC2822_Rx $DateTime_Rx );

if ($string =~ $RFC3339_Rx) {
  my %date = %+;
  ...
}

DESCRIPTION

This module provides precompiled regular expressions for parsing date/time strings in various standard formats. Each regex uses named captures to extract date and time components.

All regexes are anchored (\A ... \z). They perform structural matching only; semantic validation (e.g., day-of-month range, leap years) is not performed by the regex.

NAMED CAPTURES

Successful matches populate %+ with the following keys:

year

Two or four-digit year. Two-digit years appear in ASN1UT, RFC5280, and RFC 850 within RFC2616. Use resolve_century from Time::Str::Calendar to expand to four digits.

month

Month (1-2 digits or name, depending on format). May be a Roman numeral (I-XII) in DateTime. Use parse_month from Time::Str::Token to convert to an integer.

day

Day of month (1-2 digits). May include an ordinal suffix (e.g., 24th) in DateTime; use parse_day from Time::Str::Token to convert.

hour

Hour (1-2 digits). Single-digit hours only appear in DateTime when followed by a meridiem or minutes.

minute

Minute (2 digits).

second

Second (2 digits).

fraction

Fractional digits (1-9) of the least significant time component present. No leading separator (dot or comma).

Most formats capture fractional seconds only: RFC3339, RFC9557, RFC4287, W3CDTF, ISO9075, CLF, UnixStamp, DateTime, ECMAScript.

ISO8601 and ASN1GT may capture fractional hours, minutes, or seconds depending on which is the least significant component present.

day_name

Day name when present (e.g., Mon, Monday). Use parse_day_name from Time::Str::Token to convert to an integer (1=Monday .. 7=Sunday).

meridiem

AM/PM indicator (DateTime only). Accepts AM, PM, A.M., and P.M. (case-insensitive). Use parse_meridiem from Time::Str::Token to convert to an hour offset.

tz_utc

UTC designator: Z, z, UT, UTC, or GMT. UT is only accepted in RFC2822 and RFC2822FWS.

tz_offset

Numeric timezone offset. Format varies: ±HHMM, ±HH:MM, ±HH, ±H:MM, or ±H depending on the regex matched. Single-digit hour forms (±H, ±H:MM) are only accepted in DateTime when preceded by a UTC designator (e.g., UTC+5, GMT+5:30). Use parse_tz_offset from Time::Str::Token to convert to minutes.

Both tz_utc and tz_offset may be present in the same match (e.g., GMT+0530 in DateTime and ECMAScript).

tz_abbrev

Timezone abbreviation matching [A-Z][A-Za-z][A-Z]{1,4} (e.g., EST, CET, AEST).

tz_annotation

RFC 9557 annotation tags (RFC9557 and DateTime). May contain multiple tags (e.g., [America/New_York][u-ca=gregory]).

EXPORTED VARIABLES

All variables are exportable on request. Nothing is exported by default.

Profiles of ISO 8601

$ISO8601_Rx - ISO 8601 (basic and extended format)
$RFC4287_Rx - Atom feed timestamp (RFC 4287)
$W3CDTF_Rx - W3C Date and Time Format
$RFC5545_Rx - iCalendar (RFC 5545)

Based on ISO 8601

$RFC3339_Rx - Internet timestamp (RFC 3339)
$RFC9557_Rx - Timestamps with annotations (RFC 9557)
$ISO9075_Rx - SQL timestamp (ISO 9075)
$ASN1GT_Rx - ASN.1 GeneralizedTime
$ASN1UT_Rx - ASN.1 UTCTime
$RFC5280_Rx - X.509 certificate time (RFC 5280)

RFC / IMF / HTTP / IMAP

$RFC2822_Rx - Internet Message Format (RFC 2822, canonical)
$RFC2822FWS_Rx - RFC 2822 with folding white space and nested comments
$RFC2616_Rx - HTTP-date (RFC 2616 / RFC 7231)
$RFC3501_Rx - IMAP date-time (RFC 3501)

Unix / C Library

$ANSIC_Rx - ANSI C ctime()/asctime()
$UnixDate_Rx - Unix date(1) output
$UnixStamp_Rx - Unix date based, with optional fractional seconds and timezone
$GitDate_Rx - Git default date format
$RubyDate_Rx - Ruby/Rails date format

Other

$ECMAScript_Rx - ECMAScript Date.prototype.toString
$CLF_Rx - Common Log Format
$DateTime_Rx - Permissive multi-format parser

FUNCTIONS

mapping

my %map = Time::Str::Regexp->mapping;
my $map = Time::Str::Regexp->mapping;  # hashref in scalar context

Returns the format name to regex mapping. Keys are lowercase format names; values are precompiled regexes.

EXAMPLE

Using Time::Str::Regexp, Time::Str::Token, and Time::Str::Calendar together to build a custom parser:

use Time::Str::Regexp   qw( $DateTime_Rx );
use Time::Str::Token    qw( parse_day parse_month parse_day_name
                            parse_meridiem parse_tz_offset );
use Time::Str::Calendar qw( valid_ymd ymd_to_dow );

my $string = 'Monday, December 24th, 2012 at 3:30:45 PM UTC+1';

if ($string =~ $DateTime_Rx) {
  my %m = %+;

  my $dow       = parse_day_name($m{day_name});    # 1 (Monday)
  $m{month}     = parse_month($m{month});          # 12
  $m{day}       = parse_day($m{day});              # 24
  $m{tz_offset} = parse_tz_offset($m{tz_offset});  # 60

  valid_ymd(@m{qw(year month day)})
    or die "invalid date";

  ($dow == ymd_to_dow(@m{qw(year month day)}))
    or die "day name does not match date";

  my $hour_offset = parse_meridiem($m{meridiem});  # 12
  $m{hour} = ($m{hour} % 12) + $hour_offset;       # 15

  printf "%04d-%02d-%02dT%02d:%02d:%02d (%+3.2fH)\n",
    @m{qw(year month day hour minute second)}, $m{tz_offset} / 60;
    # 2012-12-24T15:30:45 (+1.00H)
}

SEE ALSO

Time::Str, Time::Str::Token, Time::Str::Calendar

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.