Skip to content

Release 0.0.3

Choose a tag to compare

@github-actions github-actions released this 20 Sep 01:03
· 18 commits to master since this release

[0.0.3] - 2026-09-19

Completes the parse / validate / format port (#7). With libphonenumberCompat = true the covered surface is byte-identical to libphonenumber 9.0.39 and passes upstream's own tests for it; the default mode does the more-correct thing. formatToE164() is unchanged for numbers that already parsed, so existing E.164 tokens are stable. The one behavioural change to review is the Durchwahl refusal under Changed.

Added

  • Formatting API (#14): format(number, PhoneNumberFormat) for NATIONAL / INTERNATIONAL / RFC3966 / E164, plus formatOutOfCountryCallingNumber, formatNationalNumberWithCarrierCode / …WithPreferredCarrierCode, formatByPattern, formatNumberForMobileDialing, formatInOriginalFormat, and formatOutOfCountryKeepingAlphaChars. New PhoneNumberFormat enum and public NumberFormat. Display-format templates embedded in the metadata.
  • Number type & validity (#15): getNumberType, isValidNumber, isValidNumberForRegion, getSupportedTypesForRegion, getSupportedTypesForNonGeoEntity, and the PhoneNumberType enum.
  • Possible-length checks (#16): isPossibleNumber / isPossibleNumberForType (+WithReason), truncateTooLongNumber, and the ValidationResult enum.
  • isNumberMatch (#17) in three overloads (number/number, number/string, string/string) with the MatchType enum.
  • Raw-input parsing (#18): parseAndKeepRawInput. PhoneNumber gains extension, italianLeadingZero, numberOfLeadingZeros, rawInput, countryCodeSource and preferredDomesticCarrierCode; new CountryCodeSource enum. None of these affect formatToE164().
  • Accessors & helpers (#19): getSupportedRegions / …CallingCodes / …GlobalNetworkCallingCodes, getRegionCodeForNumber / …ForCountryCode, getRegionCodesForCountryCode, getCountryCodeForRegion, getNddPrefixForRegion, getNationalSignificantNumber, getCountryMobileToken, isNANPACountry, isNumberGeographical, isAlphaNumber, canBeInternationallyDialled, isMobileNumberPortableRegion, getLengthOfGeographicalAreaCode / …NationalDestinationCode, getExampleNumber / …ForType / …ForNonGeoEntity, getInvalidExampleNumber, convertAlphaCharactersInNumber, normalizeDiallableCharsOnly.
  • parse input handling now matches upstream: alphabetic vanity numbers are keypad-converted (#9), extensions are split off and returned on PhoneNumber.extension (#5), and RFC 3966 tel: URIs with ;phone-context= are resolved (#8). ErrorType gains TOO_SHORT_AFTER_IDD, TOO_SHORT_NSN and TOO_LONG (#12).
  • PhoneNumber.extension is normalized to ASCII by the same rule as the national number: every Unicode Nd decimal digit (all 77 blocks in the default mode, BMP-only under libphonenumberCompat) is folded to ASCII, so the extension is byte-stable across scripts — a deliberate divergence from upstream, which keeps the raw typed characters. (Previously non-ASCII extension digits were not recognised and folded into the national number.) An absent or empty extension is null, never "" — a captured extension always has at least one digit.
  • ErrorType.AMBIGUOUS_TRAILING_GROUP (#6) so the default-mode Durchwahl refusal is machine-distinguishable from an ordinary NOT_A_NUMBER.

Changed

  • Ambiguous direct-dial (Durchwahl) numbers are refused in the default mode rather than silently folded (#6). When an input carries a hyphen/space-separated trailing group and the number is valid both with and without it (as in +49 30 12345678-12, +43 1 58058-0), parse throws ErrorType.AMBIGUOUS_TRAILING_GROUP; when only the base is valid the group becomes the extension. Fixed-length plans (US, GB, …) are unaffected. Pass libphonenumberCompat = true to fold like upstream.
  • Alphabetic vanity conversion is new (#9): 0.0.2 dropped letters, 0.0.3 keypad-converts them (matching upstream — 1-800-FLOWERS → 1-800-3569377). A side effect worth knowing when calling parse directly: any run of three or more letters is folded into digits, so incidental words in the input become part of the number. Refuse or strip letters upstream of parse if that is a risk for your inputs.
  • Country-code extraction rewritten to upstream's algorithm, adding TOO_SHORT_AFTER_IDD and the leading-+-then-IDD handling (#10); national-prefix stripping keeps the stripped form only when it stays a possible length (#11).
  • PhoneNumber is read-only from the public API: its constructor and generated copy() are internal (@ConsistentCopyVisibility); instances come only from parsing.

Verified

  • Upstream parity in compat mode against libphonenumber Java 9.0.39 across dedicated harnesses for parse→E.164, formatting (all forms, out-of-country, carrier, by-pattern, mobile-dialing, original-format, keeping-alpha), number type & validity, possible-length, isNumberMatch, and the accessors.
  • formatToE164() output unchanged versus 0.0.2 for every conformance-corpus example.
  • Cross-target byte-stability (parse and format) on JVM, JS, wasmJs, macOS (native), and iOS simulator.