2010-09-16T23:08:54の更新内容

programming/netfx2/string_formatting/index.wiki.txt

current previous
1,868 0,0
+
${smdncms:title,書式と文字列化}
+
${smdncms:keywords,書式指定子,フォーマット,右詰め,左詰め,文字列化,String,Format,ToString,IFormatProvider,ICustomFormatter,IFormattable}
+
.NET Frameworkの書式指定子とフォーマット例、関連するクラス等について。
+

          
+
*書式指定子の概要
+
基本型のToString()、&msdn(netfx,method,System.Console.WriteLine){Console.WriteLine()};、&msdn(netfx,method,System.String.Format){String.Format()};などのメソッドで値を文字列化する際に、値の書式を指定することができる。 .NET Frameworkでは書式指定子として定義されている。
+
#code(cs,数値に書式を指定した例){{
+
double doubleValue = 3.1416;
+

          
+
Console.WriteLine(doubleValue.ToString());
+
Console.WriteLine(doubleValue.ToString("N2"));
+
Console.WriteLine(doubleValue.ToString("###.000000"));
+
}}
+

          
+
#prompt{{
+
3.1416
+
3.14
+
3.141600
+
}}
+

          
+
#code(cs,DateTime型に書式を指定する例){{
+
DateTime dateTimeValue = new DateTime(2010, 9, 14, 1, 2, 3);
+

          
+
Console.WriteLine(dateTimeValue.ToString());
+
Console.WriteLine(dateTimeValue.ToString("r"));
+
Console.WriteLine(dateTimeValue.ToString("s"));
+
Console.WriteLine(dateTimeValue.ToString("yyyy/MM/dd (dddd) hh:mm:ss"));
+
}}
+

          
+
#prompt{{
+
2010/09/14 1:02:03
+
Tue, 14 Sep 2010 01:02:03 GMT
+
2010-09-14T01:02:03
+
2010/09/14 (火曜日) 01:02:03
+
}}
+

          
+
String.Format()メソッド、Console.WriteLine()メソッドでは、引数に適用する書式を個々に指定して文字列化することができる。
+

          
+
#code(cs){{
+
DateTime dateTimeValue = new DateTime(2010, 9, 14, 1, 2, 3);
+
double doubleValue = 3.1416;
+
int intValue = 72;
+

          
+
Console.WriteLine("{0:hh:ss} {1:N2} {2:D4}", dateTimeValue, doubleValue, intValue);
+

          
+
string formatted = string.Format("{0:hh:ss} {1:N2} {2:D4}", dateTimeValue, doubleValue, intValue);
+

          
+
Console.WriteLine(formatted);
+
}}
+

          
+
#prompt{{
+
01:03 3.14 0072
+
01:03 3.14 0072
+
}}
+

          
+
**複合書式設定と0埋め・右揃え・左揃え
+
複合書式設定を用いることで、0埋め(ゼロパディング)、右詰め(右揃え)・左詰め(左揃え)することができる。 (MSDN: &msdn(netfx,id,txafckwd){複合書式設定};)
+

          
+
複合書式設定の形式は次のようになっている。
+
 {index[,alignment][:formatString]}
+
:index|書式を適用する引数のインデックス
+
:alignment|文字列化する際の幅(桁数) 文字列の長さが指定した幅より大きい場合は無視される(切り詰めない)
+
::幅が正の場合|指定した幅で右揃えにする
+
::幅が負の場合|指定した幅で左揃えにする
+
:formatString|文字列化する際の書式
+

          
+
indexは必須、alignmentとformatStringは省略可能で組み合わせて指定することができる。 0埋めの際の書式(D6など)については後述。
+

          
+
#code(cs,複合書式の例){{
+
Console.WriteLine("|0123456789|");        // (桁取り)
+
Console.WriteLine("|{0,10}|", 72);        // 数値を幅10で右揃え
+
Console.WriteLine("|{0,-10}|", 42);       // 数値を幅10で左揃え
+
Console.WriteLine("|{0,10}|", "foo");     // 文字列を幅10で右揃え
+
Console.WriteLine("|{0,-10}|", "bar");    // 文字列を幅10で左揃え
+
Console.WriteLine("|{0,3}|", 16);         // 2桁の数値を幅3で右揃え
+
Console.WriteLine("|{0,3}|", 12345);      // 5桁の数値を幅3で右揃え
+
Console.WriteLine("|{0:D6}|", 16);        // 2桁の数値を0埋めして6桁に
+
Console.WriteLine("|{0:D6}|", 12345);     // 5桁の数値を0埋めして6桁に
+
Console.WriteLine("|{0,10:D6}|", 16);     // 2桁の数値を0埋めして6桁にし、幅10で右揃え
+
Console.WriteLine("|{0,-10:D6}|", 12345); // 5桁の数値を0埋めして6桁にし、幅10で左揃え
+
}}
+

          
+
#prompt{{
+
|0123456789|
+
|        72|
+
|42        |
+
|       foo|
+
|bar       |
+
| 16|
+
|12345|
+
|000016|
+
|012345|
+
|    000016|
+
|012345    |
+
}}
+

          
+
#code(cs,複数の引数に対する複合書式の例){{
+
// 0番目の引数を0埋めして3桁に
+
// 1番目の引数を幅5で左詰め
+
// 2番目の引数を0埋めして3桁にし、幅5で右詰め
+
Console.WriteLine("|{0:D3}/{1,-5}/{2,5:D3}|", 72, 16, 42);
+
}}
+

          
+
#prompt{{
+
|072/16   /  042|
+
}}
+

          
+
中括弧そのものを出力したい場合は、"{{"や"}}"のように二つ重ねることでエスケープされ、"{"と"}"が出力される。
+

          
+
#code(cs){{
+
Console.WriteLine("{0}}}", 72);
+
Console.WriteLine("{{{0}", 16);
+
Console.WriteLine("{{0:D6}}", 42);
+
Console.WriteLine("{{{0:D6}}}", 42);
+
}}
+

          
+
#prompt{{
+
72}
+
{16
+
{0:D6}
+
{000042}
+
}}
+

          
+
*標準の書式指定文字列
+
標準の書式指定子とはあらかじめ定義された書式を'D', 'N', 'r'などの文字で表すもので、書式指定子と桁数などの数値と組み合わせた書式指定文字列を指定することでさまざまな形式にフォーマットすることができる。
+

          
+
#code(cs,整数・日時と書式指定文字列の例){{
+
int intValue = 72;
+

          
+
Console.WriteLine("{0:D}   {0:D4}   {0:N4}", intValue);
+

          
+
DateTime dateTimeValue = new DateTime(2010, 9, 14, 1, 2, 3);
+

          
+
Console.WriteLine("{0}   {0:r}   {0:s}", dateTimeValue);
+
}}
+

          
+
#prompt{{
+
72   0072   72.0000
+
2010/09/14 1:02:03   Tue, 14 Sep 2010 01:02:03 GMT   2010-09-14T01:02:03
+
}}
+

          
+
**数値の書式指定子
+
以下の書式指定子は数値型の値に対して指定できる。 (MSDN: &msdn(netfx,id,dwhawy9k){標準の数値書式指定文字列};)
+

          
+
***整数のみに指定できる書式指定子
+
以下の書式指定子はint, long, byteなどの整数型の値に対して指定できる。
+

          
+
:D, d (decimal/10進数)|数値を10進形式で表した文字列でフォーマットする。
+
桁数が指定されている場合は、指定された桁数で0埋めされる。
+
|*書式指定子"D", "d"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(72).ToString("D")|"72"|
+
|(72).ToString("D1")|"72"|
+
|(72).ToString("D4")|"0072"|
+
|(72).ToString("d4")|"0072"|
+
|(-72).ToString("D")|"-72"|
+
|(-72)72.ToString("D4")|"-0072"|
+
:X, x (hexadecimal/16進数)|数値を16進形式で表した文字列でフォーマットする。
+
桁数が指定されている場合は、指定された桁数で0埋めされる。
+
|*書式指定子"X"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(42).ToString("X")|"2A"|
+
|(42).ToString("X1")|"2A"|
+
|(42).ToString("X4")|"002A"|
+
|(-42).ToString("X")|"FFFFFFD6"|
+
|(-42).ToString("X12")|"0000FFFFFFD6"|
+
小文字の"x"を指定した場合は、A-Fの代わりに小文字のa-fを使ってフォーマットされる。
+
|*書式指定子"x"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(42).ToString("x")|"2a"|
+
|(42).ToString("x1")|"2a"|
+
|(42).ToString("x4")|"002a"|
+
|(-42).ToString("x")|"ffffffd6"|
+
|(-42).ToString("x12")|"0000ffffffd6"|
+

          
+
***整数および実数に指定できる書式指定子
+
以下の書式指定子はint, double, decimalなどの整数型・実数型の値のどちらに対しても指定できる。
+

          
+
:F, f (fixed-point/固定小数点)|数値を10進数の固定小数点形式で表した文字列でフォーマットする。
+
桁数が指定されている場合は、小数部が指定された桁数で0埋めしてフォーマットされる。 桁数が指定されていない場合は、小数部がデフォルトの桁数でフォーマットされる。
+
小数部をフォーマットする際に、省略される部分は四捨五入してフォーマットされる。
+
|*書式指定子"F", "f"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(16).ToString("F")|"16.00"|
+
|(16).ToString("F4")|"16.0000"|
+
|(12345).ToString("F")|"12345.00"|
+
|(3.1416).ToString("F")|"3.14"|
+
|(3.1416).ToString("F3")|"3.142"|
+
|(3.1416).ToString("f3")|"3.142"|
+
|(-3.1416).ToString("F3")|"-3.142"|
+
|(-3.1416).ToString("F6")|"-3.141600"|
+
|(2.5).ToString("F0")|"3"|
+
非数と無限大の場合はそれぞれ次のようになる。
+
|*書式指定子"F"と非数・無限大のフォーマット例
+
|~値と書式指定子|~結果|h
+
|Double.NaN.ToString("F"))|"NaN"|
+
|Double.PositiveInfinity.ToString("F")|"Infinity"|
+
|Double.NegativeInfinity.ToString("F")|"-Infinity"|
+
|Double.NaN.ToString("F4")|"NaN"|
+
|Double.PositiveInfinity.ToString("F4")|"Infinity"|
+
:E, e (exponential/指数)|数値を10進数の指数形式で表した文字列でフォーマットする。
+
桁数が指定されている場合は、小数部が指定された桁数で0埋めしてフォーマットされる。 桁数が指定されていない場合は、小数部がデフォルトの桁数でフォーマットされる。
+
小数部をフォーマットする際に、省略される部分は四捨五入してフォーマットされる。
+
小文字の"e"を指定した場合は、指数部の前の'E'の代わりに小文字の'e'を使ってフォーマットされる。
+
|*書式指定子"E", "e"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(16).ToString("E")|"1.600000E+001"|
+
|(16).ToString("E2")|"1.60E+001"|
+
|(12345).ToString("E2")|"1.23E+004"|
+
|(0.9876).ToString("E2")|"9.88E-001"|
+
|(3.1416).ToString("E")|"3.141600E+000"|
+
|(3.1416).ToString("E3")|"3.142E+000"|
+
|(3.1416).ToString("e3")|"3.142e+000"|
+
|(-3.1416).ToString("E3")|"-3.142E+000"|
+
|(-3.1416).ToString("E6")|"-3.141600E+000"|
+
|(2.5).ToString("E0")|"3E+000"|
+
非数と無限大の場合はそれぞれ次のようになる。
+
|~値と書式指定子|~結果|h
+
|*書式指定子"E"と非数・無限大のフォーマット例
+
|Double.NaN.ToString("E"))|"NaN"|
+
|Double.PositiveInfinity.ToString("E")|"Infinity"|
+
|Double.NegativeInfinity.ToString("E")|"-Infinity"|
+
|Double.NaN.ToString("E4")|"NaN"|
+
|Double.PositiveInfinity.ToString("E4")|"Infinity"|
+
:P, p (percent/パーセント)|数値をパーセント形式で表した文字列でフォーマットする。
+
数値に100を乗じた値でフォーマットされ(1.0で100%となり)、位取りのカンマが挿入される。 数値が整数型の場合でも同様。
+
桁数が指定されている場合は、小数部が指定された桁数で0埋めしてフォーマットされる。 桁数が指定されていない場合は、小数部がデフォルトの桁数でフォーマットされる。
+
小数部をフォーマットする際に、省略される部分は四捨五入してフォーマットされる。
+
|*書式指定子"P", "p"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(0.0).ToString("P")|"0.00%"|
+
|(1.0).ToString("P")|"100.00%"|
+
|(0.5).ToString("P1")|"50.0%"|
+
|(-0.5).ToString("P4")|"-50.0000%"|
+
|(72).ToString("P")|"7,200.00%"|
+
|(0.0625).ToString("P1")|"6.3%"|
+
また、位取りのカンマ、小数点のピリオド、パーセント記号などはローカライズされた形式でフォーマットされる。
+
|*書式指定子"P", "p"とローカライズの例
+
|~値と書式指定子|~結果|h
+
|(-1.0).ToString("P", CultureInfo.GetCultureInfo("ja-JP"))|"-100.00%"|
+
|(-1.0).ToString("P", CultureInfo.GetCultureInfo("en-US"))|"-100.00 %"|
+
|(-1.0).ToString("P", CultureInfo.GetCultureInfo("fr-FR"))|"-100,00 %"|
+
|(-1.0).ToString("P", CultureInfo.GetCultureInfo("es-ES"))|"-100,00%"|
+
パーミル形式で表した文字列でフォーマットしたい場合は、[[カスタム数値書式指定子>#customformat_numeric_percent]]を使用する。
+
:N, n (number/数値)|数値を10進数の固定小数点形式で表した文字列でフォーマットする。
+
基本的には"F", "f"と同様だが、位取りのカンマが挿入される。
+
|*書式指定子"N", "n"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(12345).ToString("F")&br;(12345).ToString("N")|"12345.00"&br;"12,345.00"|
+
|(12345).ToString("F1")&br;(12345).ToString("N1")|"12345.0"&br;"12,345.0"|
+
また、位取りのカンマ、小数点のピリオドなどはローカライズされた形式でフォーマットされる。
+
|*書式指定子"N", "n"とローカライズの例
+
|~値と書式指定子|~結果|h
+
|(-1234567.89).ToString("N", CultureInfo.GetCultureInfo("ja-JP"))|"-1,234,567.89"|
+
|(-1234567.89).ToString("N", CultureInfo.GetCultureInfo("en-US"))|"-1,234,567.89"|
+
|(-1234567.89).ToString("N", CultureInfo.GetCultureInfo("fr-FR"))|"-1 234 567,89"|
+
|(-1234567.89).ToString("N", CultureInfo.GetCultureInfo("es-ES"))|"-1.234.567,89"|
+
:G, g (general/一般)|(未整理) 数値を10進数で表した文字列でフォーマットする。 指数形式もしくは固定小数点形式のうち、より簡潔な形式でフォーマットされる。
+
桁数を指定しない場合、数値の型によって適切な桁数が設定される(?)
+
小文字の"g"を指定した場合は、指数部の前の'E'の代わりに小文字の'e'を使ってフォーマットされる。
+
|*書式指定子"G", "g"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|byte.MaxValue.ToString("G")|"255"|
+
|byte.MaxValue.ToString("G1")|"3E+02"|
+
|int.MaxValue.ToString("G")|"2147483647"|
+
|int.MaxValue.ToString("G8")|"2.1474836E+09"|
+
|long.MaxValue.ToString("G")|"9223372036854775807"|
+
|long.MaxValue.ToString("G12")|"9.22337203685E+18"|
+
|(123456.78).ToString("G")|"123456.78"|
+
|(123456.78).ToString("G4")|"1.235E+05"|
+
|(123456.78).ToString("g4")|"1.235e+05"|
+
:C, c (currency/通貨)|数値を通貨形式で表した文字列でフォーマットする。
+
桁数が指定されている場合は、小数部が指定された桁数で0埋めしてフォーマットされる。 桁数が指定されていない場合は、小数部がデフォルトの桁数でフォーマットされる。
+
小数部をフォーマットする際に、省略される部分は四捨五入してフォーマットされる。
+
|*書式指定子"C", "c"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(72).ToString("C")|"¥72"|
+
|(72).ToString("C2")|"¥72.00"|
+
|(-16).ToString("C2")|"-¥16.00"|
+
|(3.1416).ToString("C")|"¥3"|
+
|(3.1416).ToString("C3")|"¥3.142"|
+
また、位取りのカンマ、小数点のピリオド、通貨単位記号などはローカライズされた形式でフォーマットされる。
+
|*書式指定子"C", "c"とローカライズの例
+
|~値と書式指定子|~結果|h
+
|(-12345.67).ToString("C", CultureInfo.GetCultureInfo("ja-JP"))|"-¥12,346"|
+
|(-12345.67).ToString("C", CultureInfo.GetCultureInfo("en-US"))|"($12,345.67)"|
+
|(-12345.67).ToString("C", CultureInfo.GetCultureInfo("en-GB"))|"-£12,345.67"|
+
|(-12345.67).ToString("C", CultureInfo.GetCultureInfo("fr-FR"))|"-12 345,67 €"|
+
|(-12345.67).ToString("C", CultureInfo.GetCultureInfo("es-ES"))|"-12.345,67 €"|
+

          
+
***SingleおよびDoubleのみに指定できる書式指定子
+
以下の書式指定子はfloat(Single), doubleの浮動小数点型(.NET Framework 4以降では&msdn(netfx,type,System.Numerics.BigInteger){BigInteger};も含む)の値に対してのみ指定できる。
+

          
+
:R, r (round-trip/ラウンドトリップ)|丸めを行わず、誤差なく復元できる形式でフォーマットする。
+
|*書式指定子"R", "r"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(2.0/3.0).ToString()&br;(2.0/3.0).ToString("R")|"0.666666666666667"&br;"0.66666666666666663"|
+
|(1.0f/3.0f).ToString()&br;(1.0f/3.0f).ToString("R")|"0.3333333"&br;"0.333333343"|
+
桁数は指定しても無視される。
+
|~値と書式指定子|~結果|h
+
|(2.0/3.0).ToString("R4")|"0.66666666666666663"|
+
|(1.0f/3.0f).ToString("R4")|"0.333333343"|
+

          
+
**日付と時刻の書式指定子
+
以下の書式指定子はDateTimeまたはDateTimeOffsetの日付型の値に対して指定できる。 (MSDN: &msdn(netfx,id,az4se3k1){標準の日付と時刻の書式指定文字列};)
+

          
+
***ローカライズされない書式指定子
+
以下の書式指定子はローカライズされていない(カルチャに依存しない)形式でフォーマットされる。
+

          
+
:R, r (RFC1123)|HTTPなどで用いられるRFC1123形式でフォーマットする。
+
UTCとしてフォーマットされるが、DateTime型の場合はフォーマットの際にUTCへの変換は行われないので、ToUniversalTime()メソッドを使ってUTCに変換しておく必要がある。
+
:O, o (round-trip date/time)|XMLなどで用いられるW3C-DTF(W3C Date and Time Formats, ISO8601)形式でフォーマットする。
+
秒の端数はTicks(100ナノ秒)の精度でフォーマットされる。
+
:s (sortable date/time)|ソートに適した形式でフォーマットする。
+
W3C-DTF形式に似ているが、秒の端数はフォーマットされない。 また、タイムゾーンのオフセット値もフォーマットされない。
+
:u (universal sortable date/time)|"s"と同様、ソートに適した形式でフォーマットする。
+
"s"とは異なり、UTCとしてフォーマットされ(最後に'Z'が付く)、日付と時刻の間は'T'ではなく空白になる。
+
UTCとしてフォーマットされるが、DateTime型の場合はフォーマットの際にUTCへの変換は行われないので、ToUniversalTime()メソッドを使ってUTCに変換しておく必要がある。
+

          
+
|*書式指定子"r", "o", "s", "u"とDateTime型のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString()&br;DateTime.UtcNow.ToString()|"2010/09/14 1:02:03"&br;"2010/09/13 16:02:03"|
+
|DateTime.Now.ToString("r")&br;DateTime.UtcNow.ToString("r")|"Tue, 14 Sep 2010 01:02:03 GMT"&br;"Mon, 13 Sep 2010 16:02:03 GMT"
+
|DateTime.Now.ToString("o")&br;DateTime.UtcNow.ToString("o")|"2010-09-14T01:02:03.1234567+09:00"&br;"2010-09-13T16:02:03.1234567Z"
+
|DateTime.Now.ToString("s")&br;DateTime.UtcNow.ToString("s")|"2010-09-14T01:02:03"&br;"2010-09-13T16:02:03"
+
|DateTime.Now.ToString("u")&br;DateTime.UtcNow.ToString("u")|"2010-09-14 01:02:03Z"&br;"2010-09-13 16:02:03Z"
+

          
+
|*書式指定子"r", "o", "s", "u"とDateTimeOffset型のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTimeOffset.Now.ToString()&br;DateTimeOffset.UtcNow.ToString()|"2010/09/14 1:02:03 +09:00"&br;"2010/09/13 16:02:03 +00:00"|
+
|DateTimeOffset.Now.ToString("r")&br;DateTimeOffset.UtcNow.ToString("r")|"Mon, 13 Sep 2010 16:02:03 GMT"&br;"Mon, 13 Sep 2010 16:02:03 GMT"|
+
|DateTimeOffset.Now.ToString("o")&br;DateTimeOffset.UtcNow.ToString("o")|"2010-09-14T01:02:03.1234567+09:00"&br;"2010-09-13T16:02:03.1234567+00:00"|
+
|DateTimeOffset.Now.ToString("s")&br;DateTimeOffset.UtcNow.ToString("s")|"2010-09-14T01:02:03"&br;"2010-09-13T16:02:03"|
+
|DateTimeOffset.Now.ToString("u")&br;DateTimeOffset.UtcNow.ToString("u")|"2010-09-13 16:02:03Z"&br;"2010-09-13 16:02:03Z"|
+

          
+
***ローカライズされる書式指定子
+
以下の書式指定子はローカライズされた形式でフォーマットされる。
+

          
+
:D, d (date)|日付のみ(年月日)の形式でフォーマットする。
+
"D"の場合は長い形式、"d"の場合は短い形式でフォーマットされる。
+
ToLongDateString(), ToShortDateString()でも同じ結果が得られる。
+
|*書式指定子"D", "d"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("D")&br;DateTime.Now.ToLongDateString()|"2010年9月14日"|
+
|DateTime.Now.ToString("d")&br;DateTime.Now.ToShortDateString()|"2010/09/14"|
+
|DateTime.Now.ToString("D", CultureInfo.GetCultureInfo("ja-JP"))|"2010年9月14日"|
+
|DateTime.Now.ToString("D", CultureInfo.GetCultureInfo("en-US"))|"Tuesday, September 14, 2010"|
+
|DateTime.Now.ToString("D", CultureInfo.GetCultureInfo("es-ES"))|"martes, 14 de septiembre de 2010"|
+
|DateTime.Now.ToString("d", CultureInfo.GetCultureInfo("ja-JP"))|"2010/09/14"|
+
|DateTime.Now.ToString("d", CultureInfo.GetCultureInfo("en-US"))|"9/14/2010"|
+
|DateTime.Now.ToString("d", CultureInfo.GetCultureInfo("es-ES"))|"14/09/2010"|
+
:T, t (time)|時刻のみ(時分秒)の形式でフォーマットする。
+
"T"の場合は長い形式、"t"の場合は短い形式でフォーマットされる。
+
ToLongTimeString(), ToShortTimeString()でも同じ結果が得られる。
+
|*書式指定子"T", "t"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("T")&br;DateTime.Now.ToLongTimeString()|"1:02:03"|
+
|DateTime.Now.ToString("t")&br;DateTime.Now.ToShortTimeString()|"1:02"|
+
|DateTime.Now.ToString("T", CultureInfo.GetCultureInfo("ja-JP"))|"1:02:03"|
+
|DateTime.Now.ToString("T", CultureInfo.GetCultureInfo("en-US"))|"1:02:03 AM"|
+
|DateTime.Now.ToString("T", CultureInfo.GetCultureInfo("es-ES"))|"1:02:03"|
+
|DateTime.Now.ToString("t", CultureInfo.GetCultureInfo("ja-JP"))|"1:02"|
+
|DateTime.Now.ToString("t", CultureInfo.GetCultureInfo("en-US"))|"1:02 AM"|
+
|DateTime.Now.ToString("t", CultureInfo.GetCultureInfo("es-ES"))|"1:02"|
+
:Y, y (year/month)|年月のみの形式でフォーマットする。
+
|*書式指定子"Y", "y"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("Y")|"2010年9月"|
+
|DateTime.Now.ToString("y")|"2010年9月"|
+
|DateTime.Now.ToString("Y", CultureInfo.GetCultureInfo("ja-JP"))|"2010年9月"|
+
|DateTime.Now.ToString("Y", CultureInfo.GetCultureInfo("en-US"))|"September, 2010"|
+
|DateTime.Now.ToString("Y", CultureInfo.GetCultureInfo("es-ES"))|"septiembre de 2010"|
+
:M, m (month/day)|月日のみの形式でフォーマットする。
+
|*書式指定子"M", "m"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("M")|"9月14日"|
+
|DateTime.Now.ToString("m")|"9月14日"|
+
|DateTime.Now.ToString("M", CultureInfo.GetCultureInfo("ja-JP"))|"9月14日"|
+
|DateTime.Now.ToString("M", CultureInfo.GetCultureInfo("en-US"))|"September 14"|
+
|DateTime.Now.ToString("M", CultureInfo.GetCultureInfo("es-ES"))|"14 septiembre"|
+
:F, f (full date/time)|完全な日付と時刻の形式でフォーマットする。
+
"F"の場合は長い形式、"f"の場合は短い形式でフォーマットされる。 "f"は"D"(長い形式の日付)と"t"(短い形式の時刻)を繋げた形式となる。
+
|*書式指定子"F", "f"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("F")|"2010年9月14日 1:02:03"|
+
|DateTime.Now.ToString("f")|"2010年9月14日 1:02"|
+
|DateTime.Now.ToString("F", CultureInfo.GetCultureInfo("ja-JP"))|"2010年9月14日 1:02:03"|
+
|DateTime.Now.ToString("F", CultureInfo.GetCultureInfo("en-US"))|"Tuesday, September 14, 2010 1:02:03 AM"|
+
|DateTime.Now.ToString("F", CultureInfo.GetCultureInfo("es-ES"))|"martes, 14 de septiembre de 2010 1:02:03"|
+
|DateTime.Now.ToString("f", CultureInfo.GetCultureInfo("ja-JP"))|"2010年9月14日 1:02:03"|
+
|DateTime.Now.ToString("f", CultureInfo.GetCultureInfo("en-US"))|"Tuesday, September 14, 2010 1:02 AM"|
+
|DateTime.Now.ToString("f", CultureInfo.GetCultureInfo("es-ES"))|"martes, 14 de septiembre de 2010 1:02"|
+
:G, g (general date/time)|一般的な日付と時刻の形式でフォーマットする。
+
"G"の場合は長い形式、"g"の場合は短い形式でフォーマットされる。 "g"は"d"(短い形式の日付)と"t"(短い形式の時刻)を繋げた形式となる。
+
|*書式指定子"G", "g"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("G")|"2010/09/14 1:02:03"|
+
|DateTime.Now.ToString("g")|"2010/09/14 1:02"|
+
|DateTime.Now.ToString("G", CultureInfo.GetCultureInfo("ja-JP"))|"2010/09/14 1:02:03"|
+
|DateTime.Now.ToString("G", CultureInfo.GetCultureInfo("en-US"))|"9/14/2010 1:02:03 AM"|
+
|DateTime.Now.ToString("G", CultureInfo.GetCultureInfo("es-ES"))|"14/09/2010 1:02:03"|
+
|DateTime.Now.ToString("g", CultureInfo.GetCultureInfo("ja-JP"))|"2010/09/14 1:02"|
+
|DateTime.Now.ToString("g", CultureInfo.GetCultureInfo("en-US"))|"9/14/2010 1:02 AM"|
+
|DateTime.Now.ToString("g", CultureInfo.GetCultureInfo("es-ES"))|"14/09/2010 1:02"|
+
:U (universal full date/time)|UTCでの完全な日付と日時の形式でフォーマットする。
+
値がDateTime型の場合は自動的にUTCに変換され、"F"と同じ形式でフォーマットされる。
+
DateTimeOffset型の値ではサポートされない(FormatExceptionがスローされる)。
+
|*書式指定子"U"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("F")|"2010年9月14日 1:02:03"|
+
|DateTime.Now.ToString("U")|"2010年9月13日 16:02:03"|
+
|DateTime.Now.ToString("U", CultureInfo.GetCultureInfo("ja-JP"))|"2010年9月13日 16:02:03"|
+
|DateTime.Now.ToString("U", CultureInfo.GetCultureInfo("en-US"))|"Monday, September 13, 2010 4:02:03 PM"|
+
|DateTime.Now.ToString("U", CultureInfo.GetCultureInfo("es-ES"))|"lunes, 13 de septiembre de 2010 16:02:03"|
+

          
+
**列挙型の書式指定子
+
以下の書式指定子は列挙型の値に対して指定できる。 (MSDN: &msdn(netfx,id,c3s1ez6e){列挙型書式指定文字列};)
+

          
+
:D, d (decimal)|列挙型の値を10進形式でフォーマットする。
+
Flags属性が付与されているかどうかに関わらず、常に10進形式の値でフォーマットされる。
+
|*書式指定子"D", "d"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DayOfWeek.Sunday.ToString("D")|"0"|
+
|DayOfWeek.Sunday.ToString("d")|"0"|
+
|DayOfWeek.Wednesday.ToString("D")|"3"|
+
|FileAttributes.Archive.ToString("D")|"32"|
+
|FileAttributes.ReadOnly.ToString("d")|"1"|
+
|(FileAttributes.Archive | FileAttributes.ReadOnly).ToString("d")|"33"|
+
:X, x (hexadecimal)|列挙型の値を16進形式でフォーマットする。
+
Flags属性が付与されているかどうかに関わらず、常に16進形式の値でフォーマットされる。
+
小文字の"x"を指定した場合は、A-Fの代わりに小文字のa-fを使ってフォーマットされる。
+
|*書式指定子"X", "x"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|DayOfWeek.Sunday.ToString("X")|"00000000"|
+
|DayOfWeek.Wednesday.ToString("X")|"00000003"|
+
|FileAttributes.Archive.ToString("X")|"00000020"|
+
|FileAttributes.ReadOnly.ToString("X")|"00000001"|
+
|(FileAttributes.Archive | FileAttributes.Normal).ToString("X")|"000000a0"|
+
|(FileAttributes.Archive | FileAttributes.Normal).ToString("x")|"000000A0"|
+
また、基になる型に応じて適切な桁数で0埋めされてフォーマットされる。
+
#code(cs){{
+
enum ByteEnum : byte {
+
  E1 = 0x0f,
+
}
+

          
+
enum ShortEnum : short {
+
  E1 = 0x00ff,
+
}
+

          
+
enum IntEnum : int {
+
  E1 = 0x0000ffff,
+
}
+

          
+
enum LongEnum : long {
+
  E1 = 0x00000000ffffffff,
+
}
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    Console.WriteLine(ByteEnum.E1.ToString("X"));   // 0F
+
    Console.WriteLine(ShortEnum.E1.ToString("X"));  // 00FF
+
    Console.WriteLine(IntEnum.E1.ToString("X"));    // 0000FFFF
+
    Console.WriteLine(LongEnum.E1.ToString("X"));   // 00000000FFFFFFFF
+
  }
+
}
+
}}
+
:G, g (general)|列挙型の値を文字列(メンバ名)でフォーマットする。
+
FlagsAttributeが適用されている列挙型の場合、有効な値の組み合わせをカンマ区切りの文字列でフォーマットされる。
+
FlagsAttributeが適用されていない列挙型の場合、文字列で表現できない場合は、数値(Dと同じ)でフォーマットされる。
+
:F, f (flag)|列挙型の値を文字列(メンバ名)でフォーマットする。
+
"G", "g"と異なり、FlagsAttributeが付与されていない列挙型の場合でも、有効な値の組み合わせをカンマ区切りの文字列でフォーマットされる。
+
|*書式指定子"G", "g", "F", "f"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(DayOfWeek.Wednesday | DayOfWeek.Saturday).ToString("G")|"7"|
+
|(DayOfWeek.Wednesday | DayOfWeek.Saturday).ToString("F")|"Monday, Saturday"|
+
|(FileAttributes.Archive | FileAttributes.ReadOnly).ToString("G")|"ReadOnly, Archive"|
+
|(FileAttributes.Archive | FileAttributes.ReadOnly).ToString("F")|"ReadOnly, Archive"|
+
|(FileAttributes.Archive | FileAttributes.ReadOnly).ToString("g")|"ReadOnly, Archive"|
+
|(FileAttributes.Archive | FileAttributes.ReadOnly).ToString("f")|"ReadOnly, Archive"|
+
|((DayOfWeek)0x7fffffff).ToString("G")|"2147483647"|
+
|((DayOfWeek)0x7fffffff).ToString("F")|"2147483647"|
+
|((FileAttributes)0x7fffffff).ToString("G")|"2147483647"|
+
|((FileAttributes)0x7fffffff).ToString("F")|"2147483647"|
+

          
+
**時間間隔の書式指定子
+
.NET Framework 4以降では、TimeSpan型の値についても書式指定子を使ってフォーマットできるようになっている。 以下の書式指定子はTimeSpane型の値に対して指定できる。 (MSDN: &msdn(netfx,id,ee372286){標準の時間間隔書式指定文字列};)
+

          
+
:c (constant)|固定の形式でフォーマットする。
+
時分秒は常にhh:mm:ssの形式で0埋めされてフォーマットされ、ミリ秒および日数は0でない場合にフォーマットされる。
+
時分秒区切りのコロン、小数点のピリオドなどはローカライズされずにフォーマットされる。
+
|*書式指定子"C", "c"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|TimeSpan.Zero.ToString("c")|"00:00:00"|
+
|TimeSpan.Zero.ToString("C")|"00:00:00"|
+
|(new TimeSpan(1, 2, 3)).ToString("c")|"01:02:03"|
+
|TimeSpan.FromHours(-36).ToString("c")|"-1.12:00:00"|
+
|TimeSpan.FromDays(1.234).ToString("c")|"1.05:36:57.6000000"|
+
:G, g (general)|一般的な形式でフォーマットする。
+
"G"の場合は"d:hh:mm:ss:fffffff"(時分秒すべて0埋め2桁、秒の端数は0埋め7桁)の形式、"g"の場合は"[d.]h:mm:ss[.FFFFFFF]"(分秒は0埋め2桁、時は0埋めなし、秒の端数と日数は0でない場合のみ出力)の形式でフォーマットされる。
+
時分秒区切りのコロン、小数点のピリオドなどはローカライズされた形式でフォーマットされる。
+
|*書式指定子"G", "g"のフォーマット例
+
|~値と書式指定子|~結果|h
+
|(new TimeSpan(1, 2, 3)).ToString("g")|"1:2:03"|
+
|(new TimeSpan(1, 2, 3)).ToString("G")|"0:01:02:03.0000000"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("g")|"1:2:03:04.567"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("G")|"1:02:03:04.5670000"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("g", CultureInfo.GetCultureInfo("ja-JP"))|"1:2:03:04.567"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("g", CultureInfo.GetCultureInfo("en-US"))|"1:2:03:04.567"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("g", CultureInfo.GetCultureInfo("fr-FR"))|"1:2:03:04,567"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("G", CultureInfo.GetCultureInfo("ja-JP"))|"1:02:03:04.5670000"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("G", CultureInfo.GetCultureInfo("en-US"))|"1:02:03:04.5670000"|
+
|(new TimeSpan(1, 2, 3, 4, 567)).ToString("G", CultureInfo.GetCultureInfo("fr-FR"))|"1:02:03:04,5670000"|
+

          
+
*カスタム書式指定子
+
このセクションは未整理です。
+
**数値のカスタム書式指定子
+
(MSDN: &msdn(netfx,id,0c899ak8){カスタム数値書式指定文字列};)
+

          
+
|*数値のカスタム書式指定子とフォーマット例
+
|~値と書式指定子|~結果|h
+
|(72).ToString("##.0")|"72.0"|
+
|(72).ToString("0000.0")|"0072.0"|
+
|(72).ToString("0000.#")|"0072"|
+
|(3.1416).ToString("0000.0")|"0003.1"|
+
|(3.1416).ToString("0000.0", CultureInfo.GetCultureInfo("fr-FR"))|"0003,1"|
+
|(123456789).ToString("#,###")|"123,456,789"|
+
|(123456789).ToString("#,###", CultureInfo.GetCultureInfo("fr-FR"))|"123 456 789"|
+
|(1234567).ToString("##.#e+0")|"12.3e+5"|
+

          
+
***&aname(customformat_numeric_percent){パーセント・パーミル};
+
書式指定子に"%"および"‰"を指定すると、それぞれパーセント・パーミルとしてフォーマットされる(数値に100ないし1000を乗じた値でフォーマットされる)。
+
|*数値のカスタム書式指定子とフォーマット例
+
|~値と書式指定子|~結果|h
+
|(0.5).ToString("#.0%")|"50.0%"|
+
|(0.5).ToString("#.0‰")|"500.0‰"|
+

          
+
**日付と時刻のカスタム書式指定子
+
(MSDN: &msdn(netfx,id,8kb3ddd4){カスタムの日付と時刻の書式指定文字列};)
+

          
+
|*日付と時刻のカスタム書式指定子とフォーマット例
+
|~値と書式指定子|~結果|h
+
|DateTime.Now.ToString("y/M/d h:m:s")|"10/9/14 1:2:3"|
+
|DateTime.Now.ToString("yy/MM/dd hh:mm:ss")|"10/09/14 01:02:03"|
+
|DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFzzz")|"2010-09-14T01:02:03.456789+09:00"|
+
|DateTime.Now.ToString("yyyy/MM/dd (dddd) hh:mm:ss")|"2010/09/14 (火曜日) 01:02:03"|
+
|DateTime.Now.ToString("yyyy/MM/dd (dddd) hh:mm:ss", CultureInfo.GetCultureInfo("en-US"))|"2010/09/14 (Tuesday) 01:02:03"|
+
|DateTime.Now.ToString("ddd, d MMM yyyy HH:mm:ss K")|"火, 14 9 2010 01:02:03 +09:00"|
+
|DateTime.Now.ToString("ddd, d MMM yyyy HH:mm:ss K", CultureInfo.GetCultureInfo("en-US"))|"Tue, 14 Sep 2010 01:02:03 +09:00"|
+
|DateTime.UtcNow.ToString("ddd, d MMM yyyy HH:mm:ss K")|"月, 13 9 2010 16:02:03 Z"|
+

          
+
**時間間隔のカスタム書式指定子
+
(MSDN: &msdn(netfx,id,ee372287){カスタム時間間隔書式指定文字列};)
+

          
+
|*時間間隔のカスタム書式指定子とフォーマット例
+
|~値と書式指定子|~結果|h
+
|(new TimeSpan(1, 2, 3)).ToString(@"%h\-m\-s")|"1-2-3"|
+
|(new TimeSpan(1, 2, 3)).ToString(@"hh\-mm\-ss")|"01-02-03"|
+
|TimeSpan.FromDays(10.0/7.0).ToString(@"dd\.hh\:mm\:ss\.FFFF")|"01.10:17:08.571"|
+
|TimeSpan.FromDays(10.0/7.0).ToString(@"dd\.hh\:mm\:ss\.ffff")|"01.10:17:08.0571"|
+

          
+
----
+
#googleadunit
+

          
+
*書式プロバイダ(IFormatProvider)
+
書式プロバイダ(&msdn(netfx,type,System.IFormatProvider){IFormatProvider};)は、"D", "G"などの書式指定子を適切な形式の文字列にするためのメソッドを提供するインターフェイスで、ToString()等のメソッドから参照される。
+

          
+
**スレッドのカルチャと書式プロバイダ
+
ToString()等のメソッドで書式プロバイダを指定しなかった場合は、現在のスレッドのカルチャ(Thread.CurrentThread.CurrentCulture)が提供する書式を使ってフォーマットされる。 Thread.CurrentThread.CurrentCultureにCultureInfoクラスのインスタンスを設定するか、IFormatProviderを指定してToString()等を呼び出すことで、フォーマットの際の書式を指定できる。
+

          
+
#code(cs){{
+
var dt = new DateTime(2010, 9, 14, 1, 2, 3, 456);
+

          
+
// IFormatProviderを指定しない場合
+
// (現在のスレッドのカルチャ'ja-JP'での書式でフォーマットされる)
+
Console.WriteLine("{0} {1:U}", Thread.CurrentThread.CurrentCulture.Name, dt);
+

          
+
// Thread.CurrentThread.CurrentCultureに'en-US'のCultureInfoを指定した場合
+
// (現在のスレッドのカルチャ'en-US'での書式でフォーマットされる)
+
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
+

          
+
Console.WriteLine("{0} {1:U}", Thread.CurrentThread.CurrentCulture.Name, dt);
+

          
+
// Thread.CurrentThread.CurrentCultureに'es-ES'のCultureInfoを指定した場合
+
// (現在のスレッドのカルチャ'es-ES'での書式でフォーマットされる)
+
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("es-ES");
+

          
+
Console.WriteLine("{0} {1:U}", Thread.CurrentThread.CurrentCulture.Name, dt);
+

          
+
// ToString()メソッドでIFormatProviderを指定した場合
+
// (引数で指定したIFormatProvider=カルチャ'ja-JP'での書式でフォーマットされる)
+
Console.WriteLine("{0} {1}", Thread.CurrentThread.CurrentCulture.Name, dt.ToString("U", CultureInfo.GetCultureInfo("ja-JP")));
+

          
+
// String.Format()メソッドでIFormatProviderを指定した場合
+
// (上と同様、引数で指定したIFormatProvider=カルチャ'ja-JP'での書式でフォーマットされる)
+
Console.WriteLine(String.Format(CultureInfo.GetCultureInfo("ja-JP"), "{0} {1:U}", Thread.CurrentThread.CurrentCulture, dt));
+
}}
+

          
+
#prompt{{
+
ja-JP 2010年9月13日 16:02:03
+
en-US Monday, September 13, 2010 4:02:03 PM
+
es-ES lunes, 13 de septiembre de 2010 16:02:03
+
es-ES 2010年9月13日 16:02:03
+
es-ES 2010年9月13日 16:02:03
+
}}
+

          
+
**NumberFormatInfo
+
(未整理) &msdn(netfx,type,System.Globalization.NumberFormatInfo){NumberFormatInfo};
+

          
+
**DateTimeFormatInfo
+
(未整理) &msdn(netfx,type,System.Globalization.DateTimeFormatInfo){DateTimeFormatInfo};
+

          
+
**カスタム書式プロバイダ(ICustomFormatter)
+
&msdn(netfx,type,System.IFormatProvider){IFormatProvider};インターフェイスと&msdn(netfx,type,System.ICustomFormatter){ICustomFormatter};インターフェイスを実装することで、独自に書式を定義することができる。
+

          
+
以下は、書式指定子に応じて文字列を大文字化・小文字化するカスタム書式プロバイダを実装する例。 動作は次のとおり。
+
-引数が文字列の場合
+
--書式指定子が"U", "u"の場合、引数で指定された文字列を大文字化して返す
+
--書式指定子が"L", "l"の場合、引数で指定された文字列を小文字化して返す
+
--書式指定子が指定されていない場合、引数で指定された文字列をそのまま返す
+
--上記以外の書式指定子の場合、FormatExceptionをスローする
+
-引数が文字列以外の場合
+
--引数がIFormattableを実装している場合は、IFormattable.ToString()の結果を返す
+
--引数がIFormattableを実装していない場合は、Object.ToString()の結果を返す
+

          
+
#code(cs,文字列化を大文字化・小文字化するカスタム書式プロバイダ){{
+
class UpperLowerFormatProvider : IFormatProvider, ICustomFormatter {
+
  // IFormatProvider.GetFormatの実装
+
  public object GetFormat(Type formatType)
+
  {
+
    if (formatType == typeof(ICustomFormatter))
+
      // IFormatProviderにICustomFormatter型を要求された場合は自分自身を返す
+
      return this;
+
    else
+
      // それ以外の場合はnullを返す
+
      return null;
+
  }
+

          
+
  // ICustomFormatter.Formatの実装
+
  public string Format(string format, object arg, IFormatProvider formatProvider)
+
  {
+
    var argString = arg as string;
+

          
+
    if (argString != null) {
+
      // 引数がstring型の場合、指定された書式に合わせて文字列化する
+
      switch (format) {
+
        case "u":
+
        case "U": // 書式指定子が"U"または"u"の時は、すべて大文字にする
+
          return argString.ToUpper();
+

          
+
        case "l":
+
        case "L": // 書式指定子が"L"または"l"の時は、すべて小文字にする
+
          return argString.ToLower();
+

          
+
        default:
+
          if (string.IsNullOrEmpty(format))
+
            // 書式指定子が指定されていない場合は、そのままにする
+
            return argString;
+
          else
+
            // それ以外の書式指定子の場合は、FormatExceptionをスローする
+
            throw new FormatException(string.Format("'{0}'は不正な書式指定子です", format));
+
      }
+
    }
+

          
+
    // 引数がString型でない場合
+
    if (arg is IFormattable)
+
      // 引数がIFormattableを実装している場合は、IFormattable.ToString()メソッドで文字列化する
+
      return ((IFormattable)arg).ToString(format, formatProvider);
+
    else
+
      // 引数がIFormattableを実装していない場合は、Object.ToString()メソッドで文字列化する
+
      return arg.ToString();
+
  }
+
}
+
}}
+

          
+
上記のカスタム書式プロバイダを使用した例は以下のとおり。
+
#code(cs){{
+
Console.WriteLine(string.Format(new UpperLowerFormatProvider(), "{0} {0:U} {0:u} {0:L} {0:l}", "HoGe"));
+
Console.WriteLine(string.Format(new UpperLowerFormatProvider(), "{0:D4} {0:F2}", 16));
+
Console.WriteLine(string.Format(new UpperLowerFormatProvider(), "{0:u} {0:s}", DateTime.Now));
+
Console.WriteLine(DateTime.Now.ToString("u", new UpperLowerFormatProvider()));
+
Console.WriteLine((72).ToString("X8", new UpperLowerFormatProvider()));
+
try {
+
  Console.WriteLine(string.Format(new UpperLowerFormatProvider(), "{0:U} {0:X}", "hoge"));
+
}
+
catch (FormatException ex) {
+
  Console.Error.WriteLine(ex.Message);
+
}
+
}}
+

          
+
#prompt{{
+
HoGe HOGE HOGE hoge hoge
+
0016 16.00
+
2010-09-14 01:02:03Z 2010-09-14T01:02:03
+
2010-09-14 01:02:03Z
+
00000048
+
'X'は不正な書式指定子です
+
}}
+

          
+
*書式を指定した文字列化のサポート (IFormattable)
+
&msdn(netfx,type,System.IFormattable){IFormattableインターフェイス};を実装すると、独自に定義した書式で文字列化するToString()メソッドを用意することができる。 int, double, DateTime等の基本型はIFormattableインターフェイスを実装していて、これにより書式を指定して文字列化できるようになっている。
+
ICustomFormatterでは書式化の実装を書式化したい型とは別のクラスで実装するのに対し、IFormattableでは書式化の実装を書式化したい型自体に実装することができる。
+

          
+
以下は、複素数型Complexを用意し、IFormattableで書式化処理を実装する例。 この例では次の書式指定子をサポートする。
+
:G|ガウス平面座標表示。 "(a, b)"の形式。
+
:A|絶対値表示。 |z|の値の形式。
+
:C|直交座標表示。"a±bi"の形式。 実部・虚部が0の場合は表示しない。
+
:P|極座標表示。 "r∠θ"の形式。
+

          
+
#code(cs,IFormattableを実装した構造体型Complex){{
+
struct Complex : IFormattable {
+
  // 実部
+
  public double Real {
+
    get; set;
+
  }
+

          
+
  // 虚部
+
  public double Imaginary {
+
    get; set;
+
  }
+

          
+
  public Complex(double real, double imaginary)
+
    : this()
+
  {
+
    this.Real = real;
+
    this.Imaginary = imaginary;
+
  }
+

          
+
  // Object.ToStringのオーバーライド
+
  public override string ToString()
+
  {
+
    // 書式・書式プロバイダを指定せずにToString()を呼ぶ
+
    return ToString(null, null);
+
  }
+

          
+
  public string ToString(string format)
+
  {
+
    // 書式プロバイダを指定せずにToString()を呼ぶ
+
    return ToString(format, null);
+
  }
+

          
+
  // IFormattable.ToString(string, IFormatProvider)の実装
+
  public string ToString(string format, IFormatProvider formatProvider)
+
  {
+
    if (string.IsNullOrEmpty(format))
+
      format = "G"; // 指定されていない場合は"G"の書式を使用
+

          
+
    var f = format[0]; // 書式指定文字列の1文字目で種類を分ける
+
    var acc = format.Substring(1); // 書式指定文字列の2文字目以降を精度として扱う
+

          
+
    switch (f) {
+
      case 'G': // ガウス平面座標表示
+
        return string.Format(formatProvider, "({0:F" + acc + "}, {1:F" + acc + "})", Real, Imaginary);
+

          
+
      case 'A': // 絶対値表示
+
        return Math.Pow(Real * Real + Imaginary * Imaginary, 0.5).ToString("F" + acc, formatProvider);
+

          
+
      case 'C': { // 直交形式表示
+
        string realPart;
+

          
+
        if (Real == 0.0)
+
          realPart = null;
+
        else
+
          realPart = Real.ToString("F" + acc, formatProvider);
+

          
+
        string imaginaryPart;
+
        string sign;
+

          
+
        if (Imaginary == 0.0) {
+
          imaginaryPart = null;
+
          sign = null;
+
        }
+
        else if (0 < Imaginary) {
+
          imaginaryPart = Imaginary.ToString("F" + acc, formatProvider) + "i";
+
          sign = (realPart == null) ? null : "+";
+
        }
+
        else { /*if (Imaginary < 0)*/
+
          imaginaryPart = (-Imaginary).ToString("F" + acc, formatProvider) + "i";
+
          sign = "-";
+
        }
+

          
+
        return string.Concat(realPart, sign, imaginaryPart);
+
      }
+

          
+
      case 'P': { // 極形式表示
+
        var r = Math.Pow(Real * Real + Imaginary * Imaginary, 0.5);
+
        var t = Math.Atan2(Imaginary, Real) / Math.PI;
+

          
+
        return string.Format(formatProvider, "{0:F" + acc + "}∠{1:F" + acc + "}π", r, t);
+
      }
+

          
+
      default:
+
        throw new FormatException(string.Format("'{0}'は不正な書式指定子です", format));
+
    }
+
  }
+
}
+
}}
+

          
+
上記の構造体を使用した例は以下のとおり。
+
#code(cs){{
+
Console.WriteLine("{0}, {0:G}, {0:A}, {0:C1}, {0:P6}", (new Complex(4.0, 3.0)));
+

          
+
Console.WriteLine();
+
Console.WriteLine((new Complex( 3.000,  4.000)).ToString());
+
Console.WriteLine((new Complex( 1.414,  1.414)).ToString());
+
Console.WriteLine((new Complex( 3.000,  4.000)).ToString("G", CultureInfo.GetCultureInfo("ja-JP")));
+
Console.WriteLine((new Complex(-1.414,  1.414)).ToString("G4", CultureInfo.GetCultureInfo("en-US")));
+
Console.WriteLine((new Complex( 0.000,  1.000)).ToString("G12", CultureInfo.GetCultureInfo("fr-FR")));
+

          
+
Console.WriteLine();
+
Console.WriteLine((new Complex( 3.000,  4.000)).ToString("A"));
+
Console.WriteLine((new Complex(-4.000, -3.000)).ToString("A4", CultureInfo.GetCultureInfo("ja-JP")));
+
Console.WriteLine((new Complex( 1.000, -1.000)).ToString("A1", CultureInfo.GetCultureInfo("en-US")));
+
Console.WriteLine((new Complex( 2.000,  0.000)).ToString("A1", CultureInfo.GetCultureInfo("fr-FR")));
+

          
+
Console.WriteLine();
+
Console.WriteLine((new Complex( 3.000,  4.000)).ToString("C"));
+
Console.WriteLine((new Complex(-0.707,  0.707)).ToString("C2"));
+
Console.WriteLine((new Complex( 0.707, -0.707)).ToString("C2"));
+
Console.WriteLine((new Complex( 1.000,  0.000)).ToString("C1"));
+
Console.WriteLine((new Complex(-1.000,  0.000)).ToString("C1", CultureInfo.GetCultureInfo("ja-JP")));
+
Console.WriteLine((new Complex( 0.000,  1.000)).ToString("C1", CultureInfo.GetCultureInfo("en-US")));
+
Console.WriteLine((new Complex( 0.000, -1.000)).ToString("C1", CultureInfo.GetCultureInfo("fr-FR")));
+
Console.WriteLine((new Complex( 1.000,  1.000)).ToString("C1"));
+
Console.WriteLine((new Complex( 1.000, -1.000)).ToString("C1"));
+

          
+
Console.WriteLine();
+
Console.WriteLine((new Complex( 1.000,  0.000)).ToString("P3"));
+
Console.WriteLine((new Complex( 1.414,  1.414)).ToString("P3"));
+
Console.WriteLine((new Complex( 0.000,  1.000)).ToString("P3", CultureInfo.GetCultureInfo("ja-JP")));
+
Console.WriteLine((new Complex(-1.000,  0.000)).ToString("P3", CultureInfo.GetCultureInfo("en-US")));
+
Console.WriteLine((new Complex( 0.000, -1.000)).ToString("P3", CultureInfo.GetCultureInfo("fr-FR")));
+
Console.WriteLine((new Complex( 0.000,  0.000)).ToString("P3"));
+
Console.WriteLine((new Complex(-3.000,  4.000)).ToString("P3"));
+
}}
+

          
+
#prompt{{
+
(4.00, 3.00), (4.00, 3.00), 5.00, 4.0+3.0i, 5.000000∠0.204833π
+

          
+
(3.00, 4.00)
+
(1.41, 1.41)
+
(3.00, 4.00)
+
(-1.4140, 1.4140)
+
(0,000000000000, 1,000000000000)
+

          
+
5.00
+
5.0000
+
1.4
+
2,0
+

          
+
3.00+4.00i
+
-0.71+0.71i
+
0.71-0.71i
+
1.0
+
-1.0
+
1.0i
+
-1,0i
+
1.0+1.0i
+
1.0-1.0i
+

          
+
1.000∠0.000π
+
2.000∠0.250π
+
1.000∠0.500π
+
1.000∠1.000π
+
1,000∠-0,500π
+
0.000∠0.000π
+
5.000∠0.705π
+
}}