The TelephoneNumber class was designed to use the java.text.MessageFormat class to format a US phone number with the proper characters and spacing. The class excepts numbers any many different ways and parses them into it's internal data so that it can display the phone number in the standard way, i.e. (800) 555-1212. It can even accept an alpha number like "877 HOLY-COW" and with the right options format it as alpha or numbers.
The TelephoneNumber class represents a US telephone number.
This class contains many constructors for various uses. It then stores the telephone number internally in seperate codes (area code, exchange, etc.). This encourages use of the format method to output the telephone number in any style the programmer wishes.
[needs i18n work]
Example usage:
long number = 8005551212L;
TelephoneNumber phone = new TelephoneNumber(number);
StringBuffer msg = new StringBuffer("Call me at ");
msg.append(phone.format());
// msg is now "Call me at (800) 555-1212"
US Format:
The general US format is a 3 digit area code, a 3 digit exchange, a 4 digit station. Typically written (800) 555-1212. Area codes are concidered optional unless you live in a '10 digit' calling area as many people now do. In which case you may want to set the isTenDigitArea flag which removes the parenthesis from the String output ie Denver area code requires 10 digit dailing 303 555-1212.
International Format:
International phone numbers are often written in this format:
+CC-(N)AAA-EEE-SSSS.
This expresses the numbers used for both international and national long-distance calls. In the example, +CC indicates the country code, while (N) indicates the NDD. When dialing from outside the country, the NDD would not be used after dialing the country code; when dialing from within that country, the NDD would be used, but the country code would not. Where AAA indicates the area code, EEE indicates the exchange, and SSSS indicates the station.
Country Code:
The country code is the national prefix to be used when dialing TO that particular country FROM another country.
NDD Prefix: (National Direct Dialing)
The NDD prefix is the access code used to make a call WITHIN that country from one city to another (when calling another city in the same vicinity, this may not be necessary). The NDD is followed by the city/area code for the place you are calling.
IDD Prefix: (International Direct Dialing)
The IDD prefix is the international prefix needed to dial a call FROM a country TO another country. This is followed by the country code for the country you are calling. The IDD is not part of the telephone number - but is a property of the locale, or the 'dailing device'.
Outside Line Prefix:
The Outside line prefix is use inside some private branch exchange (PBX) to connect with the outer exchange/trunk. It is typically 9 in the average US company. This is not part of the telephone number - but once again the property of the locale, or the 'dailing device'.
/*
* Copyright (c) 2003 David A. Koontz
* Licensed under the Open Software License version 2.0
*
* Grant of Copyright License. Licensor hereby grants You a world-wide,
* royalty-free, non-exclusive, perpetual, sublicenseable license to
* do the following:
* a) to reproduce the Original Work in copies;
* b) to prepare derivative works ("Derivative Works") based upon
* the Original Work;
* c) to distribute copies of the Original Work and Derivative Works
* to the public, with the proviso that copies of Original Work or
* Derivative Works that You distribute shall be licensed under the
* Open Software License;
* d) to perform the Original Work publicly; and
* e) to display the Original Work publicly.
*/
//package com..util;
import java.text.MessageFormat;
/**
* The
TelephoneNumber
class represents a US telephone number.
*
* This class contains many constructors for various uses. It then stores the
* telephone number internally in seperate codes (area code, exchange, etc.).
* This encourages use of the
format
method to output the
* telephone number in any style the programmer wishes.
*
* [needs i18n work]
*
* Example usage:
*
* long number = 8005551212L;
* TelephoneNumber phone = new TelephoneNumber(number);
* StringBuffer msg = new StringBuffer("Call me at ");
* msg.append(phone.format());
* // msg is now "Call me at (800) 555-1212"
*
*
* US Format:
* The general US format is a 3 digit area code, a 3 digit exchange, a 4 digit
* station. Typically written (800) 555-1212. Area codes are concidered
* optional unless you live in a '10 digit' calling area as many people now do.
* In which case you may want to set the
isTenDigitArea
flag which
* removes the parenthesis from the String output ie Denver area code
* requires 10 digit dailing 303 555-1212.
*
* International Format:
* International phone numbers are often written in this format:
* +CC-(N)AAA-EEE-SSSS.
* This expresses the numbers used for both international and
* national long-distance calls. In the example, +CC indicates
* the country code, while (N) indicates the NDD. When dialing
* from outside the country, the NDD would not be used after dialing
* the country code; when dialing from within that country, the NDD
* would be used, but the country code would not. Where AAA indicates
* the area code, EEE indicates the exchange, and SSSS indicates the
* station.
*
*
*
* Country Code:
* The country code is the national prefix to be used when dialing TO
* that particular country FROM another country.
*
*
* NDD Prefix: (National Direct Dialing)
* The NDD prefix is the access code used to make a call WITHIN
* that country from one city to another (when calling another city in
* the same vicinity, this may not be necessary).
* The NDD is followed by the city/area code for the place you are
* calling.
*
*
* IDD Prefix: (International Direct Dialing)
* The IDD prefix is the international prefix needed to dial a call
* FROM a country TO another country. This is
* followed by the country code for the country you are calling.
* The IDD is not part of the telephone number - but is a property of
* the locale, or the 'dailing device'.
*
* Outside Line Prefix:
* The Outside line prefix is use inside some private branch exchange (PBX)
* to connect with the outer exchange/trunk. It is typically 9 in the
* average US company. This is not part of the telephone number - but
* once again the property of the locale, or the 'dailing device'.
*
*
*
* @author David A. Koontz mailto:dakoontz@yahoo.com">[dakoontz@yahoo.com]
* @version 1.0, 7/20/2003
* @see MessageFormat
* @see http://www.opensource.org/licenses/osl-2.0.php">Open Software License
version 2.0
*
*/
public class TelephoneNumber {
// International direct dial code is not part of a telephone
// number - it would be info in the locale that the dialer is in.
/** National direct dial code */
protected String ndd; // NDD of US is 1; UK is 0
/** Country code */
protected String countryCode; // Country code of US is 1; UK is 44
/** Area code */
protected String areaCode;
/** Exchange */
protected String exchange;
/** Station */
protected String station;
/** Extension */
protected String extension;
/** Is phone number part of a ten digit dialing area. */
protected boolean isTenDigitArea = false;
/** Alphanumeric phone number */
protected String alphaNumber; // used when we store "(800) GOT MILK"
/** Is phone number an alphanumberic */
protected boolean isAlphaNumber = false;
/** The default format pattern - US centric */
protected String defaultPatternUS = "({2}) {3}-{4}";
/** The default format pattern */
protected String defaultPattern = defaultPatternUS;
/**
* Basic constructor.
*/
public TelephoneNumber() {
this(null, null, null, "555", "1212", null);
}
/**
* General constructor.
* Create +1-(1)(800) 555-1212 ext: 34
*
* @param countryCode the country code (US is 1; UK is 44)
* @param ndd the national direct dial code (US is 1; UK is 0)
* @param areaCode the area code (or city code)
* @param exchange the exchange
* @param station the station
* @param extension the extension (inside the PBX)
*/
public TelephoneNumber(String countryCode, String ndd, String areaCode, String exchange, String station, String extension) {
if ( exchange == null )
throw new IllegalArgumentException("null arg forms not allowed for 'exchange'");
if ( station == null )
throw new IllegalArgumentException("null arg forms not allowed for 'station'");
this.countryCode = countryCode;
this.ndd = ndd;
this.areaCode = areaCode;
this.exchange = exchange;
this.station = station;
this.extension = extension;
}
/**
* Create (800) 555-1212 ext: 34
*/
public TelephoneNumber(String areaCode, String exchange, String station, String extension) {
this(null, null, areaCode, exchange, station, extension);
}
/**
* Create 555-1212 ext: 34
*/
public TelephoneNumber( String exchange, String station, String extension) {
this(null, null, null, exchange, station, extension);
}
/**
* Create 555-1212
*/
public TelephoneNumber( String exchange, String station) {
this(null, null, null, exchange, station, null);
}
/**
* Create 888 HOLY COW by using alphanumeric digits
*/
public TelephoneNumber( boolean isAlphaNumeric, String alphaNumber) {
this();
this.isAlphaNumber = isAlphaNumeric;
if ( isAlphaNumber == true ) {
this.alphaNumber = alphaNumber;
// parse it
String[] nums = parse(convertFromAlpha(alphaNumber));
// ignore country code & NDD
this.areaCode = nums[1];
this.exchange = nums[2];
this.station = nums[3];
this.extension= nums[4];
} else {
// parse this also - assuming no alpha char.
String[] nums = parse(alphaNumber);
// ignore country code & NDD
this.areaCode = nums[1];
this.exchange = nums[2];
this.station = nums[3];
this.extension= nums[4];
}
}
/**
* Create (888) 555-1212 by parsing string
*/
public TelephoneNumber( String str) {
this();
// parse the string into numbers array
String[] nums = parse(str);
// ignore country code & NDD
this.areaCode = nums[1];
this.exchange = nums[2];
this.station = nums[3];
this.extension= nums[4];
}
/**
* Create (479) 555-1212 by parsing a long integer
*/
public TelephoneNumber(long number) {
this();
String[] nums = parse(number);
// convert from longs to strings
this.areaCode = nums[1];
this.exchange = nums[2];
this.station = nums[3];
}
/** Create 555-1212 via long integers
*/
public TelephoneNumber( long exchange, long station) {
this();
// convert from longs to strings
if (exchange > 0) {
this.exchange = String.valueOf(exchange);
}
if (station > 0) {
this.station = String.valueOf(station);
}
}
/**
* Create (479) 555-1212 via long integers
*/
public TelephoneNumber(long areaCode, long exchange, long station) {
this();
// convert from longs to strings
if (areaCode > 0) {
this.areaCode = String.valueOf(areaCode);
}
if (exchange > 0) {
this.exchange = String.valueOf(exchange);
}
if (station > 0) {
this.station = String.valueOf(station);
}
}
/**
* Parse a string like "(888) 555-1212 x 68" into a phone number.
* Requires area code.
* Does not allow country codes etc.
* US centric.
*/
protected String[] parse( String str) {
String[] numbers = new String[5];
StringBuffer ndd = new StringBuffer();
StringBuffer area = new StringBuffer();
StringBuffer exch = new StringBuffer();
StringBuffer stat = new StringBuffer();
StringBuffer ext = new StringBuffer();
char ch = ' ';
int areaCount = 0;
int exchCount = 0;
int statCount = 0;
if ( str != null && str.length()>0 ) {
// for each char in string
for (int i = 0; i < str.length(); i++) {
ch = str.charAt(i);
// only look at digits
if ( Character.isDigit(ch) ) {
// this is only finding this pattern 123 123 1234 99...
if ( areaCount < 3 ) {
area.append(ch);
areaCount++;
} else if ( exchCount < 3 ) {
exch.append(ch);
exchCount++;
} else if ( statCount < 4 ) {
stat.append(ch);
statCount++;
} else {
ext.append(ch);
}
// doesnot work for "571 3345 ext 897"
//@todo - get better parser
}
}
}
numbers[0] = ndd.toString();
numbers[1] = area.toString();
numbers[2] = exch.toString();
numbers[3] = stat.toString();
numbers[4] = ext.toString();
return numbers;
}
/**
* Parse a long integer like 4795718080 into phone number.
* Does not allow country codes or extensions.
* US centric.
*/
protected String[] parse(long number) {
String[] nums = new String[5];
long area = 0;
long exch = 0;
long stat = 0;
// parse the long from right to left
// assume US style phone number without extension
// example: 8005551212 or 2368000
if (number > 0) {
if (number > 9999) {
exch = number / 10000;
stat = number - (exch * 10000);
if ( exch > 999 ) {
area = exch / 1000;
exch = exch - (area * 1000);
}
}
}
// convert from longs to strings
if (area > 0) {
nums[1] = String.valueOf(area);
}
if (exch > 0) {
nums[2] = String.valueOf(exch);
}
if (stat > 0) {
nums[3] = String.valueOf(stat);
}
return nums;
}
/** Convert alphanumeric phone number to numeric. */
protected static String convertFromAlpha(String alpha) {
// If you don't want US style key pad - change it.
return convertFromAlphaUS(alpha);
}
/** Convert alphanumeric phone number to numeric - US centric */
protected static String convertFromAlphaUS(String alpha) {
// convert a US alphanumeric number into numberic
// example: 800 GOT MILK -> 800 468-6455
// where the Alpha to Numberic Key Pad
//
// 1 2 3
// ABC DEF
//
// 4 5 6
// GHI JKL MNO
//
// 7 8 9
// PQRS TUV WXYZ
//
// * 0 #
//
// prep the alpha string
StringBuffer sb = new StringBuffer(alpha.toUpperCase().trim());
// for each char in the string
for (int i = 0; i < sb.length(); i++) {
char ch = sb.charAt(i);
if ( Character.isDigit(ch) ) {
; // ignore it
} else if ( ch == '(' || ch == ')' ) {
; // ignore them
} else if ( ch == 'A' || ch == 'B' || ch == 'C' ) {
sb.deleteCharAt(i);
sb.insert(i, '2');
} else if ( ch == 'D' || ch == 'E' || ch == 'F' ) {
sb.deleteCharAt(i);
sb.insert(i, '3');
} else if ( ch == 'G' || ch == 'H' || ch == 'I' ) {
sb.deleteCharAt(i);
sb.insert(i, '4');
} else if ( ch == 'J' || ch == 'K' || ch == 'L' ) {
sb.deleteCharAt(i);
sb.insert(i, '5');
} else if ( ch == 'M' || ch == 'N' || ch == 'O' ) {
sb.deleteCharAt(i);
sb.insert(i, '6');
} else if ( ch == 'P' || ch == 'Q' || ch == 'R' || ch == 'S') {
sb.deleteCharAt(i);
sb.insert(i, '7');
} else if ( ch == 'T' || ch == 'U' || ch == 'V' ) {
sb.deleteCharAt(i);
sb.insert(i, '8');
} else if ( ch == 'W' || ch == 'X' || ch == 'Y' || ch == 'Z' ) {
sb.deleteCharAt(i);
sb.insert(i, '9');
} else {
; // ignore
}
}
return sb.toString();
}
/**
* Format the telephone number with the supplied
MessageFormat
pattern.
* The pattern has 7
messageFormatElement
arguments (0 - 6).
*
* argument 0 - ndd
* argument 1 - countryCode
* argument 2 - areaCode
* argument 3 - exchange
* argument 4 - station
* argument 5 - extension
* argument 6 - alphanumeric
*
* Examples:
* "({2}) {3}-{4} ext {5}" gives "(800) 555-1212 ext 99"
* "{2}.{3}.{4}" gives "800.555.1212"
* "{6} [{2} {3}-{4}]" gives "888 HOLY COW [888 465-9269]"
*
* @param pattern the format pattern to be used
* @see MessageFormat
*
*/
public String format(String pattern) {
// create objects array from telephone codes
Object[] objects = {ndd, countryCode, areaCode, exchange, station, extension, alphaNumber};
// create a MessageFormat with pattern
MessageFormat mf = new MessageFormat(pattern);
return mf.format(objects);
}
/**
* Format the telephone number with the
defaultPattern
MessageFormat
.
* US centric.
*/
public String format() {
// create objects array from telephone codes
Object[] objects = {ndd, countryCode, areaCode, exchange, station, extension, alphaNumber};
// create a MessageFormat with default pattern
MessageFormat mf = new MessageFormat(defaultPattern);
return mf.format(objects);
}
/** Human readable output
*/
public String toString() {
return toStringUS();
}
/** US centric human readable output
*/
public String toStringUS() {
// use US convention: "(800) 555-1212 ext: 20"
StringBuffer sb = new StringBuffer(20);
if ( this.isAlphaNumber ) {
// just spit back the string
sb.append(this.alphaNumber);
sb.append(" [").append(areaCode).append(" ").append(exchange).append(" ").append(station).append("]");
} else {
if (countryCode != null && countryCode.length() > 0) {
// format country code as '+CC-'
sb.append("+").append(countryCode).append("-");
}
if (ndd != null && ndd.length() > 0) {
if (countryCode != null && countryCode.equals("1") ) {
// in the US we don't write both the country code & the NDD
; // igonre the NDD
} else {
// format NDD as '(N) '
sb.append("(").append(ndd).append(") ");
}
}
if (areaCode != null && areaCode.length() > 0) {
// we could use a java.text.Format - but noooooo
// assume US style (000)
if ( areaCode.length() == 1 ) {
if (isTenDigitArea == true) {
sb.append("00").append(areaCode).append(" ");
} else {
sb.append("(").append("00").append(areaCode).append(") ");
}
} else if (areaCode.length() == 2 ) {
if (isTenDigitArea == true) {
sb.append("0").append(areaCode).append(" ");
} else {
sb.append("(").append("0").append(areaCode).append(") ");
}
} else if (areaCode.length() == 3 ) {
if (isTenDigitArea == true) {
sb.append(areaCode).append(" ");
} else {
sb.append("(").append(areaCode).append(") ");
}
} else {
// more than 3 digits? - OK whatever
if (isTenDigitArea == true) {
sb.append(areaCode).append(" ");
} else {
sb.append("(").append(areaCode).append(") ");
}
}
}
// exchange - assume US style 000
if ( exchange.length() == 1 ) {
sb.append("00").append(exchange).append("-");
} else if (exchange.length() == 2 ) {
sb.append("0").append(exchange).append("-");
} else if (exchange.length() == 3 ) {
sb.append(exchange).append("-");
} else {
// more than 3 digits? - OK whatever
sb.append(exchange).append("-");
}
// station - assume US style 0000
if ( station.length() == 1 ) {
sb.append("000").append(station);
} else if (station.length() == 2 ) {
sb.append("00").append(station);
} else if (station.length() == 3 ) {
sb.append("0").append(station);
} else {
sb.append(station);
}
if (extension != null && extension.length() > 0) {
sb.append(" ext: ").append(extension);
}
}
return sb.toString();
}
/** MAIN - a test stub */
public static void main(String[] args) {
// test it out
TelephoneNumber n1 = new TelephoneNumber(); // test null params
TelephoneNumber n2 = new TelephoneNumber(571L, 9999L); // test 2 longs
TelephoneNumber n3 = new TelephoneNumber(479L, 571L, 1003L); // test 3 longs
TelephoneNumber n4 = new TelephoneNumber(303L, 222L, 7800L); // test ten digit dialing
n4.isTenDigitArea = true;
TelephoneNumber n5 = new TelephoneNumber("(888) 341-8876"); // test formated string
TelephoneNumber n6 = new TelephoneNumber(127, 345, 8765); // test 3 integers
TelephoneNumber n7 = new TelephoneNumber(true, "800 GOT MILK"); // test parsing Alpha
TelephoneNumber n8 = new TelephoneNumber(3L, 4L, 5L); // test zero padding
TelephoneNumber n9 = new TelephoneNumber("1", "1", "479", "571", "8509", "40"); // test 6 strings
TelephoneNumber n10 = new TelephoneNumber(9876543210L); // test 1 long
TelephoneNumber n11 = new TelephoneNumber(false, "/800/ 555-1212 x 0"); // test parsing Non-Alpha
System.out.println("TelephoneNumber(): " + n1);
System.out.println("TelephoneNumber(571L, 9999L): " + n2);
System.out.println("TelephoneNumber(479L, 571L, 1003L): " + n3);
System.out.println("TelephoneNumber(303L, 222L, 7800L): " + n4);
System.out.println("TelephoneNumber(\"(888) 341-8876\"): " + n5);
System.out.println("TelephoneNumber(127, 345, 8765): " + n6);
System.out.println("TelephoneNumber(true, \"800 GOT MILK\"): " + n7);
System.out.println("TelephoneNumber(3L, 4L, 5L): " + n8);
System.out.println("TelephoneNumber(\"1\", \"1\", \"479\", \"571\", \"8509\", \"40\"): " + n9);
System.out.println("TelephoneNumber(9876543210L): " + n10);
System.out.println("TelephoneNumber(false, \"/800/ 555-1212 x 0\"): " + n11);
System.out.println("TelephoneNumber.format(\"{6} [{2} {3}-{4}]\"): " + n7.format("{6} [{2} {3}-{4}]"));
System.out.println("TelephoneNumber.format(): " + n9.format());
}
/******************************************************************/
/*** Getter/Setter ***/
/******************************************************************/
public String getNdd() {
return ndd;
}
public void setNdd(String value) {
ndd = value;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String value) {
countryCode = value;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String value) {
areaCode = value;
}
public String getExchange() {
return exchange;
}
public void setExchange(String value) {
exchange = value;
}
public String getStation() {
return station;
}
public void setStation(String value) {
station = value;
}
public String getExtension() {
return extension;
}
public void setExtension(String value) {
extension = value;
}
public boolean isTenDigitArea() {
return isTenDigitArea;
}
public void setTenDigitArea(boolean value) {
isTenDigitArea = value;
}
public String getAlphaNumber() {
return alphaNumber;
}
public void setAlphaNumber(String value) {
alphaNumber = value;
}
public boolean isAlphaNumber() {
return isAlphaNumber;
}
public void setAlphaNumber(boolean value) {
isAlphaNumber = value;
}
}
Comments