概要
数値を整形して表示したいことがあります。 例えば、19800 という数値に対して、
数字のみ: 19800
3ケタごとにコンマ区切り: 19,800
指数表記: 1.98e4
など、いろんな表示の仕方があります。
.NET では、ToString メソッドや、string.Format 静的メソッドなどに対して、書式を与えることで、数値の表示の仕方を変えることができます。 また、WPF や Silverlight のデータ バインディングでも、書式設定ができます。
参考:
ToString メソッド
C#では、数値などから文字列への型変換は、そのままではできません。しかし、objectクラスがToStringというメソッドを持っていて、これで文字列化できます。
自作の型を文字列化したい場合は、以下のように、ToStringメソッドをオーバーライドします。
class Point
{
public int X { get; set; }
public int Y { get; set; }
public override string ToString()
{
return "(" + X + ", " + Y + ")";
}
}
Class Point
Public Property X As Integer
Public Property Y As Integer
Public Overrides Function ToString() As String
Return "(" & X & ", " & Y & ")"
End Function
End Class
ref class Point
{
public:
property int X;
property int Y;
virtual String^ ToString() override
{
return "(" + X + ", " + Y + ")";
}
};
以下のように利用できます。
var p = new Point { X = 10, Y = 20 };
Console.WriteLine(p);
Dim p = New Point With {.X = 10, .Y = 20}
Console.WriteLine(p)
auto p = gcnew Point();
p->X = 10;
p->Y = 20;
Console::WriteLine(p);
(10, 20)
書式設定付きの ToString メソッド
intやDateTimeなど、主要な型には、書式設定が可能なバージョンのToStringメソッドが提供されています。書式を、ToStringの引数として渡します。
var n = 1980;
Console.WriteLine(n.ToString("d")); // 1980
Console.WriteLine(n.ToString("x")); // 7bc
var x = 0.12;
Console.WriteLine(x.ToString("f")); // 0.12
Console.WriteLine(x.ToString("e")); // 1.200000e-001
"d" などが書式です。
書式の書き方については後程改めて説明します。
複合書式(string.Format)
stringクラスのFormat静的メソッドで、複数の値をまとめて書式設定することができます。
var x = 7;
var y = 13;
var line = string.Format("{0} × {1} = {2}", x, y, x * y);
Console.WriteLine(line); // 7 × 13 = 91
1つ目の引数が書式で、2つ目以降の引数を、それぞれ、{0}、{1}、{2} の部分に展開します。
内の数字は、何番目の引数を参照するかのインデックス(0 始まり)を表します。
Console.Writeや、StreamWriter.Writeなど、内部的にstring.Formatを呼び出してくれる(=文字列整形の挙動は string.Format と同じ)ものもあります。
Console.WriteLine("({0}, {1})", 1, 2); // (1, 2)
インデックスに続けて、,(コンマ)で区切って幅を指定することもできます。この時、正の数を指定すると右詰め、負の数を指定すると左詰めになります。
Console.WriteLine("({0,-5}) ({1,5})", 1, 1); // (1 ) ( 1)
また、インデックスに続けて、: (コロン)で区切って、個別の書式(= ToString メソッドに渡す書式)を指定できます。
Console.WriteLine("{0:x}, {1:c}", 123, 123); // 7b, \123
//↑ "{0}, {1}", 123.ToString("x"), 123.ToString("c") と同じ扱い
それでは、個別の書式についてみていきましょう。
数値書式(標準)
整数
dは10進数、xは16進数を表します。xを大文字にするか小文字にするかで、16進数のa~fの大小を選べます。
// d:10進数、0詰め桁数指定
Console.WriteLine("{0:d}, {0:d4}", 5); // 5, 0005
// x: 16進数、0詰め桁数指定
Console.WriteLine("{0:x}, {0:X}, {0:x4}, {0:X4}", 140); // 8c, 8C, 008c, 008C
浮動小数点数
fで固定小数点表示、eで指数表記を表します。また、gで、fとeのどちらか、簡潔な方を自動選択してくれます。
// f: 小数点、小数点以下の桁数指定
Console.WriteLine("{0:f}, {0:f5}", 0.1234); // 0.12, 0.12340
// e: 指数表記、精度指定
Console.WriteLine("{0:e}, {0:e2}, {0:E2}", 0.1234); // 1.234000e-001, 1.23e-001, 1.23E-001
// g: f か e かを自動選択
Console.WriteLine("{0:g}, {1:g}", 1200000000000000.0, 0.12); // 1.2e+15, 0.12
その他
適宜桁区切り、通貨記号などをはさんでくれるn、cや、精度を自動判定してくれるr、パーセント化してくれるpなども利用できます。
// n: 適宜、桁区切りなどを挿入、小数点以下の桁数指定
Console.WriteLine("{0:n}, {0:n0}", 1234567); // 1,234,567.00, 1,234,567
// c: 通貨
Console.WriteLine("{0:c}", 1234567); // \1,234,567
// r: 復元するのに十分な桁数で出力
Console.WriteLine("{0:r}", 0.1234567890123456789f); // 0.123456791
// p: パーセント表示、小数点以下の桁数指定
Console.WriteLine("{0:p1}", 0.1234); // 12.30%
- 参考:標準の数値書式指定文字列
数値書式(カスタム)
数値は、0や#(ナンバー記号)などを使って、かなり自由な書式を作れます。
// 桁数を明示。0. の 0 は省略
Console.WriteLine("{0:#.##}", 0.2345); // .23
// 0詰め4ケタ.4ケタ
Console.WriteLine("{0:0000.0000}", 1.23); // 0001.2300
// 3ケタ区切り、小数点以下0詰め2ケタ
Console.WriteLine("{0:#,#.00}", 1234567); // 1,234,567.00
日付の書式
DateTime 型、DateTimeOffset 型に対しても、標準書式("d"など)や、カスタム書式("y/M/d" など)を設定できます。
var d = new DateTime(2008, 5, 4, 8, 30, 0);
Console.WriteLine(d.ToString("d")); // 2008/05/04
Console.WriteLine(d.ToString("D")); // 2008年5月4日
var d = new DateTime(2008, 5, 4, 8, 30, 0);
Console.WriteLine(d.ToString("y/M/d h:m:s")); // 8/5/4 8:30:0
Console.WriteLine(d.ToString("hh:mm:ss")); // 08:30:00
Console.WriteLine(d.ToString("yy/MM/dd")); // 08/05/04 8:30:0
Console.WriteLine(d.ToString("yyyy/MM/dd")); // 2008/12/04
Console.WriteLine(d.ToString("ddd dddd")); // 日 日曜日
カスタム書式で、 / や : などの記号は自由な位置に挿入できます。
その他、以下の文字は特別な意味を持ちます。
| 記号 | 意味 |
|---|---|
y, yy, yyyy |
年。それぞれ、下2桁(2桁目が0なら1ケタ)、下2桁(2桁目は0詰め)、4ケタ表示。 |
M, MM |
月。2文字並べた場合、0を挿入して2ケタにする(以下の、dd などでも同様)。 |
d, dd |
日。 |
h, hh |
時(12時間形式)。 |
H, HH |
時(24時間形式)。 |
m, mm |
分。 |
s, ss |
秒。 |
f |
秒の小数点以下。欲しい桁数分、f を並べる。 |
ddd, dddd |
曜日。ddd が省略名(mon とか 月 とか)、dddd が完全名(Monday とか 月曜日 とか)。 |
MMM, MMMM |
月名。MMM が省略名(Jun とか 1 とか)、MMMM が完全名(Junuary とか 5月 とか)。 |
t, tt |
AM か PM か。日本語カルチャーで t (省略名)を使うと残念なことに(午前でも午後でも「午」と表示)。 |
g |
年号。 |
K |
タイム ゾーン。 |
書式とカルチャー
注意点として、文字列の書式設定の結果は、カルチャーに依存します。
例えば、金額表示(通貨書式 "c" を使う)を考えてみましょう。
世界各国の通販サイトでも覗いていただけるとわかるんですが、以下のような部分が、国によってすべて異なります。
小数点以下の有無
小数点に使う記号
3ケタずつの区切りに使う記号
通貨記号
負の数の表し方
"c" 書式を使うと、金額に対して、カルチャーごとに最適な整形を掛けてくれます。
using System;
using System.Globalization;
class Program
{
static void Main()
{
var cultures = new[] { "ja-jp", "zh-cn", "en-us", "en-gb", "fr-fr", "de-de", "pt-br", "tr-tr", "he-il" };
var price = 9800;
foreach (var c in cultures)
{
var culture = new CultureInfo(c);
var plus = price.ToString("c", culture);
var minus = (-price).ToString("c", culture);
Console.WriteLine("{0,-11} / {1,-12} ({2})", plus, minus, culture.DisplayName);
}
}
}
¥9,800 / -¥9,800 (日本語 (日本))
¥9,800.00 / ¥-9,800.00 (中国語 (中華人民共和国))
$9,800.00 / ($9,800.00) (英語 (米国))
£9,800.00 / -£9,800.00 (英語 (英国))
9 800,00 € / -9 800,00 € (フランス語 (フランス))
9.800,00 € / -9.800,00 € (ドイツ語 (ドイツ))
R$ 9.800,00 / -R$ 9.800,00 (ポルトガル語 (ブラジル))
9.800,00 TL / -9.800,00 TL (トルコ語 (トルコ))
₪ 9,800.00 / ₪-9,800.00 (ヘブライ語 (イスラエル))
ちなみに、特にカルチャーを指定しなかった場合、OS 設定のカルチャー(日本語 Windows を使っているなら、デフォルトでは当然日本語)に基づいて整形します。
通貨に限らず、小数点や区切り文字、日付の書式などは文化の影響を受けます。

