개요: .NET에서 숫자, 날짜, 열거형 및 기타 형식의 형식을 지정하는 방법

서식 지정은 클래스나 구조체의 인스턴스 또는 열거형 값을 문자열 표현으로 변환하는 프로세스입니다. 목적은 결과 문자열을 사용자에게 표시하거나 나중에 역직렬화하여 원래 데이터 형식을 복원하는 것입니다. 이 문서에서는 .NET이 제공하는 서식 지정 메커니즘을 소개합니다.

참고 항목

구문 분석은 형식 지정과 반대 과정으로 진행됩니다. 구문 분석 작업은 해당 문자열 표현에서 데이터 형식의 인스턴스를 만듭니다. 자세한 내용은 문자열 구문 분석을 참조하세요. 직렬화 및 역직렬화에 대한 자세한 내용은 .NET의 직렬화를 참조하세요.

서식 지정의 기본 메커니즘은 이 항목의 뒷부분에 나오는 ToString 메서드를 사용한 기본 형식 지정 섹션에서 설명하는 Object.ToString 메서드의 기본 구현입니다. 그러나 .NET에서는 기본 형식 지정 지원을 수정하고 확장할 수 있는 여러 가지 방법을 제공합니다. 여기에는 다음이 포함됩니다.

  • Object.ToString 메서드를 재정의하여 개체의 값에 대한 사용자 지정 문자열 표현을 정의합니다. 자세한 내용은 이 항목의 뒷부분에 있는 ToString 메서드 재정의 섹션을 참조하세요.

  • 개체의 값에 대한 문자열 표현에서 여러 형식을 사용할 수 있도록 형식 지정자를 정의합니다. 예를 들어, 다음 문의 "X" 형식 지정자는 정수를 16진수 값의 문자열 표현으로 변환합니다.

    int integerValue = 60312;
    Console.WriteLine(integerValue.ToString("X"));   // Displays EB98.
    
    Dim integerValue As Integer = 60312
    Console.WriteLine(integerValue.ToString("X"))   ' Displays EB98.
    

    형식 지정자에 대한 자세한 내용은 ToString 메서드 및 형식 문자열 단원을 참조하세요.

  • 서식 공급자를 사용하여 특정 문화권의 서식 지정 규칙을 구현합니다. 예를 들어, 다음 문은 en-US 문화권의 형식 지정 규칙을 사용하여 통화 값을 표시합니다.

    double cost = 1632.54;
    Console.WriteLine(cost.ToString("C",
                      new System.Globalization.CultureInfo("en-US")));
    // The example displays the following output:
    //       $1,632.54
    
    Dim cost As Double = 1632.54
    Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US")))
    ' The example displays the following output:
    '       $1,632.54
    

    형식 공급자를 사용하여 형식을 지정하는 방법에 대한 자세한 내용은 형식 공급자 섹션을 참조하세요.

  • IFormattable 인터페이스를 구현하여 Convert 클래스를 사용하여 문자열 변환과 복합 형식 지정을 지원합니다. 자세한 내용은 IFormattable 인터페이스 단원을 참조하세요.

  • 복합 형식 지정을 사용하여 값의 문자열 표현을 더 큰 문자열에 포함합니다. 자세한 내용은 복합 형식 지정 단원을 참조하세요.

  • 문자열 보간을 사용하면 보다 읽기 쉬운 구문으로 더 큰 문자열에 값의 문자열 표현을 포함할 수 있습니다. 자세한 내용은 문자열 보간을 참조하세요.

  • ICustomFormatterIFormatProvider 를 구현하여 완벽한 사용자 지정 형식 지정 솔루션을 제공합니다. 자세한 내용은 ICustomFormatter를 사용한 사용자 지정 형식 지정 단원을 참조하세요.

다음 단원에서는 개체를 문자열 표현으로 변환하는 데 대해 이러한 메서드를 검토합니다.

ToString 메서드를 사용한 기본 서식 지정

System.Object 에서 파생되는 모든 형식은 기본적으로 형식의 이름을 반환하는 매개 변수가 없는 ToString 메서드를 상속합니다. 다음 예제에서는 기본 ToString 메서드를 보여 줍니다. 이 예제에서는 구현이 없는 Automobile 이라는 클래스를 정의합니다. 클래스가 인스턴스화되고 ToString 메서드가 호출되면 해당 형식 이름이 표시됩니다. 예제에서는 ToString 메서드를 명시적으로 호출하지 않습니다. Console.WriteLine(Object) 메서드는 인수로 전달되는 개체의 ToString 메서드를 암시적으로 호출합니다.

using System;

public class Automobile
{
   // No implementation. All members are inherited from Object.
}

public class Example9
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile
Public Class Automobile
    ' No implementation. All members are inherited from Object.
End Class

Module Example9
    Public Sub Main9()
        Dim firstAuto As New Automobile()
        Console.WriteLine(firstAuto)
    End Sub
End Module
' The example displays the following output:
'       Automobile

Warning

Windows 8.1부터 Windows 런타임에는 기본 형식 지원을 제공하는 단일 메서드인 IStringable.ToString이 포함된 IStringable 인터페이스가 포함됩니다. 그러나 관리되는 형식은 IStringable 인터페이스를 구현하지 않는 것이 좋습니다. 자세한 내용은 Object.ToString 참조 페이지의 " Windows Runtime 및 IStringable 인터페이스" 섹션을 참조하세요.

인터페이스를 제외한 모든 형식이 Object에서 파생되기 때문에 이 함수는 사용자 지정 클래스 또는 구조체에 자동으로 제공됩니다. 그러나 기본 ToString 메서드에서 제공하는 기능은 제한되어 있기 때문에 형식을 정의하더라도 해당 형식의 인스턴스에 대한 정보를 제공할 수 없습니다. 이 개체에 대한 정보를 제공하는 개체의 문자열 표현을 제공하려면 ToString 메서드를 재정의해야 합니다.

참고 항목

구조체는 ValueType에서 상속되며, 이 형식은 다시 Object에서 파생됩니다. ValueTypeObject.ToString을 재정의해도 해당 구현은 동일합니다.

ToString 메서드 재정의

형식 이름을 표시할 수 있는 경우가 종종 제한되어 형식의 사용자가 서로 다른 인스턴스를 구분할 수 없는 경우가 있습니다. 그러나 ToString 메서드를 재정의하여 개체 값을 더 유용하게 표현할 수 있습니다. 다음 예제에서는 Temperature 개체를 정의하고 ToString 메서드를 재정의하여 온도를 섭씨 단위로 표시합니다.

public class Temperature
{
    private decimal temp;

    public Temperature(decimal temperature)
    {
        this.temp = temperature;
    }

    public override string ToString()
    {
        return this.temp.ToString("N1") + "°C";
    }
}

public class Example12
{
    public static void Main()
    {
        Temperature currentTemperature = new Temperature(23.6m);
        Console.WriteLine($"The current temperature is {currentTemperature}");
    }
}
// The example displays the following output:
//       The current temperature is 23.6°C.
Public Class Temperature
    Private temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.temp = temperature
    End Sub

    Public Overrides Function ToString() As String
        Return Me.temp.ToString("N1") + "°C"
    End Function
End Class

Module Example13
    Public Sub Main13()
        Dim currentTemperature As New Temperature(23.6D)
        Console.WriteLine("The current temperature is " +
                          currentTemperature.ToString())
    End Sub
End Module
' The example displays the following output:
'       The current temperature is 23.6°C.

.NET에서 각 기본 값 형식의 ToString 메서드는 개체의 이름 대신 개체의 값을 표시하도록 재정의되었습니다. 다음 표에는 각 기본 형식의 재정의가 나와 있습니다. 재정의된 메서드의 대부분은 ToString 메서드의 다른 오버로드를 호출하고 이를 해당 형식에 대한 일반적인 형식을 정의하는 "G" 형식 지정자와 현재 문화권을 나타내는 IFormatProvider 개체에 전달합니다.

Type ToString 재정의
Boolean Boolean.TrueString 또는 Boolean.FalseString을 반환합니다.
Byte Byte.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Byte 값의 형식을 지정합니다.
Char 문자를 문자열로 반환합니다.
DateTime DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 날짜 및 시간 값의 형식을 지정합니다.
Decimal Decimal.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Decimal 값의 형식을 지정합니다.
Double Double.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Double 값의 형식을 지정합니다.
Int16 Int16.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Int16 값의 형식을 지정합니다.
Int32 Int32.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Int32 값의 형식을 지정합니다.
Int64 Int64.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Int64 값의 형식을 지정합니다.
SByte SByte.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 SByte 값의 형식을 지정합니다.
Single Single.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 Single 값의 형식을 지정합니다.
UInt16 UInt16.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 UInt16 값의 형식을 지정합니다.
UInt32 UInt32.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 UInt32 값의 형식을 지정합니다.
UInt64 UInt64.ToString("G", NumberFormatInfo.CurrentInfo) 을 호출하여 현재 문화권에 대한 UInt64 값의 형식을 지정합니다.

ToString 메서드 및 서식 문자열

개체에 문자열 표현이 하나만 있는 경우에는 기본 ToString 메서드를 사용하거나 ToString 을 재정의합니다. 하지만 개체의 값에 여러 표현이 있는 경우가 자주 있습니다. 예를 들어 온도는 화씨, 섭씨 또는 캘빈으로 표시할 수 있습니다. 마찬가지로 정수 값 10도 10, 10.0, 1.0e01, $10.00 등과 같은 여러 가지 방식으로 표현될 수 있습니다.

하나의 값에 여러 문자열 표현을 허용하기 위해 .NET에서는 형식 문자열을 사용합니다. 형식 문자열은 하나 이상의 미리 정의된 형식 지정자가 들어 있는 문자열이며, 이러한 형식 지정자는 ToString 메서드가 해당 출력의 형식을 지정하는 방식을 정의한 단일 문자 또는 문자 그룹입니다. 형식 문자열은 개체의 ToString 메서드에 매개 변수로 전달되어 개체의 값에 대한 문자열 표현의 표시 방법을 결정합니다.

.NET의 모든 숫자 형식, 날짜/시간 형식 및 열거형 형식은 미리 정의된 형식 지정자 집합을 지원합니다. 형식 문자열을 사용하여 애플리케이션 정의 데이터 형식의 여러 문자열 표현도 정의할 수 있습니다.

표준 서식 문자열

표준 형식 문자열에는 개체의 문자열 표현을 정의하는 영문자인 단일 형식 지정자와 함께 결과 문자열을 표시하는 데 사용할 자릿수에 영향을 주는 선택적 전체 자릿수 지정자가 포함됩니다. 전체 자릿수 지정자가 생략되었거나 지원되지 않으면 표준 형식 지정자는 표준 형식 문자열과 같습니다.

.NET에서는 모든 숫자 형식, 날짜/시간 형식 및 열거형 형식에 대한 표준 형식 지정자 집합을 정의합니다. 예를 들어, 이러한 각 범주는 해당 형식 값에 대한 일반적인 문자열 표현을 정의하는 "G" 표준 형식 지정자를 지원합니다.

열거형 형식의 표준 형식 문자열은 값의 문자열 표현을 직접 제어합니다. 열거형 값의 ToString 메서드에 전달된 형식 문자열은 값이 문자열 이름(“G” 및 “F” 형식 지정자), 내부 정수 값(“D” 형식 지정자) 또는 16진수 값(“X” 형식 지정자)을 사용하여 표시되는지 여부를 결정합니다. 다음 예제에서는 표준 형식 문자열을 사용하여 DayOfWeek 열거형 값의 형식을 지정하는 방법을 보여 줍니다.

DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};

foreach (string formatString in formatStrings)
   Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
//       Monday
//       Monday
//       1
//       00000001
Dim thisDay As DayOfWeek = DayOfWeek.Monday
Dim formatStrings() As String = {"G", "F", "D", "X"}

For Each formatString As String In formatStrings
    Console.WriteLine(thisDay.ToString(formatString))
Next
' The example displays the following output:
'       Monday
'       Monday
'       1
'       00000001

열거형 형식 문자열에 대한 자세한 내용은 Enumeration Format Strings을 참조하세요.

일반적으로 숫자 형식의 표준 형식 문자열은 정확한 모양이 하나 이상의 속성 값에 의해 제어되는 결과 문자열을 정의합니다. 예를 들어, "C" 형식 지정자는 숫자의 형식을 통화 값으로 지정합니다. “C” 형식 지정자를 유일한 매개 변수로 사용하여 ToString 메서드를 호출하면 현재 문화권의 NumberFormatInfo 개체에 있는 다음 속성 값이 숫자 값의 문자열 표현을 정의하는 데 사용됩니다.

  • 현재 문화권의 통화 기호를 지정하는 CurrencySymbol 속성

  • 다음과 같은 사항을 결정하는 정수를 반환하는 CurrencyNegativePattern 또는 CurrencyPositivePattern 속성

    • 통화 기호의 위치

    • 음수 값이 선행 음수 기호, 후행 음수 기호 또는 괄호로 표시되는지 여부

    • 숫자 값과 통화 기호 사이에 공백이 표시되는지 여부

  • 결과 문자열의 소수 자릿수를 정의하는 CurrencyDecimalDigits 속성

  • 결과 문자열의 소수 구분 기호를 정의하는 CurrencyDecimalSeparator 속성

  • 그룹 구분 기호를 정의하는 CurrencyGroupSeparator 속성

  • 정수 부분의 각 그룹 자릿수를 정의하는 CurrencyGroupSizes 속성

  • 음수 값을 나타내는 데 괄호가 사용되지 않는 경우 결과 문자열에 사용되는 음수 기호를 결정하는 NegativeSign 속성

이외에도 숫자 형식 문자열에는 전체 자릿수 지정자가 포함될 수도 있습니다. 이 지정자의 의미는 해당 지정자가 사용되는 형식 문자열에 따라 달라지지만 일반적으로 결과 문자열에 표시될 전체 자릿수나 소수 자릿수를 나타냅니다. 예를 들어, 다음 예제에서는 "X4" 표준 숫자 문자열과 전체 자릿수 지정자를 사용하여 네 자리의 16진수로 구성된 문자열 값을 만듭니다.

byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
   Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
//       000C
//       00A3
//       00FF
Dim byteValues() As Byte = {12, 163, 255}
For Each byteValue As Byte In byteValues
    Console.WriteLine(byteValue.ToString("X4"))
Next
' The example displays the following output:
'       000C
'       00A3
'       00FF

표준 숫자 서식 지정 문자열에 대한 자세한 내용은 표준 날짜 및 시간 형식 문자열을 참조하세요.

날짜 및 시간 값의 표준 형식 문자열은 특정 DateTimeFormatInfo 속성에 저장된 사용자 지정 형식 문자열의 별칭입니다. 예를 들어 “D” 형식 지정자를 사용하여 날짜 및 시간 값의 ToString 메서드를 호출하면 현재 문화권의 DateTimeFormatInfo.LongDatePattern 속성에 저장된 사용자 지정 형식 문자열을 사용하여 날짜 및 시간이 표시됩니다. (사용자 지정 서식 문자열에 대한 자세한 내용은 다음 섹션을 참조하세요.) 다음 예제에서는 이러한 관계를 보여 줍니다.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 6, 30);
      Console.WriteLine("D Format Specifier:     {0:D}", date1);
      string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
      Console.WriteLine("'{0}' custom format string:     {1}",
                        longPattern, date1.ToString(longPattern));
   }
}
// The example displays the following output when run on a system whose
// current culture is en-US:
//    D Format Specifier:     Tuesday, June 30, 2009
//    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009
Imports System.Globalization

Module Example
    Public Sub Main0()
        Dim date1 As Date = #6/30/2009#
        Console.WriteLine("D Format Specifier:     {0:D}", date1)
        Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
        Console.WriteLine("'{0}' custom format string:     {1}",
                          longPattern, date1.ToString(longPattern))
    End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
'    D Format Specifier:     Tuesday, June 30, 2009
'    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009

표준 날짜 및 시간 형식 문자열에 대한 자세한 내용은 Standard Date and Time Format Strings을 참조하세요.

표준 형식 문자열을 사용하여 개체의 ToString(String) 메서드에 의해 생성되는 애플리케이션 정의 개체의 문자열 표현도 정의할 수 있습니다. 개체가 지원하는 특정 표준 형식 지정자를 정의하고 이러한 지정자가 대/소문자를 구분하는지 여부를 결정할 수 있습니다. ToString(String) 메서드의 구현에서는 다음을 지원해야 합니다.

  • 개체의 사용자 지정 또는 일반 형식을 나타내는 "G" 형식 지정자. 개체의 ToString 메서드에 대한 매개 변수가 없는 오버로드는 해당 ToString(String) 오버로드를 호출하고 이를 "G" 표준 형식 문자열에 전달해야 합니다.

  • null 참조(Visual Basic의 경우Nothing )와 동일한 형식 지정자에 대한 지원. null 참조와 동일한 형식 지정자는 "G" 형식 지정자와 같은 것으로 간주됩니다.

예를 들어 Temperature 클래스는 섭씨 온도를 내부적으로 저장하고 형식 지정자를 사용하여 Temperature 개체의 값을 섭씨, 화씨 및 캘빈으로 표시할 수 있습니다. 다음 예제에서 이에 대해 설명합니다.

using System;

public class Temperature
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }
   }

   public decimal Fahrenheit
   {
      get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
   }

   public override string ToString()
   {
      return this.ToString("C");
   }

   public string ToString(string format)
   {
      // Handle null or empty string.
      if (String.IsNullOrEmpty(format)) format = "C";
      // Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant();

      // Convert temperature to Fahrenheit and return string.
      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2") + " °F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2") + " K";
         // return temperature in Celsius.
         case "G":
         case "C":
            return this.Celsius.ToString("N2") + " °C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }
   }
}

public class Example1
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(0m);
      Console.WriteLine(temp1.ToString());
      Console.WriteLine(temp1.ToString("G"));
      Console.WriteLine(temp1.ToString("C"));
      Console.WriteLine(temp1.ToString("F"));
      Console.WriteLine(temp1.ToString("K"));

      Temperature temp2 = new Temperature(-40m);
      Console.WriteLine(temp2.ToString());
      Console.WriteLine(temp2.ToString("G"));
      Console.WriteLine(temp2.ToString("C"));
      Console.WriteLine(temp2.ToString("F"));
      Console.WriteLine(temp2.ToString("K"));

      Temperature temp3 = new Temperature(16m);
      Console.WriteLine(temp3.ToString());
      Console.WriteLine(temp3.ToString("G"));
      Console.WriteLine(temp3.ToString("C"));
      Console.WriteLine(temp3.ToString("F"));
      Console.WriteLine(temp3.ToString("K"));

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
   }
}
// The example displays the following output:
//       0.00 °C
//       0.00 °C
//       0.00 °C
//       32.00 °F
//       273.15 K
//       -40.00 °C
//       -40.00 °C
//       -40.00 °C
//       -40.00 °F
//       233.15 K
//       16.00 °C
//       16.00 °C
//       16.00 °C
//       60.80 °F
//       289.15 K
//       The temperature is now 16.00 °C.
Public Class Temperature
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("C")
    End Function

    Public Overloads Function ToString(format As String) As String
        ' Handle null or empty string.
        If String.IsNullOrEmpty(format) Then format = "C"
        ' Remove spaces and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        Select Case format
            Case "F"
                ' Convert temperature to Fahrenheit and return string.
                Return Me.Fahrenheit.ToString("N2") & " °F"
            Case "K"
                ' Convert temperature to Kelvin and return string.
                Return Me.Kelvin.ToString("N2") & " K"
            Case "C", "G"
                ' Return temperature in Celsius.
                Return Me.Celsius.ToString("N2") & " °C"
            Case Else
                Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
        End Select
    End Function
End Class

Public Module Example1
    Public Sub Main1()
        Dim temp1 As New Temperature(0D)
        Console.WriteLine(temp1.ToString())
        Console.WriteLine(temp1.ToString("G"))
        Console.WriteLine(temp1.ToString("C"))
        Console.WriteLine(temp1.ToString("F"))
        Console.WriteLine(temp1.ToString("K"))

        Dim temp2 As New Temperature(-40D)
        Console.WriteLine(temp2.ToString())
        Console.WriteLine(temp2.ToString("G"))
        Console.WriteLine(temp2.ToString("C"))
        Console.WriteLine(temp2.ToString("F"))
        Console.WriteLine(temp2.ToString("K"))

        Dim temp3 As New Temperature(16D)
        Console.WriteLine(temp3.ToString())
        Console.WriteLine(temp3.ToString("G"))
        Console.WriteLine(temp3.ToString("C"))
        Console.WriteLine(temp3.ToString("F"))
        Console.WriteLine(temp3.ToString("K"))

        Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3))
    End Sub
End Module
' The example displays the following output:
'       0.00 °C
'       0.00 °C
'       0.00 °C
'       32.00 °F
'       273.15 K
'       -40.00 °C
'       -40.00 °C
'       -40.00 °C
'       -40.00 °F
'       233.15 K
'       16.00 °C
'       16.00 °C
'       16.00 °C
'       60.80 °F
'       289.15 K
'       The temperature is now 16.00 °C.

사용자 지정 서식 문자열

표준 형식 문자열 외에도 .NET에서는 숫자 값과 날짜 및 시간 값에 대한 사용자 지정 형식 문자열을 정의합니다. 사용자 지정 형식 문자열은 값의 문자열 표현을 정의하는 하나 이상의 사용자 지정 형식 지정자로 구성됩니다. 예를 들어, en-US 문화권의 경우 사용자 지정 날짜 및 시간 형식 문자열 "yyyy/mm/dd hh:mm:ss t zzz"는 날짜를 "2008/11/15 07:45:00.0000 P -08:00" 형태의 문자열 표현으로 변환합니다. 마찬가지로 사용자 지정 형식 문자열 "0000"은 정수 값 12를 "0012"로 변환합니다. 사용자 지정 서식 문자열의 전체 목록은 사용자 지정 날짜 및 시간 서식 문자열사용자 지정 숫자 형식 문자열을 참조하세요.

형식 문자열이 단일 사용자 지정 형식 지정자로 구성된 경우에는 표준 형식 지정자와 혼동되지 않도록 형식 지정자 앞에 백분율 기호(%)가 와야 합니다. 다음 예제에서는 "M" 사용자 지정 형식 지정자를 사용하여 특정 날짜의 월에 해당하는 한 자리 또는 두 자리 숫자를 표시합니다.

DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M"));       // Displays 9
Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M"))      ' Displays 9

많은 표준 형식 문자열은 DateTimeFormatInfo 개체의 속성에 정의된 사용자 지정 형식 문자열의 별칭입니다. 또한 사용자 지정 형식 문자열을 사용하면 상당히 융통성 있게 숫자 값 또는 날짜 및 시간 값에 대한 애플리케이션 정의 형식 지정 기능을 제공할 수 있습니다. 여러 사용자 지정 형식 지정자를 하나의 사용자 지정 형식 문자열로 결합하여 숫자 값과 날짜 및 시간 값에 대한 사용자 지정 결과 문자열을 정의할 수 있습니다. 다음 예제에서는 월 이름, 일, 연도 및 괄호로 묶은 요일을 차례로 표시하는 사용자 지정 형식 문자열을 정의합니다.

string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));
// The example displays the following output if run on a system
// whose language is English:
//       August 28, 2009 (Friday)
Dim customFormat As String = "MMMM dd, yyyy (dddd)"
Dim date1 As Date = #8/28/2009#
Console.WriteLine(date1.ToString(customFormat))
' The example displays the following output if run on a system
' whose language is English:
'       August 28, 2009 (Friday)      

다음 예제에서는 Int64 값을 7자리 표준 미국 전화 번호로 지역 번호와 함께 표시하는 사용자 지정 서식 문자열을 정의합니다.

using System;

public class Example17
{
   public static void Main()
   {
      long number = 8009999999;
      string fmt = "000-000-0000";
      Console.WriteLine(number.ToString(fmt));
   }
}
// The example displays the following output:
//        800-999-9999
Module Example18
    Public Sub Main18()
        Dim number As Long = 8009999999
        Dim fmt As String = "000-000-0000"
        Console.WriteLine(number.ToString(fmt))
    End Sub
End Module
' The example displays the following output:

' The example displays the following output:
'       800-999-9999

일반적으로 표준 형식 문자열로 애플리케이션 정의 형식의 형식 지정 요구를 대부분 처리할 수 있지만 사용자 지정 형식 지정자를 정의하여 형식의 형식을 지정할 수도 있습니다.

서식 문자열 및 .NET 형식

모든 숫자 형식(즉, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32,UInt64BigInteger 형식)과 DateTime, DateTimeOffset, TimeSpan, Guid 및 모든 열거형 형식은 서식 문자열을 사용한 서식 지정을 지원합니다. 각 형식에서 지원되는 형식 문자열에 대한 자세한 내용은 다음 항목을 참조하세요.

타이틀 정의
표준 숫자 형식 문자열 숫자 값의 일반적으로 사용되는 문자열 표현을 만드는 표준 형식 문자열에 대해 설명합니다.
사용자 지정 숫자 형식 문자열 숫자 값의 애플리케이션별 형식을 만드는 사용자 지정 형식 문자열에 대해 설명합니다.
표준 날짜 및 시간 형식 문자열 DateTimeDateTimeOffset 값의 일반적으로 사용되는 문자열 표현을 만드는 표준 서식 문자열에 대해 설명합니다.
사용자 지정 날짜 및 시간 형식 문자열 DateTimeDateTimeOffset 값의 애플리케이션별 서식을 만드는 사용자 지정 서식 문자열에 대해 설명합니다.
표준 TimeSpan 서식 문자열 시간 간격의 일반적으로 사용되는 문자열 표현을 만드는 표준 형식 문자열에 대해 설명합니다.
사용자 지정 TimeSpan 서식 문자열 시간 간격의 애플리케이션별 형식을 만드는 사용자 지정 형식 문자열에 대해 설명합니다.
Enumeration Format Strings 열거형 값의 문자열 표현을 만드는 데 사용되는 표준 형식 문자열에 대해 설명합니다.
Guid.ToString(String) Guid 값에 대한 표준 형식 문자열에 대해 설명합니다.

형식 공급자를 사용한 문화권 구분 형식 지정

형식 지정자를 사용하여 개체의 형식 지정을 사용자 지정할 수 있기는 하지만 의미 있는 개체의 문자열 표현을 만들려면 추가 형식 지정 정보가 필요한 경우가 종종 있습니다. 예를 들어, C" 표준 형식 문자열이나 "$ #,#.00" 같은 사용자 지정 형식 문자열을 사용하여 숫자의 형식을 통화 값으로 지정하려면 최소한 올바른 통화 기호, 그룹 구분 기호 및 소수 구분 기호에 대한 정보를 형식 지정된 문자열에 포함할 수 있어야 합니다. .NET에서는 이러한 추가 서식 지정 정보를 IFormatProvider 인터페이스를 통해 사용할 수 있습니다. 이러한 인터페이스는 숫자 형식과 날짜 및 시간 형식의 ToString 메서드에 대한 하나 이상의 오버로드에 매개 변수로 제공됩니다. IFormatProvider 구현은 .NET에서 문화권별 서식 지정을 지원하는 데 사용됩니다. 다음 예제에서는 서로 다른 문화권을 나타내는 세 IFormatProvider 개체를 사용하여 형식을 지정할 때 개체의 문자열 표현이 어떻게 바뀌는지 보여 줍니다.

using System;
using System.Globalization;

public class Example18
{
   public static void Main()
   {
      decimal value = 1603.42m;
      Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
   }
}
// The example displays the following output:
//       $1,603.420
//       1 603,420 €
//       1.603,420 €
Imports System.Globalization

Public Module Example11
    Public Sub Main11()
        Dim value As Decimal = 1603.42D
        Console.WriteLine(value.ToString("C3", New CultureInfo("en-US")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("fr-FR")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("de-DE")))
    End Sub
End Module
' The example displays the following output:
'       $1,603.420
'       1 603,420 €
'       1.603,420 €

IFormatProvider 인터페이스에는 GetFormat(Type)메서드가 하나 있으며, 이 메서드에는 형식 지정 정보를 제공하는 개체의 형식을 지정하는 매개 변수가 하나 있습니다. 이 메서드는 해당 형식의 개체를 제공할 수 있는 경우 해당 형식의 개체를 반환합니다. 그러지 않으면 null 참조(Visual Basic의 경우Nothing )를 반환합니다.

IFormatProvider.GetFormat 은 콜백 메서드입니다. ToString 매개 변수가 포함된 IFormatProvider 메서드 오버로드를 호출하면 해당 GetFormat 개체의 IFormatProvider 메서드가 호출됩니다. GetFormat 메서드는 formatType 매개 변수에 지정된 대로 필요한 형식 지정 정보를 제공하는 개체를 ToString 메서드에 반환합니다.

IFormatProvider형식의 매개 변수를 포함하는 형식 지정 또는 문자열 변환 메서드가 많이 있기는 하지만 대부분의 경우 메서드가 호출될 때 매개 변수의 값이 무시됩니다. 다음 표에서는 매개 변수를 사용하는 형식 지정 메서드와 이러한 메서드가 Type 메서드로 전달하는 IFormatProvider.GetFormat 개체의 형식을 보여 줍니다.

메서드 formatType 매개 변수의 형식
숫자 형식의 ToString 메서드 System.Globalization.NumberFormatInfo
날짜 및 시간 형식의 ToString 메서드 System.Globalization.DateTimeFormatInfo
String.Format System.ICustomFormatter
StringBuilder.AppendFormat System.ICustomFormatter

참고 항목

숫자 형식과 날짜 및 시간 형식의 ToString 메서드는 오버로드되며, 일부 오버로드에만 IFormatProvider 매개 변수가 포함됩니다. 메서드에 IFormatProvider형식의 매개 변수가 없으면 CultureInfo.CurrentCulture 속성에 의해 반환되는 개체가 대신 전달됩니다. 예를 들어, 기본 Int32.ToString() 메서드를 호출하면 결과적으로 Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)같은 메서드가 호출됩니다.

.NET에는 IFormatProvider를 구현하는 세 가지 클래스가 있습니다.

사용자 고유의 형식 공급자를 구현하여 이러한 클래스 중 하나를 대체할 수도 있습니다. 그러나 ToString 메서드에 형식 지정 정보를 제공해야 하는 경우에는 구현된 형식 공급자의 GetFormat 메서드에서 위의 표에 나와 있는 형식의 개체를 반환해야 합니다.

숫자 값의 문화권 구분 서식 지정

기본적으로 숫자 값의 형식은 문화권을 구분합니다. 형식 지정 메서드를 호출할 때 문화권을 지정하지 않으면 현재 문화권의 형식 규칙이 사용됩니다. 이는 현재 문화권을 4번 변경한 후 Decimal.ToString(String) 메서드를 호출하는 다음 예제에 나와 있습니다. 각각의 경우 결과 문자열은 현재 문화권의 형식 규칙을 반영합니다. 이는 ToStringToString(String) 메서드가 각 숫자 형식의 ToString(String, IFormatProvider) 메서드에 대한 호출을 래핑하기 때문입니다.

using System.Globalization;

public class Example6
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      Decimal value = 1043.17m;

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(value.ToString("C2"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       $1,043.17
//
//       The current culture is fr-FR
//       1 043,17 €
//
//       The current culture is es-MX
//       $1,043.17
//
//       The current culture is de-DE
//       1.043,17 €
Imports System.Globalization

Module Example6
    Public Sub Main6()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim value As Decimal = 1043.17D

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(value.ToString("C2"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       $1,043.17
'       
'       The current culture is fr-FR
'       1 043,17 €
'       
'       The current culture is es-MX
'       $1,043.17
'       
'       The current culture is de-DE
'       1.043,17 €

ToString 매개 변수를 포함하는 provider 오버로드를 호출하고 여기에 다음 중 하나를 전달하여 특정 문화권에 대한 숫자 값의 형식을 지정할 수도 있습니다.

다음 예제에서는 부동 소수점 수의 형식을 지정하기 위해 영어(미국) 및 영어(영국) 문화권과 프랑스어 및 러시아어 중립 문화권을 나타내는 NumberFormatInfo 개체를 사용합니다.

using System.Globalization;

public class Example7
{
    public static void Main()
    {
        double value = 1043.62957;
        string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

        foreach (string? name in cultureNames)
        {
            NumberFormatInfo nfi = CultureInfo.CreateSpecificCulture(name).NumberFormat;
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi));
        }
    }
}
// The example displays the following output:
//       en-US: 1,043.630
//       en-GB: 1,043.630
//       ru:    1 043,630
//       fr:    1 043,630
Imports System.Globalization

Module Example7
    Public Sub Main7()
        Dim value As Double = 1043.62957
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim nfi As NumberFormatInfo = CultureInfo.CreateSpecificCulture(name).NumberFormat
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi))
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 1,043.630
'       en-GB: 1,043.630
'       ru:    1 043,630
'       fr:    1 043,630

날짜 및 시간 값의 문화권 구분 서식 지정

기본적으로 날짜 및 시간 값의 형식은 문화권을 구분합니다. 형식 지정 메서드를 호출할 때 문화권을 지정하지 않으면 현재 문화권의 형식 규칙이 사용됩니다. 이는 현재 문화권을 4번 변경한 후 DateTime.ToString(String) 메서드를 호출하는 다음 예제에 나와 있습니다. 각각의 경우 결과 문자열은 현재 문화권의 형식 규칙을 반영합니다. 이는 DateTime.ToString(), DateTime.ToString(String), DateTimeOffset.ToString()DateTimeOffset.ToString(String) 메서드가 DateTime.ToString(String, IFormatProvider)DateTimeOffset.ToString(String, IFormatProvider) 메서드에 대한 호출을 래핑하기 때문입니다.

using System.Globalization;

public class Example4
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      DateTime dateToFormat = new DateTime(2012, 5, 28, 11, 30, 0);

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(dateToFormat.ToString("F"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       Monday, May 28, 2012 11:30:00 AM
//
//       The current culture is fr-FR
//       lundi 28 mai 2012 11:30:00
//
//       The current culture is es-MX
//       lunes, 28 de mayo de 2012 11:30:00 a.m.
//
//       The current culture is de-DE
//       Montag, 28. Mai 2012 11:30:00
Imports System.Globalization
Imports System.Threading

Module Example4
    Public Sub Main4()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim dateToFormat As Date = #5/28/2012 11:30AM#

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(dateToFormat.ToString("F"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       Monday, May 28, 2012 11:30:00 AM
'       
'       The current culture is fr-FR
'       lundi 28 mai 2012 11:30:00
'       
'       The current culture is es-MX
'       lunes, 28 de mayo de 2012 11:30:00 a.m.
'       
'       The current culture is de-DE
'       Montag, 28. Mai 2012 11:30:00 

DateTime.ToString 매개 변수를 포함하는 DateTimeOffset.ToString 또는 provider 오버로드를 호출하고 여기에 다음 중 하나를 전달하여 특정 문화권에 대한 날짜 및 시간 값의 형식을 지정할 수도 있습니다.

다음 예에서는 영어(미국) 및 영어(영국) 문화권과 프랑스어 및 러시아어 중립 문화권을 나타내는 DateTimeFormatInfo 개체를 사용하여 날짜 형식을 지정합니다.

using System.Globalization;

public class Example5
{
   public static void Main()
   {
      DateTime dat1 = new(2012, 5, 28, 11, 30, 0);
      string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

      foreach (var name in cultureNames) {
         DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture(name).DateTimeFormat;
         Console.WriteLine($"{name}: {dat1.ToString(dtfi)}");
      }
   }
}
// The example displays the following output:
//       en-US: 5/28/2012 11:30:00 AM
//       en-GB: 28/05/2012 11:30:00
//       ru: 28.05.2012 11:30:00
//       fr: 28/05/2012 11:30:00
Imports System.Globalization

Module Example5
    Public Sub Main5()
        Dim dat1 As Date = #5/28/2012 11:30AM#
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim dtfi As DateTimeFormatInfo = CultureInfo.CreateSpecificCulture(name).DateTimeFormat
            Console.WriteLine($"{name}: {dat1.ToString(dtfi)}")
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 5/28/2012 11:30:00 AM
'       en-GB: 28/05/2012 11:30:00
'       ru: 28.05.2012 11:30:00
'       fr: 28/05/2012 11:30:00

IFormattable 인터페이스

일반적으로 형식 문자열과 ToString 매개 변수로 IFormatProvider 메서드를 오버로드하는 형식은 IFormattable 인터페이스도 구현합니다. 이 인터페이스에는 형식 문자열과 형식 공급자가 매개 변수로 포함되어 있는 IFormattable.ToString(String, IFormatProvider)이라는 단일 멤버가 있습니다.

애플리케이션 정의 클래스에 대해 IFormattable 인터페이스를 구현하면 다음과 같은 두 가지 이점이 있습니다.

다음 예제에서는 Temperature 인터페이스를 구현하는 IFormattable 클래스를 정의합니다. 이 클래스는 온도를 섭씨로 표시하는 "C" 또는 "G" 형식 지정자, 온도를 화씨로 표시하는 "F" 형식 지정자 또는 온도를 켈빈으로 표시하는 "K" 형식 지정자를 지원합니다.

using System;
using System.Globalization;

namespace HotAndCold
{

    public class Temperature : IFormattable
    {
        private decimal m_Temp;

        public Temperature(decimal temperature)
        {
            this.m_Temp = temperature;
        }

        public decimal Celsius
        {
            get { return this.m_Temp; }
        }

        public decimal Kelvin
        {
            get { return this.m_Temp + 273.15m; }
        }

        public decimal Fahrenheit
        {
            get { return Math.Round((decimal)this.m_Temp * 9 / 5 + 32, 2); }
        }

        public override string ToString()
        {
            return this.ToString("G", null);
        }

        public string ToString(string format)
        {
            return this.ToString(format, null);
        }

        public string ToString(string format, IFormatProvider provider)
        {
            // Handle null or empty arguments.
            if (String.IsNullOrEmpty(format))
                format = "G";
            // Remove any white space and covert to uppercase.
            format = format.Trim().ToUpperInvariant();

            if (provider == null)
                provider = NumberFormatInfo.CurrentInfo;

            switch (format)
            {
                // Convert temperature to Fahrenheit and return string.
                case "F":
                    return this.Fahrenheit.ToString("N2", provider) + "°F";
                // Convert temperature to Kelvin and return string.
                case "K":
                    return this.Kelvin.ToString("N2", provider) + "K";
                // Return temperature in Celsius.
                case "C":
                case "G":
                    return this.Celsius.ToString("N2", provider) + "°C";
                default:
                    throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
            }
        }
    }
Public Class Temperature : Implements IFormattable
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("G", Nothing)
    End Function

    Public Overloads Function ToString(format As String) As String
        Return Me.ToString(format, Nothing)
    End Function

    Public Overloads Function ToString(format As String, provider As IFormatProvider) As String _
       Implements IFormattable.ToString

        ' Handle null or empty arguments.
        If String.IsNullOrEmpty(format) Then format = "G"
        ' Remove any white space and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        If provider Is Nothing Then provider = NumberFormatInfo.CurrentInfo

        Select Case format
     ' Convert temperature to Fahrenheit and return string.
            Case "F"
                Return Me.Fahrenheit.ToString("N2", provider) & "°F"
     ' Convert temperature to Kelvin and return string.
            Case "K"
                Return Me.Kelvin.ToString("N2", provider) & "K"
     ' Return temperature in Celsius.
            Case "C", "G"
                Return Me.Celsius.ToString("N2", provider) & "°C"
            Case Else
                Throw New FormatException(String.Format($"The '{format}' format string is not supported."))
        End Select
    End Function
End Class

다음 예제에서는 Temperature 개체를 인스턴스화합니다. 그런 다음 ToString 메서드를 호출하고 여러 복합 형식 문자열을 사용하여 Temperature 개체의 다양한 문자열 표현을 얻습니다. 이 메서드를 호출할 때마다 자동으로 IFormattable 클래스의 Temperature 구현도 호출됩니다.

public class Example11
{
    public static void Main()
    {
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
        Temperature temp = new Temperature(22m);
        Console.WriteLine(Convert.ToString(temp, new CultureInfo("ja-JP")));
        Console.WriteLine("Temperature: {0:K}", temp);
        Console.WriteLine("Temperature: {0:F}", temp);
        Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp));
    }
}
// The example displays the following output:
//       22.00°C
//       Temperature: 295.15K
//       Temperature: 71.60°F
//       Temperature: 71,60°F
Public Module Example12
    Public Sub Main12()
        Dim temp As New Temperature(22D)
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US")
        Console.WriteLine(Convert.ToString(temp, New CultureInfo("ja-JP")))
        Console.WriteLine($"Temperature: {temp:K}")
        Console.WriteLine($"Temperature: {temp:F}")
        Console.WriteLine(String.Format(New CultureInfo("fr-FR"), $"Temperature: {temp:F}"))
    End Sub
End Module
' The example displays the following output:
'       22.00°C
'       Temperature: 295.15K
'       Temperature: 71.60°F
'       Temperature: 71,60°F

복합 형식 지정

String.FormatStringBuilder.AppendFormat 같은 일부 메서드는 복합 형식 지정을 지원합니다. 복합 형식 문자열은 0개 이상의 개체에 대한 문자열 표현이 통합된 단일 문자열을 반환하는 일종의 템플릿입니다. 복합 형식 문자열에서는 각 개체가 인덱싱된 형식 항목으로 표현됩니다. 형식 항목의 인덱스는 메서드의 매개 변수 목록에 표시되는 개체의 위치에 해당합니다. 인덱스는 0에서 시작합니다. 예를 들어 다음과 같은 String.Format 메서드 호출에서 첫 번째 형식 항목인 {0:D}thatDate의 문자열 표현으로 바뀌고, 두 번째 형식 항목인 {1}item1의 문자열 표현으로 바뀌고, 세 번째 형식 항목인 {2:C2}item1.Value의 문자열 표현으로 바뀝니다.

result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value);
Console.WriteLine(result);
// The example displays output like the following if run on a system
// whose current culture is en-US:
//       On 5/1/2009, the inventory of WidgetA was worth $107.44.
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value)
Console.WriteLine(result)
' The example displays output like the following if run on a system
' whose current culture is en-US:
'       On 5/1/2009, the inventory of WidgetA was worth $107.44.

형식 항목을 해당 개체의 문자열 표현으로 바꾸는 것 외에도 형식 항목을 통해 다음을 제어할 수 있습니다.

  • 개체가 IFormattable 인터페이스를 구현하고 형식 문자열을 지원하는 경우 개체가 문자열로 표현되는 특정 방식. 이렇게 하려면 형식 항목의 인덱스 뒤에 : (콜론) 및 유효한 형식 문자열을 추가합니다. 이전 예제에서는 날짜 값의 형식을 "d"(짧은 날짜 패턴) 형식 문자열(예: {0:d})로 지정하고 숫자 값의 형식을 "C2" 형식 문자열(예: {2:C2} )로 지정하여 소수 2자리의 통화 값으로 숫자를 나타냈습니다.

  • 개체의 문자열 표현을 포함하는 필드의 너비 및 해당 필드의 문자열 표현 맞춤. 이렇게 하려면 형식 항목의 인덱스 뒤에 , (쉼표) 및 필드 너비를 추가합니다. 필드 너비가 양수 값이면 문자열이 필드에 오른쪽 맞춤되고, 필드 너비가 음수 값이면 왼쪽 맞춤됩니다. 다음 예제에서는 날짜 값을 20자 필드에 왼쪽 맞춤하고, 소수 1자리의 10진수 값을 11자 필드에 오른쪽 맞춤합니다.

    DateTime startDate = new DateTime(2015, 8, 28, 6, 0, 0);
    decimal[] temps = { 73.452m, 68.98m, 72.6m, 69.24563m,
                       74.1m, 72.156m, 72.228m };
    Console.WriteLine("{0,-20} {1,11}\n", "Date", "Temperature");
    for (int ctr = 0; ctr < temps.Length; ctr++)
       Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps[ctr]);
    
    // The example displays the following output:
    //       Date                 Temperature
    //
    //       8/28/2015 6:00 AM           73.5
    //       8/29/2015 6:00 AM           69.0
    //       8/30/2015 6:00 AM           72.6
    //       8/31/2015 6:00 AM           69.2
    //       9/1/2015 6:00 AM            74.1
    //       9/2/2015 6:00 AM            72.2
    //       9/3/2015 6:00 AM            72.2
    
    Dim startDate As New Date(2015, 8, 28, 6, 0, 0)
    Dim temps() As Decimal = {73.452, 68.98, 72.6, 69.24563,
                               74.1, 72.156, 72.228}
    Console.WriteLine("{0,-20} {1,11}", "Date", "Temperature")
    Console.WriteLine()
    For ctr As Integer = 0 To temps.Length - 1
        Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps(ctr))
    Next
    ' The example displays the following output:
    '       Date                 Temperature
    '
    '       8/28/2015 6:00 AM           73.5
    '       8/29/2015 6:00 AM           69.0
    '       8/30/2015 6:00 AM           72.6
    '       8/31/2015 6:00 AM           69.2
    '       9/1/2015 6:00 AM            74.1
    '       9/2/2015 6:00 AM            72.2
    '       9/3/2015 6:00 AM            72.2
    

    맞춤 문자열 구성 요소와 형식 문자열 구성 요소가 둘 다 있는 경우 맞춤 문자열 구성 요소가 우선합니다(예: {0,-20:g}).

복합 서식 지정에 대한 자세한 내용은 Composite Formatting을 참조하세요.

ICustomFormatter를 사용한 사용자 지정 서식 지정

두 복합 형식 지정 메서드( String.Format(IFormatProvider, String, Object[])StringBuilder.AppendFormat(IFormatProvider, String, Object[]))에 사용자 지정 형식을 지원하는 형식 공급자 매개 변수가 포함되어 있습니다. 이러한 형식 지정 메서드 중 하나를 호출하면 ICustomFormatter 인터페이스를 나타내는 Type 개체가 형식 공급자의 GetFormat 메서드에 전달됩니다. 그러면 GetFormat 메서드가 사용자 지정 형식 지정을 제공하는 ICustomFormatter 구현을 반환합니다.

ICustomFormatter 인터페이스에는 복합 형식 지정 메서드에 의해 자동으로 복합 형식 문자열의 각 형식 항목에 대해 한 번씩 호출되는 Format(String, Object, IFormatProvider)라는 메서드가 하나 있습니다. Format(String, Object, IFormatProvider) 메서드에는 세 개의 매개 변수 즉, 형식 항목의 formatString 인수를 나타내는 형식 문자열, 형식을 지정할 개체 및 형식 지정 서비스를 제공하는 IFormatProvider 개체가 포함되어 있습니다. 일반적으로 ICustomFormatter 를 구현하는 클래스는 IFormatProvider도 구현하여 이 마지막 매개 변수가 사용자 지정 형식 지정 클래스를 참조하도록 합니다. 이 메서드는 형식을 지정할 개체의 사용자 지정 형식 문자열 표현을 반환합니다. 이 메서드가 개체의 형식을 지정할 수 없는 경우에는 null 참조(Visual Basic의 경우Nothing )가 반환되어야 합니다.

다음 예제에서는 정수 값을 뒤에 공백이 오는 두 자리 16진수 값 시퀀스로 표시하는 ICustomFormatter 라는 ByteByByteFormatter 구현을 제공합니다.

public class ByteByByteFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(string format, object arg,
                          IFormatProvider formatProvider)
   {
      if (! formatProvider.Equals(this)) return null;

      // Handle only hexadecimal format string.
      if (! format.StartsWith("X")) return null;

      byte[] bytes;
      string output = null;

      // Handle only integral types.
      if (arg is Byte)
         bytes = BitConverter.GetBytes((Byte) arg);
      else if (arg is Int16)
         bytes = BitConverter.GetBytes((Int16) arg);
      else if (arg is Int32)
         bytes = BitConverter.GetBytes((Int32) arg);
      else if (arg is Int64)
         bytes = BitConverter.GetBytes((Int64) arg);
      else if (arg is SByte)
         bytes = BitConverter.GetBytes((SByte) arg);
      else if (arg is UInt16)
         bytes = BitConverter.GetBytes((UInt16) arg);
      else if (arg is UInt32)
         bytes = BitConverter.GetBytes((UInt32) arg);
      else if (arg is UInt64)
         bytes = BitConverter.GetBytes((UInt64) arg);
      else
         return null;

      for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
         output += String.Format("{0:X2} ", bytes[ctr]);

      return output.Trim();
   }
}
Public Class ByteByByteFormatter : Implements IFormatProvider, ICustomFormatter
    Public Function GetFormat(formatType As Type) As Object _
                    Implements IFormatProvider.GetFormat
        If formatType Is GetType(ICustomFormatter) Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

    Public Function Format(fmt As String, arg As Object,
                           formatProvider As IFormatProvider) As String _
                           Implements ICustomFormatter.Format

        If Not formatProvider.Equals(Me) Then Return Nothing

        ' Handle only hexadecimal format string.
        If Not fmt.StartsWith("X") Then
            Return Nothing
        End If

        ' Handle only integral types.
        If Not typeof arg Is Byte AndAlso
           Not typeof arg Is Int16 AndAlso
           Not typeof arg Is Int32 AndAlso
           Not typeof arg Is Int64 AndAlso
           Not typeof arg Is SByte AndAlso
           Not typeof arg Is UInt16 AndAlso
           Not typeof arg Is UInt32 AndAlso
           Not typeof arg Is UInt64 Then _
              Return Nothing

        Dim bytes() As Byte = BitConverter.GetBytes(arg)
        Dim output As String = Nothing

        For ctr As Integer = bytes.Length - 1 To 0 Step -1
            output += String.Format("{0:X2} ", bytes(ctr))
        Next

        Return output.Trim()
    End Function
End Class

다음 예제에서는 ByteByByteFormatter 클래스를 사용하여 정수 값의 형식을 지정합니다. ICustomFormatter.Format 메서드는 두 번째 String.Format(IFormatProvider, String, Object[]) 메서드 호출에서 두 번 이상 호출되고 세 번째 메서드 호출에서는 기본 NumberFormatInfo 공급자가 사용된다는 점에 유의하세요. 그 이유는 .ByteByByteFormatter.Format 메서드는 "N0" 형식 문자열을 인식하지 못하고 null 참조(Visual Basic의 경우 Nothing)를 반환하기 때문입니다.

public class Example10
{
   public static void Main()
   {
      long value = 3210662321;
      byte value1 = 214;
      byte value2 = 19;

      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                      value1, value2, value1 & value2));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
   }
}
// The example displays the following output:
//       00 00 00 00 BF 5E D1 B1
//       00 D6 And 00 13 = 00 12 (018)
//       3,210,662,321
Public Module Example10
    Public Sub Main10()
        Dim value As Long = 3210662321
        Dim value1 As Byte = 214
        Dim value2 As Byte = 19

        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X}", value)))
        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                        value1, value2, value1 And value2)))
        Console.WriteLine(String.Format(New ByteByByteFormatter(), "{0,10:N0}", value))
    End Sub
End Module
' The example displays the following output:
'       00 00 00 00 BF 5E D1 B1
'       00 D6 And 00 13 = 00 12 (018)
'       3,210,662,321

참고 항목

제목 정의
표준 숫자 형식 문자열 숫자 값의 일반적으로 사용되는 문자열 표현을 만드는 표준 형식 문자열에 대해 설명합니다.
사용자 지정 숫자 형식 문자열 숫자 값의 애플리케이션별 형식을 만드는 사용자 지정 형식 문자열에 대해 설명합니다.
표준 날짜 및 시간 형식 문자열 DateTime 값의 일반적으로 사용되는 문자열 표현을 만드는 표준 형식 문자열에 대해 설명합니다.
사용자 지정 날짜 및 시간 형식 문자열 DateTime 값의 애플리케이션별 형식을 만드는 사용자 지정 형식 문자열에 대해 설명합니다.
표준 TimeSpan 서식 문자열 시간 간격의 일반적으로 사용되는 문자열 표현을 만드는 표준 형식 문자열에 대해 설명합니다.
사용자 지정 TimeSpan 서식 문자열 시간 간격의 애플리케이션별 형식을 만드는 사용자 지정 형식 문자열에 대해 설명합니다.
Enumeration Format Strings 열거형 값의 문자열 표현을 만드는 데 사용되는 표준 형식 문자열에 대해 설명합니다.
복합 형식 지정 문자열에 형식이 지정된 하나 이상의 값을 포함시키는 방법에 대해 설명합니다. 그런 후 해당 문자열을 콘솔에 표시하거나 스트림에 쓸 수 있습니다.
.NET에서 문자열 구문 분석 개체를 해당 개체의 문자열 표현으로 표시되는 값으로 초기화하는 방법에 대해 설명합니다. 구문 분석은 형식 지정의 역순으로 진행됩니다.

참조