diff --git a/phonenumbers.go b/phonenumbers.go index 0996b3a..d264dbb 100644 --- a/phonenumbers.go +++ b/phonenumbers.go @@ -2661,8 +2661,14 @@ func maybeExtractCountryCode( fullValid := validNumberPattern.MatchString(fullNumber.String()) nationalValid := validNumberPattern.MatchString(potentialNationalNumber.String()) lengthValid := testNumberLength(fullNumber.String(), defaultRegionMetadata, UNKNOWN) + shouldStrip := (!fullValid && nationalValid) || lengthValid == TOO_LONG - if (!fullValid && nationalValid) || lengthValid == TOO_LONG { + // validate additional rules by country + if !shouldStrip && nationalValid { + shouldStrip = getAdditionalRulesByRegion(potentialNationalNumber.String(), defaultRegionMetadata.GetId()) + } + + if shouldStrip { nationalNumber.Write(potentialNationalNumber.Bytes()) if keepRawInput { val := PhoneNumber_FROM_NUMBER_WITHOUT_PLUS_SIGN @@ -2678,6 +2684,18 @@ func maybeExtractCountryCode( return 0, nil } +func getAdditionalRulesByRegion(potentialNationalNumber string, region string) bool { + // Indonesian mobile numbers / landline that already include the country code are 8-12 digits + var shouldStrip = false + if region == "ID" { + if len(potentialNationalNumber) >= 8 && len(potentialNationalNumber) <= 12 { + shouldStrip = true + } + } + + return shouldStrip +} + // Strips the IDD from the start of the number if present. Helper function // used by maybeStripInternationalPrefixAndNormalize. func parsePrefixAsIdd(iddPattern *regexp.Regexp, number *Builder) bool { diff --git a/phonenumbers_test.go b/phonenumbers_test.go index 53c3a62..9b13e49 100644 --- a/phonenumbers_test.go +++ b/phonenumbers_test.go @@ -1189,7 +1189,7 @@ func TestParsing(t *testing.T) { {"+22658125926", "", "+22658125926"}, {"+2203693200", "", "+2203693200"}, {"0877747666", "ID", "+62877747666"}, - {"62816640000", "ID", "+6262816640000"}, + {"62816640000", "ID", "+62816640000"}, {"2349090000001", "NG", "+2349090000001"}, {"6282240080000", "ID", "+6282240080000"}, } @@ -1729,6 +1729,143 @@ func TestGetSafeCarrierDisplayNameForNumber(t *testing.T) { } } +func TestIndonesiaMinLengthNumber(t *testing.T) { + // Mobile phone numbers typically have a total of 9 to 12 digits (excluding the country code, +62). + // Prepaid services usually range from 10 to 12 digits, while postpaid can be 9 to 11 digits. + + // Landline Phone Numbers + // Minimum length: 7 digits (in non-major cities/areas, excluding area code) + // Maximum length: 8 digits (in large cities, excluding area code) + // When including the area code (which varies in length), landline numbers typically total around 11 digits. + + // International Format + // When dialing internationally, the country code +62 is used, and the leading 0 (used for domestic long distance calls) is omitted. + // The total number length, including the country code, adheres to the international E.164 standard maximum of 15 digits. + + tests := []struct { + name string + num string + expected string + }{ + { + name: "should be valid indonesian landline pematang siantar longer.", + num: "0622425678", + expected: "+62622425678", + }, + { + name: "should be valid indonesian landline pematang siantar longer without zero.", + num: "622425678", + expected: "+62622425678", + }, + { + name: "should be valid indonesian landline pematang siantar longer format E14.", + num: "62622425678", + expected: "+62622425678", + }, + { + name: "should be valid indonesian landline pematang siantar.", + num: "062221234", + expected: "+6262221234", + }, + { + name: "should be valid indonesian landline pematang siantar without zero.", + num: "62221234", + expected: "+6262221234", + }, + { + name: "should be valid indonesian landline pematang siantar format E14.", + num: "6262221234", + expected: "+6262221234", + }, + { + name: "should be valid indonesian landline jakarta.", + num: "0213456789", + expected: "+62213456789", + }, + { + name: "should be valid indonesian landline jakarta without zero.", + num: "213456789", + expected: "+62213456789", + }, + { + name: "should be valid indonesian landline jakarta with format E14.", + num: "62213456789", + expected: "+62213456789", + }, + { + name: "should be valid indonesian number with 9 digits.", + num: "811258591", + expected: "+62811258591", + }, + { + name: "should be valid indonesian number with 10 digits.", + num: "8112585891", + expected: "+628112585891", + }, + { + name: "should be valid indonesian number with 11 digits.", + num: "81125858913", + expected: "+6281125858913", + }, + { + name: "should be valid indonesian number with 12 digits.", + num: "811258581235", + expected: "+62811258581235", + }, + { + name: "should be valid indonesian number with 9 digits, include zero.", + num: "0811258591", + expected: "+62811258591", + }, + { + name: "should be valid indonesian number with 10 digits, include zero.", + num: "08112585891", + expected: "+628112585891", + }, + { + name: "should be valid indonesian number with 11 digits, include zero.", + num: "081125858913", + expected: "+6281125858913", + }, + { + name: "should be valid indonesian number with 12 digits, include zero.", + num: "0811258581235", + expected: "+62811258581235", + }, + { + name: "should be valid indonesian number with 9 digits with format E14, include country code 62.", + num: "62811258591", + expected: "+62811258591", + }, + { + name: "should be valid indonesian number with 10 digits with format E14, include country code 62.", + num: "628112585891", + expected: "+628112585891", + }, + { + name: "should be valid indonesian number with 11 digits with format E14, include country code 62.", + num: "6281125858913", + expected: "+6281125858913", + }, + { + name: "should be valid indonesian number with 12 digits with format E14, include country code 62.", + num: "62811258581235", + expected: "+62811258581235", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + num, err := Parse(test.num, "ID") + if err != nil { + t.Errorf("Failed to parse number %s: %s", test.num, err) + } + result := Format(num, E164) + assert.Equal(t, test.expected, result, "Unexpected result for num: %s", test.name) + }) + } +} + func s(str string) *string { return &str }