PHP code example of lavendla / personal-identity-number

1. Go to this page and download the library: Download lavendla/personal-identity-number library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

lavendla / personal-identity-number example snippets


use DateTimeImmutable;
use Lavendla\PersonalIdentityNumber\Enums\Country;
use Lavendla\PersonalIdentityNumber\Enums\Format;
use Lavendla\PersonalIdentityNumber\ParseOptions;
use Lavendla\PersonalIdentityNumber\PersonalIdentityNumber;

$referenceDate = new DateTimeImmutable('2026-08-16');

$number = PersonalIdentityNumber::parse(
    '19031204-9802',
    Country::Sweden,
    new ParseOptions($referenceDate),
);

$number->canonical();              // '190312049802'
$number->birthDate()->format('Y-m-d'); // '1903-12-04'
$number->gender();                 // Gender::Female
$number->isPerson();                // true
$number->format(Format::Display);   // '19031204-9802'
$number->format(Format::Short);     // '031204+9802' — this bearer is over 100 at the reference date
$number->format(Format::Masked);    // '19031204****'

// Throws Lavendla\PersonalIdentityNumber\Exceptions\ParseException on failure,
// carrying a typed Enums\ParseFailure reason via getFailure().
$number = PersonalIdentityNumber::parse('19031204-9802', Country::Sweden, new ParseOptions($referenceDate));

// Returns null on failure, discarding the reason. For guard clauses that
// don't need to know why.
$numberOrNull = PersonalIdentityNumber::tryParse('not a number', Country::Sweden, new ParseOptions($referenceDate));
// null

// Never throws. Returns a ParseOutcome — the diagnostic and migration entry
// point, and the one every other entry point above is built from.
$outcome = PersonalIdentityNumber::explain('19031204-9802', Country::Sweden, new ParseOptions($referenceDate));
$outcome->succeeded(); // true
$outcome->number();    // the PersonalIdentityNumber above
$outcome->failure();   // null

// A bare boolean, for guard clauses and form validation.
PersonalIdentityNumber::validates('19031204-9802', Country::Sweden, new ParseOptions($referenceDate)); // true

// For search paths, where the country is what you're trying to find out —
// never for writes. Returns every interpretation, in no priority order, and
// never picks a winner.
$candidates = PersonalIdentityNumber::detect('19031204-9802', new ParseOptions($referenceDate));
// one candidate: twelve digits cannot be a Danish CPR number

$ambiguous = PersonalIdentityNumber::detect('2601012384', new ParseOptions($referenceDate));
// two candidates: valid as Swedish (born 2026-01-01) and as Danish (born
// 1901-01-26). See the Denmark section.

// Asserts the result is a person — throws if it resolves to an organization
// number instead.
$person = PersonalIdentityNumber::parseForPerson('19031204-9802', Country::Sweden, $referenceDate);

// Asserts the result is an organization number — throws if the value resolves
// to a personal or coordination number instead.
$organization = PersonalIdentityNumber::parseForOrganization('202100-5448', Country::Sweden, $referenceDate);
$organization->canonical();            // '162021005448' — the 16 prefix is part of the canonical form
$organization->format(Format::Display); // '202100-5448' — the form Sweden actually writes
$organization->birthDate();            // null
$organization->gender();               // null
$organization->isPerson();             // false

use Lavendla\PersonalIdentityNumber\Enums\ParseFailure;

$outcome = PersonalIdentityNumber::explain(
    '190312049802',
    Country::Sweden,
    ParseOptions::forCenturyCompleteInput(),
);
$outcome->succeeded(); // true — the century was already in the input

// But a ten-digit input under the same options fails loudly instead of guessing:
$tenDigitOutcome = PersonalIdentityNumber::explain(
    '031204-9802',
    Country::Sweden,
    ParseOptions::forCenturyCompleteInput(),
);
$tenDigitOutcome->failure(); // ParseFailure::CenturyRequired

final readonly class ParseOptions
{
    public function __construct(
        public ?DateTimeImmutable $referenceDate,
        public bool $allowCoordinationNumber = true,
        public bool $allowOrganizationNumber = true,
        public bool $allowUnknownBirthNumber = true,
    ) {}

    public static function forCenturyCompleteInput(
        bool $allowCoordinationNumber = true,
        bool $allowOrganizationNumber = true,
        bool $allowUnknownBirthNumber = true,
    ): self;
}

$options = new ParseOptions($referenceDate, allowCoordinationNumber: false);
PersonalIdentityNumber::explain('140168+2396', Country::Sweden, $options)->failure();
// ParseFailure::SchemeNotAllowed

$number->scheme(): Scheme
$number->country(): Country
$number->canonical(): string
$number->format(Format $format, ?DateTimeImmutable $referenceDate = null): string
$number->birthDate(): ?DateTimeImmutable
$number->gender(): ?Gender
$number->ageOn(DateTimeImmutable $referenceDate): ?int
$number->isPerson(): bool
$number->equals(PersonalIdentityNumber $other): bool

$number->format(Format $format, ?DateTimeImmutable $referenceDate = null): string

$number->format(Format::Short); // uses the reference date supplied at parse time

$noDateObject = PersonalIdentityNumber::parse(
    '190312049802',
    Country::Sweden,
    ParseOptions::forCenturyCompleteInput(),
);

$noDateObject->format(Format::Display); // fine — no reference date involved
$noDateObject->format(Format::Short);   // throws ParseException(ParseFailure::ReferenceDateRequired)

$candidates = PersonalIdentityNumber::detect('2601012384', $options);
// two candidates: one SE, one DK

// A 0000 birth number — the stillborn and unknown-person convention.
$unknownBearer = PersonalIdentityNumber::parse('20240115-0000', Country::Sweden, $options);
$unknownBearer->birthDate()->format('Y-m-d'); // '2024-01-15' — fully present
$unknownBearer->ageOn($referenceDate);        // 2
$unknownBearer->gender();                     // null

// A coordination number with an unknown birth month.
$unknownMonth = PersonalIdentityNumber::parse('191500722390', Country::Sweden, $options);
$unknownMonth->canonical();  // '191500722390' — complete, so matching is unaffected
$unknownMonth->birthDate();  // null
$unknownMonth->gender();     // Gender::Male — the birth number is intact

PersonalIdentityNumber::explain('001203049802', Country::Sweden, $options)->failure();
// ParseFailure::ImplausibleBirthDate — structurally valid, Luhn-valid, and a birth in the year 12

$outcome = PersonalIdentityNumber::explain('0104909989', Country::Sweden, $options);
$outcome->failure();           // ParseFailure::ChecksumMismatch
$outcome->recognizedCountry(); // Country::Denmark

$number = PersonalIdentityNumber::parse('010280-952L', Country::Finland, $options);
$number->canonical();                  // '010280-952L'
$number->birthDate()->format('Y-m-d'); // '1980-02-01'
$number->gender();                     // Gender::Female
$number->format(Format::Display);      // '010280-952L'