C#中如何移除TimeSpan格式化输出字符串的末尾多余0
你当前代码未达预期的核心问题是逻辑矛盾:你先调用ToString("hh':'mm':'ss'.'f")把时间差格式化为1位小数的字符串,又在外层套了TimeSpan.Parse()把格式化后的字符串重新转回TimeSpan类型赋值给Duration。TimeSpan是值类型,底层存储的是精确到100纳秒的时长刻度数,不会保留格式化阶段设置的小数位数,你最终看到的12:13:08.1000000是TimeSpan默认格式化规则的输出结果,和你之前传入ToString的格式参数没有关联。
根据你Duration字段的实际类型,选对应方案即可:
场景1:Duration是字符串类型
直接去掉外层多余的TimeSpan.Parse调用,直接取ToString的结果即可。TimeSpan的f格式说明符本身就只会输出对应位数的小数,不会自动补末尾多余的0:
Duration = stopEventOut.StopEventDateTime .Subtract(stopEventIn.StopEventDateTime) .ToString(@"hh\:mm\:ss\.f");
用你给出的示例值12:13:08.1265838测试,上述代码输出结果为12:13:08.1,无多余尾0。
格式字符串里用
\:转义冒号、\.转义小数点,和你原来写法里用单引号包裹分隔符的效果完全一致,写法更简洁。
场景2:Duration必须是TimeSpan类型
你需要先明确:TimeSpan作为存储时长的值结构,本身没有“保留几位小数、去除尾0”的概念,你看到的尾0都是输出展示环节的默认格式化规则生成的,和值本身的存储逻辑无关,对应两种处理方式:
- 如果只是需要展示、序列化输出时去掉尾0:不需要在赋值
Duration的时候做任何格式化处理,只在最终输出Duration的位置,调用上述带格式参数的ToString方法即可。 - 如果需要把
Duration的实际精度截断到0.1秒,从根源上避免默认输出带多余尾0,可以在计算时长时先做精度截断,再生成TimeSpan赋值:
var rawDuration = stopEventOut.StopEventDateTime.Subtract(stopEventIn.StopEventDateTime); // 将时长截断到0.1秒精度 Duration = TimeSpan.FromSeconds(Math.Truncate(rawDuration.TotalSeconds * 10) / 10);
处理后的Duration值本身精度就是十分之一秒,直接默认输出也只会显示12:13:08.1,不会出现后面补6个0的情况。
不要用“先输出7位小数再手动TrimEnd掉末尾0和小数点”的写法实现需求,这种写法冗余且易出错,直接使用对应位数的f说明符是官方支持的最高效写法:需要1位小数就传1个f,需要2位就传2个f,该说明符默认就不会输出无意义的尾0。
内容的提问来源于stack exchange,提问作者SJ_Dev

