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;
}
$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