【问题标题】:Use String.Format on a TimeSpan to output full seconds without milliseconds在 TimeSpan 上使用 String.Format 以输出完整的秒数而不是毫秒
【发布时间】:2010-08-23 07:30:40
【问题描述】:

我想在一个字符串中显示两个日期之间经过的时间。

假设我有以下代码:

DateTime date1 = DateTime.Now();
System.Threading.Thread.Sleep(2500);
DateTime date2 = DateTime.Now();

TimeSpan elapsed = date2.substract(date1);
Console.WriteLine("> {0:hh:mm:ss}", elapsed);

我的期望:

> 00:00:03

我得到了什么:

> 00:00:02.5002500

有没有办法使用 String.Format 函数只返回完整的秒数?
我还尝试使用以下方法删除小数位:

elapsed = elapsed.Substract(TimeSpan.FromMiliseconds((double)Timespan.Miliseconds);

但这也不起作用,因为 elapsed.Miliseconds 返回 500 作为整数。

【问题讨论】:

    标签: c# timespan string.format


    【解决方案1】:

    改变

    Console.WriteLine("> {0:hh:mm:ss}", elapsed);
    

    Console.WriteLine("> {0:hh\\:mm\\:ss}", elapsed);
    

    .Net 4 允许您在 Timespan 中使用自定义格式字符串。您可以在 MSDN Custom TimeSpan Format Strings 页面上找到可用格式说明符的完整参考。

    您需要使用“\”转义“:”字符(除非您使用逐字字符串,否则必须对其本身进行转义)。

    这段摘自 MSDN Custom TimeSpan Format Strings 页面解释了如何转义“:”和“.”。格式字符串中的字符:

    自定义 TimeSpan 格式说明符不包含占位符分隔符,例如将天与小时、小时与分钟或秒与小数秒分开的符号。相反,这些符号必须作为字符串文字包含在自定义格式字符串中。例如,“dd.hh:mm”将句点 (.) 定义为天和小时之间的分隔符,将冒号 (:) 定义为小时和分钟之间的分隔符。

    【讨论】:

      【解决方案2】:

      很遗憾,不能像格式化 DateTime 值一样格式化 TimeSpan。但是,您可以进行快速转换,因为 TimeSpan 和 DateTime 都将它们的值存储为刻度(在 Ticks 属性中)。

      在您的代码中如下所示:

      Console.WriteLine("> {0:hh:mm:ss}", new DateTime(elapsed.Ticks));

      更新:这适用于 .NET 3.5 及更早版本,.NET 4 确实支持格式化 TimeSpan。

      【讨论】:

      • 我相信您希望HH:mm:ss 这样做是正确的。巧妙的技巧,我 +1
      • 很好的解决方案(因为我的时间跨度永远不会超过 24 小时),并且恐惧是正确的:HH:mm:ss 更有意义。
      • 在 .Net 4 中,您确实可以以与 DateTime 相同的方式格式化 Timespan。您可以使用以下内容:{0:hh\\:mm\\:ss}。有关详细信息,请参阅下面的答案。
      • 不一样,DateTime的格式更灵活
      【解决方案3】:

      TimeSpan 类具有 HoursMinutesSeconds 属性,它们分别返回每个时间部分。所以你可以试试:

      String.Format(CultureInfo.CurrentCulture, "{0}:{1}:{2}", 
          elapsed.Hours, 
          elapsed.Minutes, 
          elapsed.Seconds)
      

      得到你想要的格式。

      可能有更优化的方法,但我还没有找到。

      【讨论】:

        【解决方案4】:

        在查看了几种方法之后,不幸的是,我得到了一个丑陋的答案。您不能真正使用 Ticks,因为它不能正确返回格式,但以下方法会起作用:

        DateTime date1 = DateTime.Now;
        System.Threading.Thread.Sleep(2500);
        DateTime date2 = DateTime.Now;
        
        TimeSpan elapsed = date2.Subtract(date1);
        
        string[] Split = elapsed.ToString().Split('.');
        
        string m = Split[0]; // Returns 00:00:02
        

        【讨论】:

        • 也是一个不错的解决方案(而且可能是最有效的性能解决方案)。
        • 可以用 0 秒的片段创建一个新的 TimeSpan,然后打印那个片段。 “g”格式与 CultureInfo.InvariantCulture 应该可以正常工作
        • 请注意,TimeSpan 的默认格式是“c”(常量)。例如。 [-][d.]hh:mm:ss[.fffffff]。强制“g”或“G”是你处理天数的一半。
        【解决方案5】:
        Timespan duration = endDateTime - startDateTime;
        duration.ToString("hh\\:mm\\:ss");
        

        【讨论】:

        • 在回答一个九年前的问题和其他七个答案时,解释您的答案所针对的问题的哪些新方面非常重要。通过添加对它们的工作原理和原因的解释,几乎总是可以改进仅代码的答案。
        【解决方案6】:

        嗯,这很糟糕(事实证明)- 至少在 .NET 4.0 之前

        如果你去这里:http://msdn.microsoft.com/en-us/library/1ecy8h51(v=VS.90).aspx 它会告诉你在时间跨度内没有格式重载,你必须手动完成,例如:

             span.Hours.ToString("00") + ":" + 
             span.Minutes.ToString("00") + ":" + 
             span.Seconds.ToString("00") + "."
        

        这似乎 - 至少从文档中 - 将在 .NET 4.0 中修复

        【讨论】:

          【解决方案7】:

          你可以这样做:

          dt.Subtract(TimeSpan.FromMilliseconds(dt.Millisecond)).ToString();
          

          【讨论】:

          • 请也添加一些解释!
          • 这也可以,但是因为 Framework 4 .NET 原生支持时间跨度格式,这是最好的解决方案。
          【解决方案8】:

          有以下自定义格式说明符 y(年)、M(月)、d(日)、h(12 小时)、H(24 小时)、m(分钟)、s(秒)、f(秒小数) )、F(第二个小数,尾随零被修剪)、t(PM 或 AM)和 z(时区)。

          以下示例演示了如何将格式说明符重写为输出。 [C#]

          // create date time 2008-03-09 16:05:07.123    
          DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);    
          String.Format("{0:y yy yyy yyyy}", dt);  // "8 08 008 2008"   year    
          String.Format("{0:M MM MMM MMMM}", dt);  // "3 03 Mar March"  month    
          String.Format("{0:d dd ddd dddd}", dt);  // "9 09 Sun Sunday" day    
          String.Format("{0:h hh H HH}",     dt);  // "4 04 16 16"      hour 12/24
          String.Format("{0:m mm}",          dt);  // "5 05"            minute
          String.Format("{0:s ss}",          dt);  // "7 07"            second    
          String.Format("{0:f ff fff ffff}", dt);  // "1 12 123 1230"   sec.fraction    
          String.Format("{0:F FF FFF FFFF}", dt);  // "1 12 123 123"    without zeroes    
          String.Format("{0:t tt}",          dt);  // "P PM"            A.M. or P.M.    
          String.Format("{0:z zz zzz}",      dt);  // "-6 -06 -06:00"   time zone
          

          【讨论】:

            猜你喜欢
            • 2017-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-10-19
            • 1970-01-01
            • 2014-12-21
            • 1970-01-01
            • 2018-07-22
            相关资源
            最近更新 更多