简体   繁体   English

如何在C#中对HH:MM:SS格式时间字符串进行除法?

[英]How do I do division on HH:MM:SS format time strings in C#?

I have a series of times that are coming to me as strings from a web service. 我有很多次从Web服务中以字符串形式出现。 The times are formated as HH:MM:SS:000 (3 milisecond digits). 时间格式为HH:MM:SS:000(3毫秒数字)。 I need to compare two times to determine if one is more than twice as long as the other: 我需要比较两次以确定一个时间是否是另一个时间的两倍以上:

if ( timeA / timeB > 2 )

What's the simplest way to work with the time strings? 使用时间字符串最简单的方法是什么?


If I was writing in Python this would be the answer to my question: Difference between two time intervals? 如果我使用Python编写,这将是我的问题的答案: 两个时间间隔之间有差异吗?

(Except the operator I need is division, not subtraction) (除了我需要的运算符是除法运算,而不是减法运算)


Edit: What I'm really looking for is a way to get the ratio of timeA to timeB, which requires division, not subtraction. 编辑:我真正想要的是一种获取timeA与timeB的比率的方法,这需要除法而不是减法。 Unfortunately, the DateTime structure doesn't appear to have a division operator. 不幸的是,DateTime结构似乎没有除法运算符。 Updated the question title and body to reflect this. 更新了问题标题和正文以反映这一点。


Solution: 解:

Based on the answer I picked below, which was the simplest of all the proposed methods so far, here is the working solution: 根据我在下面选择的答案,这是到目前为止所有提出的方法中最简单的方法,这是可行的解决方案:

DateTime timeA;
DateTime timeB;
DateTime.TryParse(webServiceTimeString_A, out timeA);
DateTime.TryParse(webServiceTimeString_B, out timeB);

// TimeA is more than twice the duration of TimeB.
if ( (double)timeA.TimeOfDay.Ticks / (double)timeB.TimeOfDay.Ticks > 2.0f )
{
    // Do stuff.
}
else
{
    // Do different stuff.
}

JavaScript: JavaScript:

Recently, this functionality was also required in JavaScript for an AJAX call, so, I had to write a conversion function after all (just not in C#). 最近,JavaScript在AJAX调用中也需要此功能,因此,我毕竟必须编写一个转换功能(只是在C#中不行)。 In case it's needed: 如果需要的话:

if (_timeInSeconds(timeA) / _timeInSeconds(timeB) > 2) {
    // Do stuff.
}

// Convert HH:MM:SS:000 string to a number of seconds so we can do math on it.
function _timeInSeconds(stringTime) {
    var timeArray = stringTime.split(":");
    var timeInSeconds = 0;

    //HH
    timeInSeconds += (parseInt(timeArray[0], 10) * 3600);

    //MM
    timeInSeconds += (parseInt(timeArray[1], 10) * 60);

    //SS
    timeInSeconds += (parseInt(timeArray[2], 10));

    //Milliseconds
    timeInSeconds += (parseInt(timeArray[3], 10) / 1000);

    return timeInSeconds;
}

Word to the wise: Make sure to specify the second argument of parseInt... 明智的选择:确保指定parseInt的第二个参数。

parseInt(string, 10)

...to specify that the string is a Base-10 number. ...以指定字符串为以10为底的数字。 Otherwise, if the string starts with 0 (common in HH:MM:SS formats), JavaScript decides it's a Base-8 number. 否则,如果字符串以0开头(在HH:MM:SS格式中常见),则JavaScript会确定它是一个以8为基数的数字。 This causes the strings "08" and "09" to be converted to decimal integer 0 (because 8 and 9 don't exist in Base-8), and the calculations get thrown off. 这将导致字符串"08""09"被转换为十进制整数0 (因为在Base-8中不存在8和9),并且计算被抛弃了。

First you create a DateTime by parsing the string and then the math is easy :) 首先,您通过解析字符串创建DateTime ,然后进行数学运算就很简单了 :)

Note that subtracting two dates with the - operator will return a TimeSpan , check the MSDN docs for what those look like. 请注意,使用-运算符减去两个日期将返回一个TimeSpan ,请检查MSDN文档中的内容。

See the TimeSpan structure and then Calculate period of time with .NET 查看TimeSpan结构,然后使用.NET计算时间段

And actually, your code could be simplified thusly: 实际上,可以这样简化您的代码:

    DateTime timeA = DateTime.Now;
    DateTime timeB = DateTime.Now.AddHours(-10.0);

    if ( (double)timeA.TimeOfDay.Ticks / (double)timeB.TimeOfDay.Ticks > 2.0f )
        Console.WriteLine("Time A is more than twice time B");
    else
        Console.WriteLine("Time A is NOT more than twice time B");

I think the easiest way to parse the strings is with TimeSpan.ParseExact in .Net 4: 我认为解析字符串的最简单方法是使用.Net 4中的TimeSpan.ParseExact

    public static bool MoreThanDouble(string t1, string t2)
    {
        const string format = @"%h\:mm\:ss\:fff";
        long ticks1 = TimeSpan.ParseExact(t1, format, null).Ticks,
             ticks2 = TimeSpan.ParseExact(t2, format, null).Ticks;
        return ticks1 - ticks2 > ticks2;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MoreThanDouble("10:11:12:123", "1:23:45:000"));
        Console.WriteLine(MoreThanDouble("10:11:12:123", "9:23:45:000"));
    }

That will print True False . 那将打印True False If you don't have .Net 4, you can use DateTime : 如果没有.Net 4,则可以使用DateTime

    public static bool MoreThanDouble2(string t1, string t2)
    {
        const string format = @"%h\:mm\:ss\:fff";
        long ticks1 = DateTime.ParseExact(t1, format, null,
             System.Globalization.DateTimeStyles.NoCurrentDateDefault).Ticks,
             ticks2 = DateTime.ParseExact(t2, format, null,
             System.Globalization.DateTimeStyles.NoCurrentDateDefault).Ticks;
        return ticks1 - ticks2 > ticks2;
    }

使用DateTime.FormatExact()将您的字符串转换为DateTime,然后通过区别它们来获取一个TimeSpan进行播放。

I would just parse the strings into a timespan rather then converting to a DateTime first 我只是将字符串解析为时间跨度,而不是先转换为DateTime

Here's a sample of how you could do this: 以下是如何执行此操作的示例:

class Program
{
    static void Main( string[] args )
    {
        Console.WriteLine( ( "02:00:00:001".ToTimeSpan().TotalMilliseconds / "01:00:00:000".ToTimeSpan().TotalMilliseconds ) > 2 );
        Console.WriteLine( ( "02:00:00:001".ToTimeSpan().TotalMilliseconds / "00:60:00:000".ToTimeSpan().TotalMilliseconds ) > 2 );
        Console.WriteLine( ( "02:00:00:000".ToTimeSpan().TotalMilliseconds / "01:00:00:001".ToTimeSpan().TotalMilliseconds ) > 2 );
        Console.WriteLine( ( "25:12:60:002".ToTimeSpan().TotalMilliseconds / "12:12:60:002".ToTimeSpan().TotalMilliseconds ) > 2 );
    }
}

public static class Helpers
{
    public static TimeSpan ToTimeSpan(this string time )
    {
        var split = time.Split( ':' );
        if( split.Length != 4 )
        {
            throw new InvalidOperationException("Invalid format");
        }
        //First posistion is days.
        return new TimeSpan(0, split[ 0 ].ToInt(), split[ 1 ].ToInt(), split[ 2 ].ToInt(), split[ 3 ].ToInt() );
    }

    public static int ToInt( this string str )
    {
        return Convert.ToInt32( str );
    }
}

You could add some more validation to the above code as necessary based on how consistent you can expect the time strings to be. 您可以根据期望时间字符串的一致性,根据需要向上述代码添加更多验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM