目次

概要

数値を整形して表示したいことがあります。 例えば、19800 という数値に対して、

  • 数字のみ: 19800

  • 3ケタごとにコンマ区切り: 19,800

  • 指数表記: 1.98e4

など、いろんな表示の仕方があります。

.NET では、ToString メソッドや、string.Format 静的メソッドなどに対して、書式を与えることで、数値の表示の仕方を変えることができます。 また、WPF や Silverlight のデータ バインディングでも、書式設定ができます。

データ バインディングにおける書式設定。
データ バインディングにおける書式設定。

参考:

ToString メソッド

C#では、数値などから文字列への型変換は、そのままではできません。しかし、objectクラスがToStringというメソッドを持っていて、これで文字列化できます。

自作の型を文字列化したい場合は、以下のように、ToStringメソッドをオーバーライドします。

  • C#
  • VB
  • C++
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 + ")";
  }
};

以下のように利用できます。

  • C#
  • VB
  • C++
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 を使っているなら、デフォルトでは当然日本語)に基づいて整形します。

通貨に限らず、小数点や区切り文字、日付の書式などは文化の影響を受けます。

更新履歴

ブログ