C#

[문법] IFormatProvider

CCS_Cheese 2025. 8. 4. 19:36

이전 String To int Parser에 이어지는 내용으로 int.Parse의 파라미터에 있는 IFormatProvider에 대해서 알아보도록 하겠습니다.

2025.07.15 - [C#] - [문법] String To int Parser

 

[문법] String To int Parser

2025.07.10 - [코딩테스트] - [PCCP 기출문제] 1번 / 동영상 재생기 위 코딩 테스트 문제를 풀면서 아쉬웠던 문법들에 대해 알아보는 시간을 가지고자 글을 작성하게 되었습니다. C# 공식문서 문자열을

develophyun.tistory.com

IFormatProvider 공식문서

 

IFormatProvider Interface (System)

Provides a mechanism for retrieving an object to control formatting.

learn.microsoft.com

IFormatProvider는 기본적으로 '서식 지정을 제어하는 개체를 검색하기 위한 메커니즘을 제공'합니다.
서식을 지정을 제어한다는 것은 int.Parse에서 숫자를 지정된 문화권에 맞춰 변환하는 것을 의미합니다. 아래에서 자세히 다루어 보겠습니다.


기본적으로 많이 사용하는 IFormatProvider 방식으로는 CultureInfo를 활용하여 현재 접속한 문화권에 맞춰 기본적으로 변환하는 것을 많이 활용합니다

int.Parse(string targetString, NumberStyles targetNumberStyles, IFormatProvider provider);

 

정의부에서 볼 수 있듯이 IFormatProvider를 상속받은 Class는 모두 해당 파싱에 활용될 수 있습니다. 많이 사용되는 CultureInfo에 대해서 알아보겠습니다.

namespace System.Globalization
{
    public class CultureInfo : ICloneable, IFormatProvider
    {
        public CultureInfo(int culture);
        public CultureInfo(string name);
        public CultureInfo(int culture, bool useUserOverride);
        public CultureInfo(string name, bool useUserOverride);

        public static CultureInfo InvariantCulture { get; }
        public static CultureInfo InstalledUICulture { get; }
        public static CultureInfo DefaultThreadCurrentUICulture { get; set; }
        public static CultureInfo DefaultThreadCurrentCulture { get; set; }
        public static CultureInfo CurrentCulture { get; set; }
        public static CultureInfo CurrentUICulture { get; set; }
        public virtual string EnglishName { get; }
        public virtual string ThreeLetterWindowsLanguageName { get; }
        public virtual string ThreeLetterISOLanguageName { get; }
        public virtual TextInfo TextInfo { get; }
        public virtual CultureInfo Parent { get; }
        public virtual Calendar[] OptionalCalendars { get; }
        public virtual NumberFormatInfo NumberFormat { get; set; }
        public virtual string NativeName { get; }
        public virtual string Name { get; }
        public virtual int LCID { get; }
        public virtual int KeyboardLayoutId { get; }
        public bool IsReadOnly { get; }
        public virtual bool IsNeutralCulture { get; }
        public string IetfLanguageTag { get; }
        public virtual string DisplayName { get; }
        public bool UseUserOverride { get; }
        public virtual Calendar Calendar { get; }
        public virtual DateTimeFormatInfo DateTimeFormat { get; set; }
        public virtual CompareInfo CompareInfo { get; }
        public virtual string TwoLetterISOLanguageName { get; }
        public CultureTypes CultureTypes { get; }

        public static CultureInfo CreateSpecificCulture(string name);
        public static CultureInfo GetCultureInfo(string name, string altName);
        public static CultureInfo GetCultureInfo(string name);
        public static CultureInfo GetCultureInfo(int culture);
        public static CultureInfo GetCultureInfoByIetfLanguageTag(string name);
        public static CultureInfo[] GetCultures(CultureTypes types);
        public static CultureInfo ReadOnly(CultureInfo ci);
        public void ClearCachedData();
        public virtual object Clone();
        public override bool Equals(object value);
        public CultureInfo GetConsoleFallbackUICulture();
        public virtual object GetFormat(Type formatType);
        public override int GetHashCode();
        public override string ToString();
    }
}

 

각 나라별 CultureInfo의 기호 정리

지역 CultureInfo 천 단위
구분자
소수점
구분자
통화
기호
날짜 패턴
(`"d"`)
1 234 567.89
표현 예
대한민국 ko-KR , . yyyy-MM-dd 1,234,567.89
일본 ja-JP , . yyyy/MM/dd 1,234,567.89
중국 zh-CN , . yyyy/M/d 1,234,567.89
미국 en-US , . $ M/d/yyyy 1,234,567.89
인도 en-IN / hi-IN , . dd/MM/yyyy 12,34,567.89
프랑스 fr-FR (공백) , dd/MM/yyyy 1 234 567,89

 

간단하게, 대한민국, 일본, 중국, 미국, 인도, 유럽(프랑스) 등으로 각 문화권에 따른 통화 기호 및 각 숫자 표현, 날짜 패턴들이 다 다르기 때문에 실제 숫자 문자열을 변환할 때 각 문화권에 맞춰서 활용합니다. 국내에서만 사용하는 서비스라면 문제가 없지만, 앱 내에서 다국어를 적용하게 된다면, 우리나라에서도 미국이나, 중국의 통화 기호나 숫자 표현의 변환을 신경 써야 할 필요가 있다는 것이지요. Ex) 테이블 오더의 다국어 설정

 

여기까지는 기본적인 IFormatProvider를 상속받은 CultureInfo에 대한 설명이고 이를 활용해 보면 아래와 같은 방식으로 활용이 가능합니다.

 var de = CultureInfo.GetCultureInfo("de-DE");
 string raw = "123.1231";
 // 천 단위 점(.) 허용하려면 스타일에 AllowThousands 추가
 int deDeValues = int.Parse(raw,
                       NumberStyles.AllowThousands,
                       de);              // → 1231231

 Debug.Log($"de-DE : {deDeValues}");
 // Output >> de-DE : 1231231

 

코드 설명

  • 독일권에서는 첫 단위 기호를 점(.)을 활용하게 되는데 이를 활용하여 독일권의 숫자 변환 방식에 대응이 가능합니다.

추가적으로 사용자가 직접 커스텀하게 NumberStyles을 수정하여, 사용자만의 IFormatProvider를 사용할 수 있습니다. 아래 소스에서 확인해 보겠습니다.

 

public class FormatProvider : IFormatProvider
{
    private NumberFormatInfo nfi;

    public NumberFormatInfo Nfi => nfi ??= new NumberFormatInfo() { NegativeSign = "&", NumberGroupSeparator = "*" };
    public object GetFormat(Type formatType)
    {
        return Nfi;
    }
}

 

처음 int.Parse의 정의부를 확인해 보시면 특정 Class가 아닌 IFormatProvider 인터페이스를 파라미터로 받고 있는 것을 볼 수 있습니다. 이는 IFormatProvider를 상속받은 모든 Class는 모두 인자로 전달받을 수 있다는 뜻입니다. 그리하여, 사용자가 직접 특정 문화권에 귀속되지 않은 나만의 FormatProvider를 적용할 수 있습니다. 코드에서 볼 수 있듯이. NumberFormatInfo를 추가적으로 수정하여 GetFormat시 return 하고 있습니다.

 

해당 Provider를 활용하는 부분을 같이 보겠습니다.

FormatProvider formatProvider = new FormatProvider();
int CustomProvider = int.Parse("&1*2*3*4*1*2*3*4", 
NumberStyles.AllowThousands | NumberStyles.AllowLeadingSign, formatProvider);

Debug.Log(CustomProvider);
// Output >> -12341234

 

코드 설명

  • 미리 사전에 정의한 Provider인 FormatProvider를 생성하고, 이를 int.Parse 시 Provider로 전달하게 되면 내부적으로 ko(대한민국)의 음수 기호와, 천의자리 구분자가 사용자가 정의한 기호로 변경되어 해석되어 변환됩니다.

위와 같은 방식으로 다양한 문화권, 커스텀한 Provider를 통해, 문자열 변환이 가능하고 이를 프로그램에서 활용할 수 있습니다. 

 

글을 마치며

해당 글에서는 String To int에 관한 IFormatProvider에 대해서만 다루고, 되게 간략하게 적용해 보았는데요. 공식문서를 보시면 아시겠지만, 사용자가 직접 정의한 FormatProvider는 더 다양한 방식으로 분기처리하고 추가적인 작업이 가능합니다.
위 표를 보시면 아시겠지만, 문화권에 따라 DateTime, 시간의 문자열 표기가 다르기 때문에 이를 프로그램에서 하나의 데이터 타입 (DateTime, TimeSpan)등으로 변환할 때 활용이 가능할 수 있다는 것을 알게 되었습니다.

추가 Tips

사용자 커스텀이나, 문화권을 추가하여, IFormatProvider를 통해 문자열이 매칭되어도, NumberStyles이 허용되어있지 않으면, 정상적으로 변환되지 않을 수 있고, 일반적인 프로그램에서는 CulureInfo를 통해 대부분 대응이 될 것으로 생각합니다.

'C#' 카테고리의 다른 글

[문법] ReadOnlySpan<char> 자료형  (2) 2025.08.12
[문법] String To int Parser  (0) 2025.07.15