【问题标题】:How to parse string with hours greater than 24 to TimeSpan?如何将小时数大于 24 的字符串解析为 TimeSpan?
【发布时间】:2010-04-28 09:45:29
【问题描述】:

如何在 C# 中将 30:15 之类的字符串解析为 TimeSpan? 30:15 表示 30 小时 15 分钟。

string span = "30:15";
TimeSpan ts = TimeSpan.FromHours(
    Convert.ToDouble(span.Split(':')[0])).
  Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1]))));

这似乎不太优雅。

【问题讨论】:

  • 查看question(重复)。
  • 是否需要支持本地化? (例如,根据语言设置为 30.15)
  • 格式将始终为 hh:mm 但 hh 可能恰好 > 24。

标签: c# timespan


【解决方案1】:

如果您确定格式始终为“HH:mm”,请尝试以下操作:

string span = "35:15";
TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]),    // hours
                           int.Parse(span.Split(':')[1]),    // minutes
                           0);                               // seconds

【讨论】:

  • 这不适用于负时间跨度(-35:15 将导致 -34:45)
  • c# TimeSpan 工作得很好,但是你将如何将这个值存储在 MSSQL 中? Time(7) 不起作用,字符串也不会那么好。
【解决方案2】:

类似于卢克的回答:

String span = "123:45";
Int32 colon = span.IndexOf(':');
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon - 1)),
                                 Int32.Parse(span.Substring(colon + 1)), 0);

显然它假定原始字符串是格式正确的(由冒号分隔的两部分组成,可解析为整数)。

【讨论】:

  • 我估计卢克的一把手 > 99 不是吗?
  • @Erik,@jlp:是的,我的处理时间超过 99 小时就好了,虽然我的原始答案没有(在我半小时前编辑它之前)。也许 Erik 正在寻找旧答案。
  • @Luke:是的!就像你在这里回答的那样;)
  • @ErikBurigo 您的解决方案不起作用,如果 span 为“99:00”,那么您发送到 Parse 函数的字符串将是“9”和“:00”,因为我刚刚在我的代码,.net 4.5。这是代码:codesend.com/view/6ac57c0773c29b021a12fc91007d79a6
【解决方案3】:

我正在使用我很久以前设计并今天刚刚发布到我的博客的简单方法:

public static class TimeSpanExtensions
{
    static int[] weights = { 60 * 60 * 1000, 60 * 1000, 1000, 1 };

    public static TimeSpan ToTimeSpan(this string s)
    {
        string[] parts = s.Split('.', ':');
        long ms = 0;
        for (int i = 0; i < parts.Length && i < weights.Length; i++)
            ms += Convert.ToInt64(parts[i]) * weights[i];
        return TimeSpan.FromMilliseconds(ms);
    }
}

与之前提供的更简单的解决方案相比,这可以处理更多的情况,但也有其自身的缺点。我进一步讨论here

现在,如果您使用 .NET 4,您可以将 ToTimeSpan 实现缩短为:

public static TimeSpan ToTimeSpan(this string s)
{
    return TimeSpan.FromMilliseconds(s.Split('.', ':')
        .Zip(weights, (d, w) => Convert.ToInt64(d) * w).Sum());
}

如果您不介意使用横屏状态,您甚至可以将其设为单线...

【讨论】:

  • 如果问题与问题中描述的完全一致,则解决方案是可以的。但如果 TimeSpan 字符串值类似于“1.06:00:00”,则此解决方案将失败。不幸的是,解释这些缺点的链接不起作用。可能这个问题在那里讨论过。
  • @Florian 我正在将我的博客移动到一个新的(更好的)主机上,这就是它现在离线的原因!它不支持几天,只支持几个小时。因此,如果您想要 24 + 6 小时,则必须使用 30:00:00。这个想法是完全避免使用天数。缺点更多与不支持负值有关......
【解决方案4】:

类似于 Lukes 的答案,有更多代码和改进空间。但它也处理负数小时(“-30:15”),所以也许它可以帮助某人。

public static double GetTotalHours(String s)
    {
        bool isNegative = false;
        if (s.StartsWith("-"))
            isNegative = true;

        String[] splitted = s.Split(':');
        int hours = GetNumbersAsInt(splitted[0]);
        int minutes = GetNumbersAsInt(splitted[1]);

        if (isNegative)
        {
            hours = hours * (-1);
            minutes = minutes * (-1);
        }
        TimeSpan t = new TimeSpan(hours, minutes, 0);
        return t.TotalHours;
    }

public static int GetNumbersAsInt(String input)
        {
            String output = String.Empty;
            Char[] chars = input.ToCharArray(0, input.Length);
            for (int i = 0; i < chars.Length; i++)
            {
                if (Char.IsNumber(chars[i]) == true)
                    output = output + chars[i];
            }
            return int.Parse(output);
        }

用法

double result = GetTotalHours("30:15");
double result2 = GetTotalHours("-30:15");

【讨论】:

    【解决方案5】:

    通常在需要特定格式的地方使用TimeSpan.ParseExact。但唯一可以指定的小时格式是天的一部分(请参阅Custom TimeSpan Format Strings)。

    因此,您需要自己完成工作:

    string input = "30:24";
    var parts = input.Split(':');
    var hours = Int32.Parse(parts[0]);
    var minutes = Int32.Parse(parts[1]);
    var result = new TimeSpan(hours, minutes, 0);
    

    (但有一些错误检查。)

    timespan 的三个整数构造函数允许小时 >= 24 溢出到天数中。

    【讨论】:

      【解决方案6】:

      基于Jan's Answer

      .NET 5

          /// <summary>
          /// 1 number : hours    "0" to "0:0:0" ,    "-1" to "-01:00:00"
          /// 2 numbers : hours, minutes    "1:2" to "01:02:00"
          /// 3 numbers : hours, minutes, seconds    "1:2:3" to "01:02:03"
          /// 4 numbers : days, hours, minutes, seconds    "1:2:3:4" to "1.02:03:04"
          /// Any char can be used as separator.    "1,2 3aaaa4" to "1.02:03:04"
          /// </summary>
          /// <param name="timeSpanString"></param>
          /// <param name="ts"></param>
          /// <returns>true : conversion succeeded</returns>
          public static bool GetTimeSpan(string timeSpanString, ref TimeSpan ts)
          {
      
              bool isNegative = timeSpanString.StartsWith("-"); // "-1:2:3" is true
              var digitsString = Regex.Replace(timeSpanString, "[^0-9]", " "); // "-1:2:3" to " 1 2 3" 
              var s = digitsString.Split(' ', StringSplitOptions.RemoveEmptyEntries); // "1","2","3"
      
              int days = 0;
              int hours = 0;
              int minutes = 0;
              int seconds = 0;
      
              switch (s.Length)
              {
                  case 1:
                      hours = int.Parse(s[0]);
                      break;
      
                  case 2:
                      hours = int.Parse(s[0]);
                      minutes = int.Parse(s[1]);
                      break;
      
                  case 3:
                      hours = int.Parse(s[0]);
                      minutes = int.Parse(s[1]);
                      seconds = int.Parse(s[2]);
                      break;
      
                  case 4:
                      days = int.Parse(s[0]);
                      hours = int.Parse(s[1]);
                      minutes = int.Parse(s[2]);
                      seconds = int.Parse(s[3]);
                      break;
      
                  default:
                      return false; //no digits or length > 4
              }
      
              if (isNegative)
              {
                  ts = new TimeSpan(-days, -hours, -minutes, -seconds);
              }
              else
              {
                  ts = new TimeSpan(days, hours, minutes, seconds);
              }
      
              return true;
          }
      

      TimeSpanHelper 将 TimeSpan 转换为超过 24 小时的数字。 TimeSpan 转换器,TextBox 规则。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-28
        • 1970-01-01
        • 2010-09-06
        • 2011-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多