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秒です。