본문 바로가기

[Java] String.format()으로 깔끔한 문자열 만들기: 포맷 지정자 완전 정복

IT by Sense. 2025. 6. 1.

목차

    Java에서 문자열을 다루다 보면, 변수 값을 포함하거나 특정 형식에 맞춰 문자열을 구성해야 할 때가 많습니다. 단순 문자열 결합(+ 연산자)은 코드가 지저분해지거나 가독성이 떨어질 수 있습니다. 이럴 때 String 클래스의 static 메서드인 format()을 사용하면 매우 유용하고 깔끔하게 문자열 형식을 지정할 수 있습니다.

    String.format() 메서드는 C언어의 printf 함수와 유사한 방식으로, 형식 지정자(format specifier)를 사용하여 다양한 타입의 데이터를 원하는 형태로 문자열에 삽입합니다.

    기본적인 사용법은 다음과 같습니다.

    public static String format(String format, Object... args)
    public static String format(Locale l, String format, Object... args)
    

    첫 번째 메서드는 시스템의 기본 로캘(Locale) 설정을 따르며, 두 번째 메서드는 특정 로캘을 지정하여 국가별 형식에 맞게 문자열을 생성할 수 있습니다.

    주요 형식 지정자들은 다음과 같습니다:

    • %d: 10진수 정수
    • %s: 문자열
    • %f: 실수
    • %t: 날짜/시간
    • %c: 유니코드 문자
    • %o, %x: 8진수, 16진수 정수

    이제 각 지정자별 사용법을 자세히 알아보겠습니다.

    1. 숫자를 더욱 깔끔하게: %d (정수 포맷팅)

    10진수 정수(integer) 값을 특정 형식으로 표현할 때 사용합니다.

    int count = 7;
    int bigNumber = 1234567;
    
    System.out.println(String.format("기본: [%d]", count));          // 기본 출력
    System.out.println(String.format("5자리, 오른쪽 정렬: [%5d]", count)); // 전체 5자리, 오른쪽 정렬
    System.out.println(String.format("5자리, 왼쪽 정렬: [%-5d]", count)); // 전체 5자리, 왼쪽 정렬
    System.out.println(String.format("5자리, 0으로 채움: [%05d]", count)); // 전체 5자리, 빈 공간을 0으로
    System.out.println(String.format("천단위 쉼표: [%,d]", bigNumber));    // 천단위 쉼표
    System.out.println(String.format("15자리, 천단위 쉼표, 0채움: [%,015d]", bigNumber));
    

    출력 결과:

    기본: [7]
    5자리, 오른쪽 정렬: [    7]
    5자리, 왼쪽 정렬: [7    ]
    5자리, 0으로 채움: [00007]
    천단위 쉼표: [1,234,567]
    15자리, 천단위 쉼표, 0채움: [000,1,234,567]
    
    • %d 사이에 숫자를 넣어 전체 자릿수를 지정할 수 있습니다.
    • 기본적으로 오른쪽 정렬되며, -를 붙이면 왼쪽 정렬됩니다.
    • 숫자 앞에 0을 붙이면 남는 공간을 0으로 채웁니다 (leading zeros).
    • , 플래그를 사용하면 천 단위마다 쉼표를 넣어줍니다.

    2. 문자열을 원하는 대로: %s (문자열 포맷팅)

    문자열(String)의 형식을 지정할 때 사용합니다.

    String message = "Hello";
    
    System.out.println(String.format("기본: [%s]", message));
    System.out.println(String.format("10자리, 오른쪽 정렬: [%10s]", message));
    System.out.println(String.format("10자리, 왼쪽 정렬: [%-10s]", message));
    System.out.println(String.format("최대 3글자: [%.3s]", message));
    System.out.println(String.format("10자리, 왼쪽 정렬, 최대 3글자: [%-10.3s]", message));
    System.out.println(String.format("10자리, 오른쪽 정렬, 최대 3글자: [%10.3s]", message));
    

    출력 결과:

    기본: [Hello]
    10자리, 오른쪽 정렬: [     Hello]
    10자리, 왼쪽 정렬: [Hello     ]
    최대 3글자: [Hel]
    10자리, 왼쪽 정렬, 최대 3글자: [Hel       ]
    10자리, 오른쪽 정렬, 최대 3글자: [       Hel]
    
    • %s는 문자열을 그대로 출력합니다.
    • %s 사이에 숫자를 넣어 전체 자릿수를 확보하고, -로 정렬 방향을 지정할 수 있습니다.
    • .숫자를 사용하면 문자열의 최대 출력 길이를 제한할 수 있습니다.

    3. 소수점 정밀도 제어: %f (실수 포맷팅)

    실수(floating-point) 값의 형식을 지정합니다.

    double pi = 3.1415926535;
    
    System.out.println(String.format("기본 (소수점 6자리): [%f]", pi));
    System.out.println(String.format("소수점 2자리: [%.2f]", pi));       // 반올림됨
    System.out.println(String.format("전체 10자리, 소수점 3자리: [%10.3f]", pi));
    System.out.println(String.format("전체 10자리, 왼쪽정렬, 소수점 3자리: [%-10.3f]", pi));
    System.out.println(String.format("전체 10자리, 0채움, 소수점 2자리: [%010.2f]", pi));
    

    출력 결과:

    기본 (소수점 6자리): [3.141593]
    소수점 2자리: [3.14]
    전체 10자리, 소수점 3자리: [     3.142]
    전체 10자리, 왼쪽정렬, 소수점 3자리: [3.142     ]
    전체 10자리, 0채움, 소수점 2자리: [0000003.14]
    
    • %f의 기본 소수점 자릿수는 6자리입니다.
    • .숫자를 통해 원하는 소수점 자릿수를 지정할 수 있으며, 값은 반올림됩니다.
    • 정수부와 마찬가지로 전체 자릿수, 정렬, 0 채우기 등을 적용할 수 있습니다. (이때 .도 자릿수에 포함됩니다.)

    4. 다국어 지원의 핵심: Locale 활용

    String.format(Locale, String, Object...) 메서드를 사용하면 특정 국가나 지역의 형식에 맞춰 문자열을 생성할 수 있습니다. 이는 숫자, 통화, 날짜/시간 표현 등에서 중요합니다.

    import java.util.Date;
    import java.util.Locale;
    
    int amount = 1234500;
    Date now = new Date();
    
    // 기본 로캘 (한국어 OS 기준)
    System.out.println(String.format("금액 (기본): %,d 원", amount));
    System.out.println(String.format("오전/오후 (기본): %tp", now));
    
    // 미국 로캘
    System.out.println(String.format(Locale.US, "Amount (US): $%,d", amount));
    System.out.println(String.format(Locale.US, "AM/PM (US): %tp", now));
    
    // 독일 로캘
    System.out.println(String.format(Locale.GERMANY, "Betrag (DE): %,d €", amount));
    System.out.println(String.format(Locale.GERMANY, "AM/PM (DE): %tp", now)); // 독일은 am/pm 대신 다른 표현 사용 가능
    

    출력 결과 (실행 환경에 따라 약간 다를 수 있음):

    금액 (기본): 1,234,500 원
    오전/오후 (기본): 오후 (또는 현재 시간에 따라 오전)
    Amount (US): $1,234,500
    AM/PM (US): pm (or am depending on current time)
    Betrag (DE): 1.234.500 €
    AM/PM (DE): pm (or am, Germany might show 24h time or different indicators)
    
    • 로캘을 지정하지 않으면 OS의 기본 설정이 적용됩니다.
    • 미국은 천 단위 구분자로 ,를 사용하고, 독일은 .를 사용합니다.
    • 오전/오후를 나타내는 %tp도 로캘에 따라 오후, pm 등으로 다르게 표시됩니다.

    5. 시간과 날짜를 자유자재로: %t (날짜/시간 포맷팅)

    Date 또는 Calendar 객체를 다양한 형식으로 표현할 때 사용합니다. %t 뒤에 특정 문자를 추가하여 원하는 부분을 추출합니다.

    문자 설명 예시 (2023년 10월 26일 14시 30분 5초)
    Y 연도 (4자리) 2023
    y 연도 (2자리) 23
    m 월 (01-12) 10
    B 월 이름 (로캘에 따라 다름) 10월 (한국어), October (영어)
    b 월 축약 이름 (로캘에 따라 다름) 10월 (한국어), Oct (영어)
    d 일 (01-31) 26
    e 일 (1-31, 0 없음) 26
    A 요일 이름 (로캘에 따라 다름) 목요일 (한국어), Thursday (영어)
    a 요일 축약 이름 (로캘에 따라 다름) (한국어), Thu (영어)
    H 시 (24시간, 00-23) 14
    I 시 (12시간, 01-12) 02
    k 시 (24시간, 0-23, 0 없음) 14
    l 시 (12시간, 1-12, 0 없음) 2
    M 분 (00-59) 30
    S 초 (00-59) 05
    L 밀리초 (000-999) (해당 값)
    N 나노초 (000000000-999999999) (해당 값)
    p 오전/오후 (로캘에 따라 소문자) 오후 (한국어), pm (영어)
    Z 시간대 이름 KST
    z 시간대 오프셋 +0900

    복합 형식 지정자:

    • %tF: YYYY-MM-DD 형식 (%tY-%tm-%td와 동일)
    • %tD: MM/DD/YY 형식 (%tm/%td/%ty와 동일)
    • %tT: HH:MM:SS 형식 (24시간, %tH:%tM:%tS와 동일)
    • %tR: HH:MM 형식 (24시간, %tH:%tM와 동일)
    • %tc: 로캘 특정 전체 날짜/시간 (%ta %tb %td %tT %tZ %tY 와 유사)
    import java.util.Date;
    import java.util.Locale;
    
    Date today = new Date(); // 현재 날짜와 시간
    
    System.out.println(String.format("전체 날짜 (YYYY-MM-DD): %tF", today));
    System.out.println(String.format("전체 시간 (HH:MM:SS): %tT", today));
    System.out.println(String.format("연월일(YYMMDD): %ty%tm%td", today, today, today)); // 각 요소마다 today 전달
    System.out.println(String.format("시분초(HHMMSS): %tH%tM%tS", today, today, today));
    System.out.println(String.format(Locale.US, "월(축약), 일, 연도(4자리): %tb %<te, %<tY", today)); // '<'는 이전 인수 재사용
    System.out.println(String.format(Locale.KOREA, "요일(전체), 오전/오후: %tA %<tp", today));
    

    출력 예시 (2023년 10월 26일 14시 30분 5초 기준):

    전체 날짜 (YYYY-MM-DD): 2023-10-26
    전체 시간 (HH:MM:SS): 14:30:05
    연월일(YYMMDD): 231026
    시분초(HHMMSS): 143005
    월(축약), 일, 연도(4자리): Oct 26, 2023
    요일(전체), 오전/오후: 목요일 오후
    
    • %t 지정자마다 해당 Date 또는 Calendar 객체를 인수로 전달해야 합니다.
    • < 플래그를 사용하면 이전 인수를 재사용할 수 있어 편리합니다. (%<te는 바로 앞의 today를 다시 사용)

    6. 기타 유용한 서식자들

    6.1. %c (유니코드 문자 포맷팅):

    정수 값을 유니코드 문자로 변환합니다.

    System.out.println(String.format("65 -> %c, 97 -> %c", 65, 97));    // 65 -> A, 97 -> a
    System.out.println(String.format("44032 -> %c", 44032));         // 44032 -> 가
    

    출력:

    65 -> A, 97 -> a
    44032 -> 가
    

    6.2. %o, %x (8진수/16진수 포맷팅):

    정수를 각각 8진수, 16진수로 표현합니다.

    int value = 255;
    System.out.println(String.format("10진수 %d는 8진수 %o, 16진수 %x 입니다.", value, value, value));
    System.out.println(String.format("16진수 대문자: %X", value)); // X는 대문자로 출력
    

    출력:

    10진수 255는 8진수 377, 16진수 ff 입니다.
    16진수 대문자: FF
    

    6.3. %% (퍼센트 문자 자체 출력):

    포맷 문자열 내에서 % 기호를 사용하고 싶다면 %%로 입력합니다.

    System.out.println(String.format("할인율: 10%%"));
    

    출력:

    할인율: 10%
    

    마무리

    String.format() 메서드는 Java에서 문자열을 동적으로 구성하고 형식을 지정하는 데 매우 강력하고 유연한 도구입니다. 다양한 형식 지정자와 플래그, 로캘 설정을 조합하여 원하는 거의 모든 형태의 문자열을 만들어낼 수 있습니다. 코드의 가독성을 높이고, 유지보수를 용이하게 하며, 특히 다국어 환경을 지원하는 애플리케이션 개발 시 필수적인 기능입니다.

    다양한 옵션들을 직접 테스트해보면서 손에 익히면, 문자열 처리 작업이 훨씬 수월해질 것입니다!

    • 트위터 공유하기
    • 페이스북 공유하기
    • 카카오톡 공유하기