Date-Cmp

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

# NAME

Date::Cmp - Compare two dates with approximate parsing support

# VERSION

Version 0.06

# SYNOPSIS

    use Date::Cmp qw(datecmp);

    my $cmp = datecmp('1914', '1918');            # -1 (1914 is earlier)
    my $cmp = datecmp('Abt. 1850', '1855');       # -1
    my $cmp = datecmp('BET 1830 AND 1832', '1831'); # 0 (within range)

    # Optional complaint callback for ambiguous range edge-cases:
    $cmp = datecmp('1996-2000', '1996',
        sub { warn "ambiguous: @_" });

# DESCRIPTION

`Date::Cmp` provides a single exported function, `datecmp`, which compares
two date strings or date-like objects, returning a numeric result like Perl's
`<=>` operator.

The comparison handles approximate dates (`Abt. 1902`, `BET 1830 AND 1832`,
`Oct/Nov/Dec 1950`), partial dates (year-only), and the common genealogy
qualifiers `BEF` and `AFT`.  Exact parsing delegates to
[DateTime::Format::Genealogy](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AGenealogy); a cascade of fast-path heuristics handles
the most common year-only comparisons without invoking the heavier parser.

# FUNCTIONS

## datecmp

### Purpose

Compare two genealogy-style date strings (or date-like objects) and return
a value equivalent to Perl's spaceship operator (`<=>`): `-1` if the
left operand is earlier, `0` if equivalent, or `1` if later.

### Arguments

- `$left` (required)

    The left-hand date.  Accepted types:

    - A string in any format listed under ["SUPPORTED FORMATS"](#supported-formats).
    - A blessed object with a `date()` method returning a date string.
    - A hash reference with a `date` key whose value is a date string.

- `$right` (required)

    The right-hand date.  Accepts the same types as `$left`.

- `$complain` (optional)

    A CODE reference invoked with a diagnostic string for ambiguous conditions:
    equal range endpoints or an inverted range.  `undef` and other falsy values
    are silently ignored (the guard is never triggered).  A truthy non-CODE
    value causes an immediate `croak`.

### Returns

- `-1` — `$left` is earlier than `$right`
- `0`  — the two dates are considered equivalent
- `1`  — `$left` is later than `$right`

When either argument is `undef` (or resolves to `undef` after unwrapping),
the function prints a diagnostic to STDERR and returns `0` rather than dying.
On a fatal parse failure it dies; the exception string begins with
`"Date parse failure: "`.

### Side Effects

May print coloured diagnostics to STDERR when dates cannot be parsed, when a
range is inverted, or when an argument is undefined.  The `$complain`
callback is invoked (instead of STDERR output) for selected ambiguous
conditions.

### EXAMPLE

    use Date::Cmp qw(datecmp);

    # Plain years
    datecmp('1900', '1950');              # -1

    # Approximate prefixes are stripped
    datecmp('Abt. 1850', '1850');        # 0
    datecmp('ca. 1799',  '1800');        # -1

    # Year ranges — any year within the range is "equal"
    datecmp('1 Jan 1831', '1830-1832');  # 0
    datecmp('BET 1830 AND 1832', '1829'); # 1  (range is later)

    # Blessed object with date() method
    package MyDate;
    sub new  { bless { d => $_[1] }, $_[0] }
    sub date { $_[0]->{d} }
    package main;
    datecmp(MyDate->new('1900'), '1950'); # -1

    # Hash ref with 'date' key
    datecmp({ date => '1900' }, '1950'); # -1

    # Sort a list of dates
    my @sorted = sort { datecmp($a, $b) } qw(1832 Abt. 1800 1756 BET 1815 AND 1820);

### API SPECIFICATION

#### Input

    $left    : Str | Object(date) | HashRef(date => Str)   # required
    $right   : Str | Object(date) | HashRef(date => Str)   # required
    $complain: CodeRef | undef | false                      # optional

Valid string formats (see ["SUPPORTED FORMATS"](#supported-formats)):

    exact    => qr/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2})?$/



( run in 1.514 second using v1.01-cache-2.11-cpan-9789f410c06 )