如何使用模运算计算时间跨度?

时间:2016-10-07 13:16:18

标签: c# modulo timespan modular-arithmetic

这个问题基本上是关于在代码中表示模块化算术概念并使用模数符号。

所以最近我做了SCCM安装的弹出窗口,它应该给用户时间来安装应用程序,客户端的要求是向用户显示一个时钟,其中包含安装剩余的时间(或者让用户立即安装) )。他们想要的时间是24小时,加上24小时过去的时间到下午4点所以:

程序在13:00运行,然后时钟显示24 + 3 = 27小时

16:00时应该是24 + 24,这是48小时

当22:00它应该是24 + 18,这是42小时

现在我注意到了:

13 + 27 = 40

16 + 24 = 40

22 + 18 = 40

40 Modulo 24 = 16

所以基本上如果我从40减去当前时间,那么我将留下差异:

40 - 13 = 27

40 - 16 = 24

40 - 22 = 18

所以我做的是:

//I need to make a timespan object which has 24 hours from current time + time left to the next 4pm

//The context is time to install, which user should see
Timespan TimeToInstall = new Timespan(23,59,59)

DateTime Now = DateTime.Now;
if (Now.Hour < 16)
{
    long TimeTo4 = (new TimeSpan(40, 0, 0).Ticks - Now.TimeOfDay.Ticks);
    TimeToInstall = TimeSpan.FromTicks(TimeTo4);
}
else
{

long TimeTo4 = (new TimeSpan(40, 0, 0).Ticks - Now.TimeOfDay.Ticks) + TimeGiven.Ticks;
TimeToInstall = TimeSpan.FromTicks(TimeTo4);

}

上述解决方案的问题在于我知道它可以更短,因为当我在下午4点之前减去时间时,如果运行时间高于或等于我,则不需要增加24小时下午4点然后我需要增加24小时。我有一个粗略的想法,如何在数学/伪代码中重构这个例子:

绝对(16-13)模24 = 3

绝对值(16-16)模24 = 0(24)

绝对(16-22)模24 = 18

问题是如何用C#代码来重构这段代码?请使用您喜欢的任何语言,但我会很高兴C#示例。谢谢你们

1 个答案:

答案 0 :(得分:1)

如果您正在寻找更短的解决方案,那该怎么办?

public static int HoursUntilDueTime(DateTime time)
{
    DateTime dueTime = (time + TimeSpan.FromHours(8)).Date + TimeSpan.FromHours(24 + 16);
    return (int)(0.5 + (dueTime - time).TotalHours);
}

或者,如果您想传入目标时间(忽略日期部分):

public static int HoursUntilDueTime(DateTime currentTime, DateTime targetTime)
{
    DateTime dueTime = (currentTime + TimeSpan.FromHours(24 - targetTime.Hour)).Date + TimeSpan.FromHours(24 + targetTime.Hour);
    return (int)(0.5 + (dueTime - currentTime).TotalHours);
}

测试代码:

var targetTime = new DateTime(2000, 1, 1, 16, 00, 00);
Console.WriteLine(HoursUntilDueTime(new DateTime(2016, 1, 1, 13, 00, 00), targetTime));
Console.WriteLine(HoursUntilDueTime(new DateTime(2016, 1, 1, 16, 00, 00), targetTime));
Console.WriteLine(HoursUntilDueTime(new DateTime(2016, 1, 1, 22, 00, 00), targetTime));