C# String.Formatの使い方完全ガイド|0埋め・桁数指定・日付・数値の書式指定をサンプルで解説
はじめに
C#で文字列を組み立てるとき、変数の値をそのまま連結するだけではなく、「数値を3桁区切りにしたい」「IDを0埋めしたい」「日付をyyyy/MM/dd形式にしたい」「一覧を桁揃えしたい」といった場面がよくあります。
そのようなときに使える代表的な方法がString.Formatです。String.Formatは、指定した書式に従って値を文字列化し、テンプレート内のプレースホルダーへ埋め込むメソッドです。Microsoftのドキュメントでも、String.Formatは値を書式指定に基づいて文字列へ変換し、別の文字列へ挿入するメソッドとして説明されています。
この記事では、C#のString.Formatについて、基本構文から0埋め、桁数指定、日付、数値、カンマ区切り、パーセント、通貨、エラー対処まで、実務で使いやすいサンプルを交えて解説します。
1. C# String.Formatとは?文字列を書式指定して整形する基本
String.Formatは、文字列の中に{0}や{1}のようなプレースホルダーを置き、そこに引数の値を埋め込んで新しい文字列を作るメソッドです。
C#string name = "田中";
int age = 30;
string message = String.Format("名前は{0}、年齢は{1}歳です。", name, age);
Console.WriteLine(message);
// 名前は田中、年齢は30歳です。
単純な文字列結合よりも、文章の形を保ったまま値だけを差し替えられるため、メッセージ、ログ、帳票、画面表示などで便利です。
1-1. String.Formatでできること
String.Formatでは、主に次のようなことができます。
C#int number = 123;
double price = 1234.5;
DateTime date = new DateTime(2026, 6, 6, 9, 5, 3);
Console.WriteLine(String.Format("番号: {0:D5}", number));
Console.WriteLine(String.Format("価格: {0:N2}", price));
Console.WriteLine(String.Format("日時: {0:yyyy/MM/dd HH:mm:ss}", date));
実行結果は次のようになります。
番号: 00123
価格: 1,234.50
日時: 2026/06/06 09:05:03
このように、String.Formatでは値を埋め込むだけでなく、数値や日付の表示形式も同時に指定できます。.NETの複合書式指定では、固定文字列と書式項目を組み合わせ、複数の値を1つの文字列に整形できます。
1-2. 「{0}」「{1}」などのプレースホルダーの意味
{0}や{1}は、String.Formatに渡した引数の位置を表します。番号は0から始まります。
C#string result = String.Format("{0}さんは{1}点です。", "佐藤", 85);
Console.WriteLine(result);
// 佐藤さんは85点です。
この場合、{0}には1番目の引数である"佐藤"、{1}には2番目の引数である85が入ります。
C#String.Format("名前: {0}, 点数: {1}", "佐藤", 85);
対応関係は次のとおりです。
{0} → "佐藤"
{1} → 85
1-3. String.Formatの基本構文
String.Formatの基本構文は次のとおりです。
C#String.Format("文字列 {0} 文字列 {1}", 値1, 値2);
書式指定まで含める場合は、次の形になります。
C#String.Format("{index,alignment:format}", value);
各要素の意味は次のとおりです。
| 要素 | 意味 | 例 |
|---|---|---|
index | 引数の番号 | {0} |
alignment | 表示幅・右寄せ・左寄せ | {0,10} |
format | 数値や日付の書式 | {0:D5} |
.NETの複合書式指定では、書式項目は{index[,alignment][:formatString]}という形で表されます。
1-4. 複数の値を埋め込むサンプル
複数の値を埋め込む場合は、{0}、{1}、{2}のように番号を増やします。
C#string product = "ノートPC";
int quantity = 2;
decimal price = 98000m;
string message = String.Format(
"商品: {0}, 数量: {1}, 単価: {2:N0}円",
product,
quantity,
price
);
Console.WriteLine(message);
// 商品: ノートPC, 数量: 2, 単価: 98,000円
数値にN0を指定すると、3桁区切りで小数点以下0桁の表示になります。標準数値書式指定子は、数値型を文字列表現に変換するために使われます。
1-5. String.Formatを使うメリットと主な利用シーン
String.Formatを使うメリットは、文字列の構造と値を分離できることです。
C#string userName = "山田";
int point = 1200;
string message = String.Format("{0}さんの現在のポイントは{1:N0}ptです。", userName, point);
文字列結合で書くと次のようになります。
C#string message = userName + "さんの現在のポイントは" + point.ToString("N0") + "ptです。";
短いコードであればどちらでも問題ありませんが、値が増えたり書式指定が必要になったりすると、String.Formatのほうが文章全体の形を把握しやすくなります。
主な利用シーンは次のような場面です。
| 利用シーン | 例 |
|---|---|
| ログ出力 | 日時、レベル、メッセージを整形 |
| 画面表示 | 金額、割合、日付を見やすく表示 |
| ファイル名生成 | 日時や連番を含める |
| 帳票・CSV出力 | 数値や日付の形式を統一 |
| メール本文作成 | ユーザー名や注文番号を埋め込む |
2. C# String.Formatの基本的な使い方
String.Formatの基本は、「テンプレート文字列」と「埋め込む値」を渡すことです。
C#string text = String.Format("こんにちは、{0}さん。", "鈴木");
Console.WriteLine(text);
// こんにちは、鈴木さん。
テンプレート文字列の中にある{0}が、後ろに指定した値で置き換わります。
2-1. 文字列に変数を埋め込む方法
変数を埋め込む場合も、直接値を書く場合と同じです。
C#string name = "高橋";
string department = "営業部";
string message = String.Format("{0}さんは{1}に所属しています。", name, department);
Console.WriteLine(message);
// 高橋さんは営業部に所属しています。
String.Formatでは、文字列、数値、日付、真偽値など、さまざまな値を埋め込めます。
C#bool isActive = true;
string result = String.Format("ユーザー: {0}, 有効: {1}", name, isActive);
Console.WriteLine(result);
// ユーザー: 高橋, 有効: True
2-2. 引数の順番とインデックス指定の関係
String.Formatでは、プレースホルダーの番号と引数の順番が対応します。
C#string result = String.Format("{0} {1} {2}", "A", "B", "C");
Console.WriteLine(result);
// A B C
番号を入れ替えると、表示順も変わります。
C#string result = String.Format("{2} {1} {0}", "A", "B", "C");
Console.WriteLine(result);
// C B A
この特徴を使うと、同じ値を別の順番で表示できます。
C#string result = String.Format("姓: {0}, 名: {1}, 表示名: {0} {1}", "山田", "太郎");
Console.WriteLine(result);
// 姓: 山田, 名: 太郎, 表示名: 山田 太郎
2-3. 同じ値を複数回表示する方法
同じ値を複数回表示したい場合は、同じインデックスを何度も使えます。
C#string name = "田中";
string message = String.Format("{0}さん、こんにちは。{0}さんのログインを確認しました。", name);
Console.WriteLine(message);
// 田中さん、こんにちは。田中さんのログインを確認しました。
同じ値を繰り返し渡す必要はありません。
C#// 不要な書き方
String.Format("{0}さん、こんにちは。{1}さんのログインを確認しました。", name, name);
// シンプルな書き方
String.Format("{0}さん、こんにちは。{0}さんのログインを確認しました。", name);
2-4. 書式指定の基本ルール「{index,alignment:format}」
String.Formatの書式指定は、次の形を覚えると理解しやすくなります。
C#{index,alignment:format}
例を見てみましょう。
C#int number = 123;
Console.WriteLine(String.Format("{0}", number)); // 123
Console.WriteLine(String.Format("{0,10}", number)); // 123
Console.WriteLine(String.Format("{0:D5}", number)); // 00123
Console.WriteLine(String.Format("{0,10:D5}", number)); // 00123
それぞれの意味は次のとおりです。
{0} → 0番目の値をそのまま表示
{0,10} → 0番目の値を幅10で右寄せ
{0:D5} → 0番目の値を5桁で0埋め
{0,10:D5} → 5桁で0埋めした値を幅10で右寄せ
2-5. Console.WriteLineでString.Formatと同じ書式を使う方法
Console.WriteLineには、String.Formatと同じような複合書式指定を使えるオーバーロードがあります。
C#string name = "佐藤";
int score = 95;
Console.WriteLine("{0}さんの点数は{1}点です。", name, score);
// 佐藤さんの点数は95点です。
次の2つは、ほぼ同じ目的で使えます。
C#Console.WriteLine(String.Format("{0}さんの点数は{1}点です。", name, score));
Console.WriteLine("{0}さんの点数は{1}点です。", name, score);
コンソールに直接出力するだけなら、Console.WriteLineに書式と値をそのまま渡すほうが簡潔です。一方、文字列として変数に保持したい場合はString.Formatを使います。
3. 数値をString.Formatで書式指定する方法
数値の書式指定は、String.Formatの中でも特によく使われます。小数点以下の桁数、カンマ区切り、通貨、パーセント、16進数などを簡単に指定できます。
C#double value = 1234.567;
Console.WriteLine(String.Format("{0:F2}", value)); // 1234.57
Console.WriteLine(String.Format("{0:N2}", value)); // 1,234.57
.NETの標準数値書式指定文字列は、[format specifier][precision specifier]という形で表されます。
3-1. 整数を表示する基本サンプル
整数をそのまま表示する場合は、単純に{0}を使います。
C#int count = 150;
string result = String.Format("件数: {0}", count);
Console.WriteLine(result);
// 件数: 150
整数に書式指定を付けることもできます。
C#int count = 150;
Console.WriteLine(String.Format("{0:D}", count)); // 150
Console.WriteLine(String.Format("{0:D5}", count)); // 00150
Dは10進数を表す標準数値書式指定子で、整数の0埋めによく使われます。
3-2. 小数点以下の桁数を指定する方法
小数点以下の桁数を指定するには、Fを使います。
C#double value = 123.4567;
Console.WriteLine(String.Format("{0:F0}", value)); // 123
Console.WriteLine(String.Format("{0:F1}", value)); // 123.5
Console.WriteLine(String.Format("{0:F2}", value)); // 123.46
Console.WriteLine(String.Format("{0:F3}", value)); // 123.457
F2は「小数点以下2桁で表示する」という意味です。
C#decimal price = 1200m;
string result = String.Format("{0:F2}", price);
Console.WriteLine(result);
// 1200.00
小数点以下を必ず2桁表示したい金額や計算結果に向いています。
3-3. 四捨五入されるケースと注意点
小数点以下の桁数を指定すると、表示される値は指定桁数に丸められます。
C#double value = 1.236;
Console.WriteLine(String.Format("{0:F2}", value));
// 1.24
ただし、表示上の丸めと、業務ロジック上の丸めは分けて考えるべきです。請求金額や税額など、丸めルールが重要な処理では、先にMath.Roundなどで明示的に丸めてから表示するほうが安全です。
C#decimal tax = 123.456m;
decimal rounded = Math.Round(tax, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(String.Format("{0:F2}", rounded));
// 123.46
String.Formatは表示を整えるための機能であり、計算ルールそのものを管理するためのものではありません。
3-4. 3桁区切りのカンマを付ける方法
3桁区切りのカンマを付けるには、Nを使います。
C#int amount = 1234567;
Console.WriteLine(String.Format("{0:N0}", amount));
// 1,234,567
小数点以下2桁まで表示する場合はN2です。
C#double amount = 1234567.89;
Console.WriteLine(String.Format("{0:N2}", amount));
// 1,234,567.89
金額や件数をユーザーに見せる場合、カンマ区切りにすると読みやすくなります。
C#decimal total = 9876543m;
string message = String.Format("合計金額は{0:N0}円です。", total);
Console.WriteLine(message);
// 合計金額は9,876,543円です。
3-5. パーセント表示にする方法
パーセント表示にはPを使います。
C#double rate = 0.1234;
Console.WriteLine(String.Format("{0:P0}", rate)); // 12%
Console.WriteLine(String.Format("{0:P1}", rate)); // 12.3%
Console.WriteLine(String.Format("{0:P2}", rate)); // 12.34%
Pは値を100倍してパーセント記号付きで表示します。
C#double taxRate = 0.10;
string message = String.Format("消費税率: {0:P0}", taxRate);
Console.WriteLine(message);
// 消費税率: 10%
すでに10という値を持っている場合にP0を使うと1,000%のようになるため注意が必要です。
C#double rate = 10;
Console.WriteLine(String.Format("{0:P0}", rate));
// 1,000%
パーセント書式を使う場合は、0.1を10%として扱うイメージで使います。
3-6. 通貨形式で表示する方法
通貨形式にはCを使います。
C#decimal price = 1234.5m;
Console.WriteLine(String.Format("{0:C}", price));
通貨記号や桁区切り、小数点の扱いは、実行環境のカルチャによって変わります。標準数値書式指定では、通貨、10進数、固定小数点、数値、パーセント、16進数などの書式指定子が用意されています。
日本の形式で明示的に表示したい場合は、CultureInfoを指定します。
C#using System.Globalization;
decimal price = 1234.5m;
string result = String.Format(
CultureInfo.GetCultureInfo("ja-JP"),
"{0:C}",
price
);
Console.WriteLine(result);
// ¥1,235
小数点以下を0桁にしたい場合はC0を使います。
C#Console.WriteLine(String.Format(
CultureInfo.GetCultureInfo("ja-JP"),
"{0:C0}",
1234.5m
));
// ¥1,235
3-7. 16進数で表示する方法
16進数で表示するにはXまたはxを使います。
C#int number = 255;
Console.WriteLine(String.Format("{0:X}", number)); // FF
Console.WriteLine(String.Format("{0:x}", number)); // ff
桁数を指定すると、足りない桁が0で埋められます。
C#int number = 255;
Console.WriteLine(String.Format("{0:X4}", number));
// 00FF
色コード、バイト列、デバッグ情報などを表示するときに便利です。
C#byte r = 255;
byte g = 128;
byte b = 0;
string colorCode = String.Format("#{0:X2}{1:X2}{2:X2}", r, g, b);
Console.WriteLine(colorCode);
// #FF8000
4. 0埋め・桁数指定をString.Formatで行う方法
String.Formatで検索されることが多いテーマの1つが、0埋めです。連番、注文番号、会員ID、ファイル名などでよく使います。
C#int id = 42;
Console.WriteLine(String.Format("{0:D5}", id));
// 00042
D5は、整数を5桁で表示し、足りない桁を0で埋める指定です。
4-1. 整数を0埋めする基本サンプル
整数を0埋めする基本はDを使う方法です。
C#int number = 7;
string result = String.Format("{0:D3}", number);
Console.WriteLine(result);
// 007
D3は3桁、D5は5桁、D8は8桁のように指定します。
C#int number = 123;
Console.WriteLine(String.Format("{0:D3}", number)); // 123
Console.WriteLine(String.Format("{0:D5}", number)); // 00123
Console.WriteLine(String.Format("{0:D8}", number)); // 00000123
指定した桁数より元の数値の桁数が多い場合、数値が切り捨てられることはありません。
C#int number = 123456;
Console.WriteLine(String.Format("{0:D3}", number));
// 123456
4-2. 「D5」で5桁の0埋めをする方法
5桁の0埋めは、次のように書きます。
C#int id = 25;
string formatted = String.Format("{0:D5}", id);
Console.WriteLine(formatted);
// 00025
実務では、注文番号や連番に接頭辞を付けることも多いです。
C#int orderNo = 25;
string orderCode = String.Format("ORD-{0:D5}", orderNo);
Console.WriteLine(orderCode);
// ORD-00025
Dは整数向けの標準書式指定子です。小数値に使うのではなく、intやlongなどの整数値に使うと覚えておくとよいでしょう。
4-3. 「00000」などカスタム書式で0埋めする方法
0埋めは、カスタム数値書式でも指定できます。
C#int number = 25;
Console.WriteLine(String.Format("{0:00000}", number));
// 00025
00000は「5桁分の数字を表示し、足りない部分は0で埋める」という意味です。カスタム数値書式指定文字列では、0や#などの指定子を組み合わせて、数値データの表示方法を定義できます。
D5と00000は、単純な整数の0埋めでは似た結果になります。
C#int number = 25;
Console.WriteLine(String.Format("{0:D5}", number)); // 00025
Console.WriteLine(String.Format("{0:00000}", number)); // 00025
通常の整数IDならD5、より細かい表示制御をしたい場合はカスタム書式を使うとよいでしょう。
4-4. 桁数を変数で指定する方法
桁数を変数で指定したい場合は、書式文字列自体を組み立てます。
C#int number = 25;
int digits = 6;
string format = "{0:D" + digits + "}";
string result = String.Format(format, number);
Console.WriteLine(result);
// 000025
文字列補間を使って書式文字列を作ることもできます。
C#int number = 25;
int digits = 6;
string result = String.Format($"{{0:D{digits}}}", number);
Console.WriteLine(result);
// 000025
ここではString.Format用の波括弧を文字として扱う必要があるため、{{と}}を使っています。波括弧のエスケープについては、後半で詳しく解説します。
4-5. 0埋めした連番・ID・ファイル名を作る実用例
0埋めは、連番ファイルやログファイルの生成でよく使います。
C#for (int i = 1; i <= 5; i++)
{
string fileName = String.Format("image_{0:D4}.png", i);
Console.WriteLine(fileName);
}
実行結果は次のとおりです。
image_0001.png
image_0002.png
image_0003.png
image_0004.png
image_0005.png
注文番号の例です。
C#int orderId = 123;
string orderCode = String.Format("ORDER-{0:D8}", orderId);
Console.WriteLine(orderCode);
// ORDER-00000123
会員IDの例です。
C#int memberId = 987;
string memberCode = String.Format("M{0:D6}", memberId);
Console.WriteLine(memberCode);
// M000987
4-6. 0埋めと空白埋めの違い
0埋めと空白埋めは似ていますが、目的が違います。
C#int number = 123;
Console.WriteLine(String.Format("{0:D5}", number)); // 00123
Console.WriteLine(String.Format("{0,5}", number)); // 123
D5は数値そのものを5桁の0埋めで表示します。一方、{0,5}は表示幅を5文字分にして右寄せします。足りない部分は空白になります。
一覧表示では空白埋め、ID生成では0埋めを使うことが多いです。
C#Console.WriteLine(String.Format("ID:{0:D5}", number)); // ID:00123
Console.WriteLine(String.Format("No:{0,5}", number)); // No: 123
4-7. 負の数を0埋めするときの表示例
負の数を0埋めすると、マイナス記号が先頭に付き、数値部分が0埋めされます。
C#int number = -12;
Console.WriteLine(String.Format("{0:D5}", number));
// -00012
カスタム書式でも同様に、符号が付いた表示になります。
C#int number = -12;
Console.WriteLine(String.Format("{0:00000}", number));
// -00012
負の数を扱う可能性があるIDやコードでは、マイナス値を許可する設計なのか、事前にチェックすべきなのかを決めておきましょう。
C#int id = -12;
if (id < 0)
{
throw new ArgumentOutOfRangeException(nameof(id), "IDには0以上の値を指定してください。");
}
string code = String.Format("{0:D5}", id);
5. 文字列の桁数・右寄せ・左寄せを指定する方法
String.Formatでは、数値だけでなく文字列の表示幅も指定できます。ログや一覧表をコンソールに出すときに便利です。
C#Console.WriteLine(String.Format("|{0,10}|", "ABC"));
Console.WriteLine(String.Format("|{0,-10}|", "ABC"));
実行結果は次のようになります。
| ABC|
|ABC |
5-1. alignmentを使って表示幅を指定する
表示幅は、プレースホルダーのカンマの後に指定します。
C#string name = "Alice";
Console.WriteLine(String.Format("|{0,10}|", name));
// | Alice|
{0,10}は「0番目の値を幅10で右寄せ」という意味です。
数値でも同じように使えます。
C#int score = 95;
Console.WriteLine(String.Format("|{0,5}|", score));
// | 95|
5-2. 正の値で右寄せする方法
alignmentに正の値を指定すると右寄せになります。
C#Console.WriteLine(String.Format("|{0,10}|", "A"));
Console.WriteLine(String.Format("|{0,10}|", "ABC"));
Console.WriteLine(String.Format("|{0,10}|", "ABCDE"));
実行結果です。
| A|
| ABC|
| ABCDE|
数値の列を右寄せすると、桁の位置が揃って見やすくなります。
C#Console.WriteLine(String.Format("{0,10}", 100));
Console.WriteLine(String.Format("{0,10}", 2500));
Console.WriteLine(String.Format("{0,10}", 30000));
100
2500
30000
5-3. 負の値で左寄せする方法
alignmentに負の値を指定すると左寄せになります。
C#Console.WriteLine(String.Format("|{0,-10}|", "A"));
Console.WriteLine(String.Format("|{0,-10}|", "ABC"));
Console.WriteLine(String.Format("|{0,-10}|", "ABCDE"));
実行結果です。
|A |
|ABC |
|ABCDE |
名前やカテゴリなど、文字列の列を左寄せしたい場合に便利です。
C#Console.WriteLine(String.Format("{0,-10} {1,5}", "Apple", 120));
Console.WriteLine(String.Format("{0,-10} {1,5}", "Orange", 80));
Console.WriteLine(String.Format("{0,-10} {1,5}", "Banana", 100));
Apple 120
Orange 80
Banana 100
5-4. 表形式のログや一覧表示を整えるサンプル
コンソールやログに一覧を出す場合、alignmentを使うと見やすい表形式にできます。
C#Console.WriteLine(String.Format("{0,-10} {1,8} {2,10}", "商品", "数量", "金額"));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "りんご", 3, 300));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "みかん", 12, 1200));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "バナナ", 5, 500));
出力例です。
商品 数量 金額
りんご 3 300
みかん 12 1,200
バナナ 5 500
数値は右寄せ、文字列は左寄せにすると読みやすくなります。
5-5. 日本語文字列を整列するときの注意点
日本語をコンソールで桁揃えする場合、英数字と同じように揃わないことがあります。理由は、alignmentが表示上の横幅ではなく、基本的には文字列の長さをもとに幅を扱うためです。
C#Console.WriteLine(String.Format("|{0,-10}|{1,5}|", "Apple", 100));
Console.WriteLine(String.Format("|{0,-10}|{1,5}|", "りんご", 100));
Console.WriteLine(String.Format("|{0,-10}|{1,5}|", "バナナ", 100));
環境によっては、日本語が全角幅で表示されるため、見た目の位置がずれることがあります。
厳密に日本語の表示幅を揃えたい場合は、文字数ではなく表示幅を計算する処理を別途用意する必要があります。ログや簡易表示ならString.Formatで十分なことも多いですが、ユーザー向けの表や帳票では専用のレイアウト機能を使うほうが安全です。
6. 日付・時刻をString.Formatで書式指定する方法
DateTimeの表示形式を指定する場合も、String.Formatが使えます。
C#DateTime now = new DateTime(2026, 6, 6, 9, 5, 3);
Console.WriteLine(String.Format("{0:yyyy/MM/dd}", now));
Console.WriteLine(String.Format("{0:HH:mm:ss}", now));
Console.WriteLine(String.Format("{0:yyyy/MM/dd HH:mm:ss}", now));
実行結果です。
2026/06/06
09:05:03
2026/06/06 09:05:03
カスタム日時書式指定文字列は、DateTimeやDateTimeOffsetの値をテキスト表現へ変換するために使用できます。
6-1. DateTimeを基本形式で表示する方法
DateTimeをそのまま{0}で表示すると、現在のカルチャに応じた形式で表示されます。
C#DateTime date = new DateTime(2026, 6, 6, 9, 5, 3);
Console.WriteLine(String.Format("{0}", date));
出力形式は環境によって変わる可能性があります。そのため、ログやファイル名など、形式を固定したい場面では明示的に書式を指定するのがおすすめです。
C#Console.WriteLine(String.Format("{0:yyyy-MM-dd HH:mm:ss}", date));
// 2026-06-06 09:05:03
6-2. yyyy/MM/dd形式で日付を表示する
日付をyyyy/MM/dd形式で表示するには、次のように書きます。
C#DateTime date = new DateTime(2026, 6, 6);
string result = String.Format("{0:yyyy/MM/dd}", date);
Console.WriteLine(result);
// 2026/06/06
各指定子の意味は次のとおりです。
| 指定子 | 意味 | 例 |
|---|---|---|
yyyy | 4桁の年 | 2026 |
MM | 2桁の月 | 06 |
dd | 2桁の日 | 06 |
ハイフン区切りにしたい場合は、次のようにします。
C#Console.WriteLine(String.Format("{0:yyyy-MM-dd}", date));
// 2026-06-06
6-3. HH:mm:ss形式で時刻を表示する
時刻をHH:mm:ss形式で表示するには、次のように書きます。
C#DateTime time = new DateTime(2026, 6, 6, 9, 5, 3);
string result = String.Format("{0:HH:mm:ss}", time);
Console.WriteLine(result);
// 09:05:03
各指定子の意味は次のとおりです。
| 指定子 | 意味 | 例 |
|---|---|---|
HH | 24時間表記の時 | 09 |
mm | 分 | 05 |
ss | 秒 | 03 |
12時間表記にしたい場合はhhを使います。
C#Console.WriteLine(String.Format("{0:hh:mm:ss tt}", time));
// 09:05:03 AM
6-4. 年月日・曜日を含めて表示する
曜日を含めたい場合は、dddまたはddddを使います。
C#DateTime date = new DateTime(2026, 6, 6);
Console.WriteLine(String.Format("{0:yyyy年MM月dd日 ddd}", date));
Console.WriteLine(String.Format("{0:yyyy年MM月dd日 dddd}", date));
日本語の曜日名で表示したい場合は、カルチャを指定します。
C#using System.Globalization;
DateTime date = new DateTime(2026, 6, 6);
string result = String.Format(
CultureInfo.GetCultureInfo("ja-JP"),
"{0:yyyy年MM月dd日 dddd}",
date
);
Console.WriteLine(result);
// 2026年06月06日 土曜日
曜日名や月名はカルチャの影響を受けます。標準日時書式指定でも、短い日付や長い日付などはカルチャに定義されたパターンに基づきます。
6-5. ログ出力向けの日時フォーマット例
ログ出力では、並び替えや検索がしやすい形式がよく使われます。
C#DateTime now = DateTime.Now;
string log = String.Format("[{0:yyyy-MM-dd HH:mm:ss}] 処理を開始しました。", now);
Console.WriteLine(log);
// [2026-06-06 09:05:03] 処理を開始しました。
ミリ秒まで含める場合はfffを使います。
C#DateTime now = DateTime.Now;
string log = String.Format("[{0:yyyy-MM-dd HH:mm:ss.fff}] 処理を開始しました。", now);
Console.WriteLine(log);
ファイル名に使う場合は、/や:を避けるのがポイントです。
C#DateTime now = DateTime.Now;
string fileName = String.Format("log_{0:yyyyMMdd_HHmmss}.txt", now);
Console.WriteLine(fileName);
// log_20260606_090503.txt
6-6. 月と分の「M」「m」を間違えないための注意点
日付書式でよくあるミスが、月のMと分のmの混同です。
C#DateTime date = new DateTime(2026, 6, 6, 9, 5, 3);
Console.WriteLine(String.Format("{0:yyyy/MM/dd HH:mm}", date));
// 2026/06/06 09:05
月は大文字のM、分は小文字のmです。
MM → 月
mm → 分
間違えると、意図しない表示になります。
C#Console.WriteLine(String.Format("{0:yyyy/mm/dd}", date));
// 2026/05/06 のように、月の位置に「分」が出る
日付ではyyyy/MM/dd、時刻ではHH:mm:ssとセットで覚えると間違いにくくなります。
6-7. カルチャによって表示が変わる日付形式
dやDなどの標準日時書式は、カルチャによって表示が変わります。
C#using System.Globalization;
DateTime date = new DateTime(2026, 6, 6);
Console.WriteLine(String.Format(CultureInfo.GetCultureInfo("ja-JP"), "{0:D}", date));
Console.WriteLine(String.Format(CultureInfo.GetCultureInfo("en-US"), "{0:D}", date));
日本語環境と英語環境では、曜日や月名、日付の並びが変わります。
形式を固定したい場合は、yyyy-MM-ddやyyyy/MM/ddのようなカスタム書式を使います。
C#Console.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0:yyyy-MM-dd}", date));
// 2026-06-06
ログ、CSV、API連携などでは、カルチャに依存しない形式を選ぶことが重要です。
7. 標準書式指定子とカスタム書式指定子の違い
String.Formatの書式指定には、大きく分けて「標準書式指定子」と「カスタム書式指定子」があります。
C#int number = 1234;
Console.WriteLine(String.Format("{0:N0}", number)); // 標準書式
Console.WriteLine(String.Format("{0:#,0}", number)); // カスタム書式
標準書式は短く書ける決まった形式、カスタム書式は細かく表示を制御する形式です。
7-1. 標準数値書式指定子とは
標準数値書式指定子は、D、N、F、C、P、Xなど、あらかじめ決められた文字で数値の表示形式を指定する方法です。
C#double value = 1234.567;
Console.WriteLine(String.Format("{0:F2}", value)); // 1234.57
Console.WriteLine(String.Format("{0:N2}", value)); // 1,234.57
Console.WriteLine(String.Format("{0:P1}", 0.123)); // 12.3%
標準数値書式指定文字列は、一般的な数値型をテキスト表現へ書式設定するための機能です。
7-2. D・N・F・C・P・Xの使い分け
よく使う標準数値書式指定子は次のとおりです。
| 書式 | 意味 | 例 |
|---|---|---|
D | 10進数、整数の0埋め | 00123 |
N | 数値、3桁区切り | 1,234.56 |
F | 固定小数点 | 1234.56 |
C | 通貨 | ¥1,235 |
P | パーセント | 12.3% |
X | 16進数 | FF |
サンプルです。
C#int intValue = 255;
double doubleValue = 1234.567;
double rate = 0.1234;
decimal price = 1234.5m;
Console.WriteLine(String.Format("{0:D5}", intValue)); // 00255
Console.WriteLine(String.Format("{0:N2}", doubleValue)); // 1,234.57
Console.WriteLine(String.Format("{0:F2}", doubleValue)); // 1234.57
Console.WriteLine(String.Format("{0:C0}", price)); // カルチャに応じた通貨表示
Console.WriteLine(String.Format("{0:P1}", rate)); // 12.3%
Console.WriteLine(String.Format("{0:X4}", intValue)); // 00FF
7-3. カスタム数値書式指定子とは
カスタム数値書式指定子は、0、#、.、,、%などを組み合わせて、表示形式を細かく指定する方法です。
C#double value = 1234.5;
Console.WriteLine(String.Format("{0:000000}", value)); // 001235
Console.WriteLine(String.Format("{0:#,0}", value)); // 1,235
Console.WriteLine(String.Format("{0:0.00}", value)); // 1234.50
標準書式よりも柔軟ですが、読みやすさはやや下がるため、必要な場合に使うのがおすすめです。
7-4. 0・#・.・,・%の使い方
代表的なカスタム数値書式指定子の意味は次のとおりです。
| 指定子 | 意味 | 例 |
|---|---|---|
0 | 桁がない場合も0を表示 | 00025 |
# | 桁がある場合のみ表示 | 1,234 |
. | 小数点 | 123.45 |
, | 桁区切り | 1,234 |
% | 100倍して%表示 | 12.3% |
サンプルです。
C#double value = 12.3;
Console.WriteLine(String.Format("{0:000.00}", value)); // 012.30
Console.WriteLine(String.Format("{0:###.##}", value)); // 12.3
0は足りない桁を0で埋めますが、#は不要な0を表示しません。
C#double value = 12;
Console.WriteLine(String.Format("{0:0.00}", value)); // 12.00
Console.WriteLine(String.Format("{0:#.##}", value)); // 12
7-5. 標準書式とカスタム書式はどちらを使うべきか
基本的には、標準書式で書けるものは標準書式を使うのがおすすめです。
C#// おすすめ
String.Format("{0:N0}", 1234567);
// カスタム書式でも可能
String.Format("{0:#,0}", 1234567);
標準書式は短く、意味も伝わりやすいからです。
一方、次のような場合はカスタム書式が向いています。
C#// 小数点以下を必要な場合だけ表示
String.Format("{0:0.##}", 123.4);
// 独自の0埋め形式
String.Format("{0:000-000}", 12345);
// 独自のパーセント表示
String.Format("{0:0.0%}", 0.1234);
読みやすさを優先するなら標準書式、細かい制御が必要ならカスタム書式、と使い分けましょう。
7-6. よく使う書式指定子の早見表
String.Formatでよく使う書式をまとめると、次のようになります。
| 目的 | 書き方 | 出力例 |
|---|---|---|
| そのまま表示 | {0} | 1234 |
| 5桁0埋め | {0:D5} | 01234 |
| 小数点以下2桁 | {0:F2} | 1234.50 |
| カンマ区切り | {0:N0} | 1,234 |
| カンマ区切り小数2桁 | {0:N2} | 1,234.50 |
| パーセント | {0:P1} | 12.3% |
| 通貨 | {0:C0} | ¥1,235 |
| 16進数 | {0:X2} | FF |
| 日付 | {0:yyyy/MM/dd} | 2026/06/06 |
| 時刻 | {0:HH:mm:ss} | 09:05:03 |
| 日時 | {0:yyyy-MM-dd HH:mm:ss} | 2026-06-06 09:05:03 |
| 右寄せ | {0,10} | 幅10で右寄せ |
| 左寄せ | {0,-10} | 幅10で左寄せ |
8. String.FormatとToString・文字列補間の違い
C#で書式指定を行う方法は、String.Formatだけではありません。ToStringや文字列補間もよく使われます。
C#int id = 25;
Console.WriteLine(String.Format("{0:D5}", id));
Console.WriteLine(id.ToString("D5"));
Console.WriteLine($"{id:D5}");
どれも次のように表示されます。
00025
8-1. String.FormatとToStringの違い
ToStringは、1つの値を文字列に変換するときに便利です。
C#int number = 25;
string result = number.ToString("D5");
Console.WriteLine(result);
// 00025
一方、String.Formatは複数の値を1つの文章に埋め込むときに便利です。
C#string name = "田中";
int point = 1200;
string message = String.Format("{0}さんのポイントは{1:N0}ptです。", name, point);
Console.WriteLine(message);
// 田中さんのポイントは1,200ptです。
1つの値だけならToString、文章全体を組み立てるならString.Format、と考えると分かりやすいです。
8-2. 0埋めだけならToStringが簡単なケース
0埋めした値だけが欲しい場合は、ToStringのほうが簡潔です。
C#int id = 42;
string idText = id.ToString("D5");
Console.WriteLine(idText);
// 00042
String.Formatで書くと次のようになります。
C#string idText = String.Format("{0:D5}", id);
どちらも正しいですが、単体の値を変換するだけならToString("D5")のほうがシンプルです。
8-3. String.Formatと文字列補間の違い
文字列補間は、$"..."の中に変数や式を直接埋め込む書き方です。
C#string name = "佐藤";
int score = 90;
string message = $"{name}さんの点数は{score}点です。";
Console.WriteLine(message);
// 佐藤さんの点数は90点です。
String.Formatで書くと次のようになります。
C#string message = String.Format("{0}さんの点数は{1}点です。", name, score);
文字列補間は、変数名をそのまま文章内に書けるため、どの値がどこに入るのか分かりやすいのが特徴です。MicrosoftのC#ドキュメントでも、文字列補間は複合書式指定より読みやすく便利な構文として説明されています。
8-4. $"..."で同じ書式指定を行う方法
文字列補間でも、String.Formatと同じように書式指定ができます。
C#int id = 42;
decimal price = 1234.5m;
DateTime date = new DateTime(2026, 6, 6);
Console.WriteLine($"{id:D5}");
Console.WriteLine($"{price:N0}円");
Console.WriteLine($"{date:yyyy/MM/dd}");
実行結果です。
00042
1,235円
2026/06/06
右寄せや左寄せも指定できます。
C#string name = "Apple";
int price = 120;
Console.WriteLine($"{name,-10} {price,5:N0}");
文字列補間は、複合書式指定の機能をサポートする、より読みやすい代替手段として説明されています。
8-5. 可読性・保守性で使い分けるポイント
現在のC#では、通常の文字列組み立てには文字列補間を使うことが多いです。
C#// 読みやすい
string message = $"{name}さんの点数は{score}点です。";
ただし、String.Formatが向いている場面もあります。
C#string template = "{0}さんの点数は{1}点です。";
string message = String.Format(template, name, score);
たとえば、テンプレート文字列を外部ファイルやリソースから読み込む場合は、String.Formatのほうが扱いやすいことがあります。
C#string template = "注文番号{0}の合計金額は{1:N0}円です。";
string message = String.Format(template, orderNo, total);
使い分けの目安は次のとおりです。
| 方法 | 向いている場面 |
|---|---|
ToString | 1つの値を整形する |
String.Format | テンプレートに複数値を差し込む |
| 文字列補間 | コード上で読みやすく文字列を組み立てる |
8-6. 現在のC#でおすすめの書き方
現在のC#では、コード内でメッセージを組み立てるなら、文字列補間が読みやすくおすすめです。
C#string message = $"{name}さんの購入金額は{amount:N0}円です。";
一方、テンプレートを後から差し替えたい場合や、既存コードでString.Formatが使われている場合は、String.Formatも十分に有効です。
C#string template = "{0}さんの購入金額は{1:N0}円です。";
string message = String.Format(template, name, amount);
String.Formatは古いから使ってはいけない、というものではありません。用途に応じて、ToString、String.Format、文字列補間を使い分けるのが実務的です。
9. String.Formatでよくあるエラーと対処法
String.Formatでは、プレースホルダーの番号や波括弧の書き方を間違えるとFormatExceptionが発生することがあります。
C#// エラー例
string result = String.Format("{0} {1}", "A");
{1}に対応する2番目の引数がないため、エラーになります。
9-1. FormatExceptionが発生する原因
FormatExceptionが発生する主な原因は、書式文字列が正しくないことです。
代表的な例は次のとおりです。
C#// 引数が足りない
String.Format("{0} {1}", "A");
// 波括弧が閉じていない
String.Format("{0", "A");
// 波括弧をそのまま書いている
String.Format("値は {0} }", "A");
複合書式指定では、波括弧やインデックスの書き方が決まっているため、テンプレート文字列を動的に作る場合は特に注意が必要です。
9-2. 引数の数とプレースホルダーが一致しないケース
次のコードはエラーになります。
C#string result = String.Format("名前: {0}, 年齢: {1}", "田中");
{0}には"田中"が入りますが、{1}に対応する引数がありません。
修正例です。
C#string result = String.Format("名前: {0}, 年齢: {1}", "田中", 30);
Console.WriteLine(result);
// 名前: 田中, 年齢: 30
プレースホルダーの番号は0から始まるため、{2}を使うなら少なくとも3つの引数が必要です。
C#string result = String.Format("{0}, {1}, {2}", "A", "B", "C");
9-3. 波括弧「{」「}」を文字として表示する方法
String.Formatで波括弧をそのまま表示したい場合は、{{と}}のように2つ重ねます。
C#string result = String.Format("{{0}}の値は{0}です。", 123);
Console.WriteLine(result);
// {0}の値は123です。
JSONのような文字列を作る場合にも注意が必要です。
C#string name = "Taro";
string json = String.Format("{{ \"name\": \"{0}\" }}", name);
Console.WriteLine(json);
// { "name": "Taro" }
波括弧を1つだけ書くと、String.Formatのプレースホルダーとして解釈されるため、エラーの原因になります。
9-4. 書式指定子の記述ミスを防ぐポイント
書式指定子のミスを防ぐには、よく使う形式をパターンとして覚えておくのが効果的です。
C#// ID
String.Format("{0:D5}", id);
// 金額
String.Format("{0:N0}", amount);
// 小数点以下2桁
String.Format("{0:F2}", value);
// 日付
String.Format("{0:yyyy/MM/dd}", date);
// 日時
String.Format("{0:yyyy-MM-dd HH:mm:ss}", dateTime);
特に日付では、月のMMと分のmmを間違えやすいです。
C#// 正しい
String.Format("{0:yyyy/MM/dd HH:mm:ss}", dateTime);
// 間違いやすい
String.Format("{0:yyyy/mm/dd HH:MM:ss}", dateTime);
迷った場合は、小さなサンプルコードで出力結果を確認すると安全です。
9-5. nullを指定した場合の挙動
String.Formatにnullを渡した場合、基本的には空文字として扱われます。
C#string name = null;
string result = String.Format("名前: {0}", name);
Console.WriteLine(result);
// 名前:
ただし、nullを想定していない値として扱うと、意味の分かりにくい表示になることがあります。
C#string name = null;
string result = String.Format("こんにちは、{0}さん", name);
Console.WriteLine(result);
// こんにちは、さん
必要に応じて、事前にデフォルト値を設定するとよいでしょう。
C#string name = null;
string displayName = name ?? "ゲスト";
string result = String.Format("こんにちは、{0}さん", displayName);
Console.WriteLine(result);
// こんにちは、ゲストさん
9-6. カルチャ差による表示崩れを防ぐ方法
数値や日付の表示は、カルチャによって変わることがあります。
C#using System.Globalization;
decimal price = 1234.5m;
Console.WriteLine(String.Format(CultureInfo.GetCultureInfo("ja-JP"), "{0:C}", price));
Console.WriteLine(String.Format(CultureInfo.GetCultureInfo("en-US"), "{0:C}", price));
日本とアメリカでは、通貨記号や小数点以下の扱いが変わります。
ログ、CSV、外部システム連携など、環境に依存しない出力が必要な場合は、CultureInfo.InvariantCultureを使うと安定します。
C#using System.Globalization;
double value = 1234.56;
string result = String.Format(CultureInfo.InvariantCulture, "{0:N2}", value);
Console.WriteLine(result);
// 1,234.56
ユーザー向け表示ではユーザーのカルチャ、システム連携では固定カルチャ、というように使い分けるのが基本です。
10. String.Formatの実践サンプル集
ここからは、実務でそのまま使いやすいString.Formatのサンプルを紹介します。
10-1. 商品価格をカンマ区切りで表示する
商品価格を3桁区切りで表示する例です。
C#decimal price = 29800m;
string message = String.Format("価格: {0:N0}円", price);
Console.WriteLine(message);
// 価格: 29,800円
小数点以下を含める場合はN2を使います。
C#decimal price = 29800.5m;
string message = String.Format("価格: {0:N2}円", price);
Console.WriteLine(message);
// 価格: 29,800.50円
10-2. 消費税率や割合をパーセント表示する
消費税率や達成率を表示する例です。
C#double taxRate = 0.10;
double progress = 0.856;
Console.WriteLine(String.Format("消費税率: {0:P0}", taxRate));
Console.WriteLine(String.Format("進捗率: {0:P1}", progress));
出力例です。
消費税率: 10%
進捗率: 85.6%
Pは100倍して表示するため、10%を表示したい場合は0.10を渡します。
10-3. 注文番号や会員IDを0埋めする
注文番号を0埋めする例です。
C#int orderId = 123;
string orderNo = String.Format("ORD-{0:D8}", orderId);
Console.WriteLine(orderNo);
// ORD-00000123
会員IDの例です。
C#int memberId = 45;
string memberCode = String.Format("MEM-{0:D6}", memberId);
Console.WriteLine(memberCode);
// MEM-000045
固定桁のコードを作る場合は、D桁数を使うと簡潔です。
10-4. ログファイル名に日時を入れる
ログファイル名に現在日時を入れる例です。
C#DateTime now = DateTime.Now;
string fileName = String.Format("app_{0:yyyyMMdd_HHmmss}.log", now);
Console.WriteLine(fileName);
// app_20260606_090503.log
ファイル名では、/や:などの使用を避けるのがポイントです。
C#string fileName = String.Format("backup_{0:yyyyMMdd}.zip", DateTime.Now);
Console.WriteLine(fileName);
// backup_20260606.zip
10-5. 一覧データを桁揃えして出力する
一覧データをコンソールに整形して出力する例です。
C#Console.WriteLine(String.Format("{0,-10} {1,8} {2,10}", "商品名", "数量", "金額"));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "Apple", 3, 300));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "Orange", 12, 1200));
Console.WriteLine(String.Format("{0,-10} {1,8} {2,10:N0}", "Banana", 5, 500));
出力例です。
商品名 数量 金額
Apple 3 300
Orange 12 1,200
Banana 5 500
文字列は左寄せ、数値は右寄せにすると見やすくなります。
10-6. メール本文やメッセージを組み立てる
メール本文のような文章を組み立てる場合にもString.Formatは使えます。
C#string userName = "山田太郎";
string orderNo = "ORD-00000123";
decimal total = 29800m;
string body = String.Format(
@"{0} 様
ご注文ありがとうございます。
注文番号: {1}
合計金額: {2:N0}円
商品の発送準備が整い次第、改めてご連絡いたします。",
userName,
orderNo,
total
);
Console.WriteLine(body);
複数行のテンプレートに値を埋め込む場合、String.Formatを使うとテンプレート部分と値を分けて管理しやすくなります。
11. C# String.Formatに関するよくある質問
ここでは、String.Formatに関するよくある疑問をまとめます。
11-1. String.Formatで0埋めするにはどう書けばいい?
整数を0埋めするには、Dを使います。
C#int number = 25;
string result = String.Format("{0:D5}", number);
Console.WriteLine(result);
// 00025
D5は5桁の0埋め、D8は8桁の0埋めです。
C#Console.WriteLine(String.Format("{0:D8}", number));
// 00000025
11-2. 小数点以下2桁で表示するには?
小数点以下2桁で表示するには、F2またはN2を使います。
C#double value = 1234.5;
Console.WriteLine(String.Format("{0:F2}", value));
// 1234.50
Console.WriteLine(String.Format("{0:N2}", value));
// 1,234.50
カンマ区切りが不要ならF2、カンマ区切りが必要ならN2を使います。
11-3. 日付をyyyyMMdd形式にするには?
日付をyyyyMMdd形式にするには、次のように書きます。
C#DateTime date = new DateTime(2026, 6, 6);
string result = String.Format("{0:yyyyMMdd}", date);
Console.WriteLine(result);
// 20260606
ファイル名や連携用データでよく使われる形式です。
C#string fileName = String.Format("data_{0:yyyyMMdd}.csv", date);
Console.WriteLine(fileName);
// data_20260606.csv
11-4. カンマ区切りで数値を表示するには?
カンマ区切りで表示するには、N0を使います。
C#int amount = 1234567;
string result = String.Format("{0:N0}", amount);
Console.WriteLine(result);
// 1,234,567
小数点以下2桁まで表示したい場合はN2です。
C#double amount = 1234567.89;
Console.WriteLine(String.Format("{0:N2}", amount));
// 1,234,567.89
11-5. String.Formatと$文字列はどちらを使うべき?
通常のコードでは、読みやすい文字列補間を使うことが多いです。
C#string message = $"{name}さんの点数は{score}点です。";
ただし、テンプレート文字列を外部から読み込む場合や、既存コードでString.Formatを使っている場合は、String.Formatも有効です。
C#string template = "{0}さんの点数は{1}点です。";
string message = String.Format(template, name, score);
文字列補間はString.Formatと同じ結果をより読みやすく書ける機能として説明されています。
11-6. 波括弧をそのまま表示するには?
波括弧をそのまま表示したい場合は、{{と}}を使います。
C#string result = String.Format("{{名前}}: {0}", "田中");
Console.WriteLine(result);
// {名前}: 田中
JSON文字列を作る場合も同じです。
C#string json = String.Format("{{ \"id\": {0} }}", 123);
Console.WriteLine(json);
// { "id": 123 }
11-7. String.Formatは古い書き方なのか?
String.Formatは現在でも使える有効な書き方です。ただし、C#では文字列補間が使えるため、コード内で直接文字列を組み立てる場合は、文字列補間のほうが読みやすいことが多いです。
C#// String.Format
string message1 = String.Format("{0}さんの点数は{1}点です。", name, score);
// 文字列補間
string message2 = $"{name}さんの点数は{score}点です。";
一方で、テンプレートを変数として持つ場合はString.Formatが便利です。
C#string template = "{0}さん、注文番号{1}を受け付けました。";
string message = String.Format(template, userName, orderNo);
つまり、String.Formatが古くて使えないわけではなく、現在のC#では文字列補間と使い分けるのが現実的です。
まとめ
String.Formatは、C#で文字列を整形するための基本的で便利なメソッドです。{0}や{1}のようなプレースホルダーに値を埋め込み、さらに数値、日付、桁数、0埋め、右寄せ、左寄せなどを指定できます。
特によく使う書式は次のとおりです。
C#String.Format("{0:D5}", 25); // 00025
String.Format("{0:F2}", 123.456); // 123.46
String.Format("{0:N0}", 1234567); // 1,234,567
String.Format("{0:P1}", 0.1234); // 12.3%
String.Format("{0:yyyy/MM/dd}", DateTime.Now); // 2026/06/06
String.Format("{0,10}", 123); // 右寄せ
String.Format("{0,-10}", "ABC"); // 左寄せ
単体の値を整形するだけならToString、コード内で読みやすく文字列を作るなら文字列補間、テンプレートに複数の値を埋め込むならString.Formatが向いています。
String.Formatの基本である{index,alignment:format}を理解しておけば、0埋め、桁数指定、日付、数値、ログ、ID生成、ファイル名作成など、さまざまな場面で応用できます。

