/** * Takes two phone numbers and compares them for equality. * * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero for Italian numbers * and any extension present are the same. * Returns NSN_MATCH if either or both has no region specified, and the NSNs and extensions are * the same. * Returns SHORT_NSN_MATCH if either or both has no region specified, or the region specified is * the same, and one NSN could be a shorter version of the other number. This includes the case * where one has an extension specified, and the other does not. * Returns NO_MATCH otherwise. * For example, the numbers +1 345 657 1234 and 657 1234 are a SHORT_NSN_MATCH. * The numbers +1 345 657 1234 and 345 657 are a NO_MATCH. * * @param firstNumberIn first number to compare * @param secondNumberIn second number to compare * * @return NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH or EXACT_MATCH depending on the level of equality * of the two numbers, described in the method definition. */ public MatchType IsNumberMatch(PhoneNumber firstNumberIn, PhoneNumber secondNumberIn) { // Make copies of the phone number so that the numbers passed in are not edited. var firstNumber = new PhoneNumber.Builder(); firstNumber.MergeFrom(firstNumberIn); var secondNumber = new PhoneNumber.Builder(); secondNumber.MergeFrom(secondNumberIn); // First clear raw_input, country_code_source and preferred_domestic_carrier_code fields and any // empty-string extensions so that we can use the proto-buffer equality method. firstNumber.ClearRawInput(); firstNumber.ClearCountryCodeSource(); firstNumber.ClearPreferredDomesticCarrierCode(); secondNumber.ClearRawInput(); secondNumber.ClearCountryCodeSource(); secondNumber.ClearPreferredDomesticCarrierCode(); if (firstNumber.HasExtension && firstNumber.Extension.Length == 0) firstNumber.ClearExtension(); if (secondNumber.HasExtension && secondNumber.Extension.Length == 0) secondNumber.ClearExtension(); // Early exit if both had extensions and these are different. if (firstNumber.HasExtension && secondNumber.HasExtension && !firstNumber.Extension.Equals(secondNumber.Extension)) return MatchType.NO_MATCH; int firstNumberCountryCode = firstNumber.CountryCode; int secondNumberCountryCode = secondNumber.CountryCode; // Both had country_code specified. if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) { if (AreEqual(firstNumber, secondNumber)) return MatchType.EXACT_MATCH; else if (firstNumberCountryCode == secondNumberCountryCode && IsNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) { // A SHORT_NSN_MATCH occurs if there is a difference because of the presence or absence of // an 'Italian leading zero', the presence or absence of an extension, or one NSN being a // shorter variant of the other. return MatchType.SHORT_NSN_MATCH; } // This is not a match. return MatchType.NO_MATCH; } // Checks cases where one or both country_code fields were not specified. To make equality // checks easier, we first set the country_code fields to be equal. firstNumber.SetCountryCode(secondNumberCountryCode); // If all else was the same, then this is an NSN_MATCH. if (AreEqual(firstNumber, secondNumber)) return MatchType.NSN_MATCH; if (IsNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) return MatchType.SHORT_NSN_MATCH; return MatchType.NO_MATCH; }
/** * Gets the length of the national destination code (NDC) from the PhoneNumber object passed in, * so that clients could use it to split a national significant number into NDC and subscriber * number. The NDC of a phone number is normally the first group of digit(s) right after the * country calling code when the number is formatted in the international format, if there is a * subscriber number part that follows. An example of how this could be used: * * <pre> * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); * PhoneNumber number = phoneUtil.parse("18002530000", "US"); * String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number); * String nationalDestinationCode; * String subscriberNumber; * * int nationalDestinationCodeLength = phoneUtil.getLengthOfNationalDestinationCode(number); * if (nationalDestinationCodeLength > 0) { * nationalDestinationCode = nationalSignificantNumber.substring(0, * nationalDestinationCodeLength); * subscriberNumber = nationalSignificantNumber.substring(nationalDestinationCodeLength); * } else { * nationalDestinationCode = ""; * subscriberNumber = nationalSignificantNumber; * } * </pre> * * Refer to the unittests to see the difference between this function and * {@link #getLengthOfGeographicalAreaCode}. * * @param number the PhoneNumber object for which clients want to know the length of the NDC. * @return the length of NDC of the PhoneNumber object passed in. */ public int GetLengthOfNationalDestinationCode(PhoneNumber number) { PhoneNumber copiedProto; if (number.HasExtension) { // We don't want to alter the proto given to us, but we don't want to include the extension // when we format it, so we copy it and clear the extension here. var builder = new PhoneNumber.Builder(); builder.MergeFrom(number); builder.ClearExtension(); copiedProto = builder.Build(); } else { copiedProto = number; } var nationalSignificantNumber = Format(copiedProto, PhoneNumberFormat.INTERNATIONAL); var numberGroups = NON_DIGITS_PATTERN.Split(nationalSignificantNumber); // The pattern will start with "+COUNTRY_CODE " so the first group will always be the empty // string (before the + symbol) and the second group will be the country calling code. The third // group will be area code if it is not the last group. if (numberGroups.Length <= 3) return 0; if (GetRegionCodeForCountryCode(number.CountryCode) == "AR" && GetNumberType(number) == PhoneNumberType.MOBILE) // Argentinian mobile numbers, when formatted in the international format, are in the form of // +54 9 NDC XXXX.... As a result, we take the length of the third group (NDC) and add 1 for // the digit 9, which also forms part of the national significant number. // // TODO: Investigate the possibility of better modeling the metadata to make it // easier to obtain the NDC. return numberGroups[3].Length + 1; return numberGroups[2].Length; }