[C#] TimeSpanのToStringは癖がある。

C#やVB.NETで使用される時間間隔を扱うクラスTimeSpanは便利だが、文字列として出力する際のToString()に癖がある。
DateTimeクラスと同じように、カスタム日時書式文字列を使いたいところだが微妙に違う。

まず、下記のように適当にTimeSpanを用意して

var ts = new TimeSpan(12, 15, 10);
var ts2 = - new TimeSpan(12, 15, 10, 10, 500);

標準の時間間隔書式文字列

標準の時間間隔書式文字列は、c, g, G の3パターンがある。

//c [-][d.]hh:mm:ss[.fffffff]   *[]は無い場合省略される
Console.WriteLine(ts.ToString("c"));     //12:15:10
Console.WriteLine(ts2.ToString("c"));    //-12.15:10:10:5000000

//g [-][d:]h:mm:ss[.FFFFFFF]
Console.WriteLine(ts.ToString("g"));     //12:15:10
Console.WriteLine(ts2.ToString("g"));    //-12.15:10:10.5

//G [-]d:hh:mm:ss.fffffff
Console.WriteLine(ts.ToString("G"));     //0.12:15:10:0000000
Console.WriteLine(ts2.ToString("G"));    //-12.15:10:10.5000000

普通に表示させるだけであれば、上記を切り分ける。

カスタム時間間隔書式文字列

カスタム時間間隔書式文字列は自由に表記できるが、通常慣れしたんだDateTimeとは勝手が違う。

書式文字以外はすべて\を直前に置くか ‘ (シングルクォーテーション) でくくる。
HHでなくhhだったり、マイナスは標準方式だと出てくれるが、カスタムだと自前で引っ付ける必要があるなど・・・。

Console.WriteLine(ts.ToString(@"hh\:mm\:ss"));     //12:15:10
Console.WriteLine(ts2.ToString(@"hh\:mm\:ss"));    //15:10:10

//マイナスは3項演算子とかで頑張るしかない。(公式でこう書いてあるから仕方ないね。)
Console.WriteLine(ts.ToString($@"{(ts < TimeSpan.Zero ? @"\-" : "")}hh\:mm\:ss"));     //12:15:10
Console.WriteLine(ts2.ToString($@"{(ts2 < TimeSpan.Zero ? @"\-" : "")}hh\:mm\:ss"));   //-12:10:10

//\を直前に置く残念な形
Console.WriteLine(ts.ToString(@"hh\時\間mm\分ss\秒\で\す\。"));   //12時間15分10秒です。
//''でくくるともう少しマシな感じ
Console.WriteLine(ts.ToString(@"hh'時間'mm'分'ss'秒です。'"));    //12時間15分10秒です。

//ちなみに24時間以上はdのほうに入るので、28時間とやりたい場合は、頑張るしかない。
var dts = new TimeSpan(1, 12, 15, 10);
int hourWithDay = 24 * dts.Days + dts.Hours;
Console.WriteLine($"{hourWithDay}時間{dts.Minutes}分{dts.Minutes}秒です。");   //36時間15分10秒です。

毎回、シングルクォーテーションで括るのがめんどうなので、どこかのクラスに拡張を作って

public static class TimeSpanExternal
{
	public static string ToStringEx(this TimeSpan ts, string format)
	{
		string hh = ts.ToString("hh");
		if (ts < TimeSpan.Zero) { hh = "-" + hh; }
		string mm = ts.ToString("mm");
		string ss = ts.ToString("ss");

		format = format.Replace("hh", hh);
		format = format.Replace("mm", mm);
		format = format.Replace("ss", ss);

		return format;
	}
}

こんな風に呼び出してもいいかも。

Console.WriteLine(ts.ToStringEx("hh時間mm分ss秒です。"));  //12時間15分10秒です。
Console.WriteLine(ts.ToStringEx("hh時間mm分ss秒です。"));  //-15時間10分10秒です。

 

 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>