在 .NET 中乘以时间跨度
Posted
技术标签:
【中文标题】在 .NET 中乘以时间跨度【英文标题】:Multiply TimeSpan in .NET 【发布时间】:2012-04-12 03:19:06 【问题描述】:如何在 C# 中乘以 TimeSpan 对象?假设变量duration
是TimeSpan,我想,例如
duration*5
但这给了我一个错误“运算符 * 不能应用于类型 TimeSpan 和 int”。这是我目前的解决方法
duration+duration+duration+duration+duration
但这不会扩展到非整数倍数,例如。 duration * 3.5
【问题讨论】:
【参考方案1】:乘法现在可用于 TimeSpan!!!
但仅适用于 .NET Core、.NET Standard 和 .NET 5+。
自.NET Core 2.0(或.NET Standard 2.1)您可以成功运行以下代码:
Console.WriteLine(TimeSpan.FromSeconds(45) * 3);
// Prints:
// 00:02:15
限制
不过,请务必注意 (as described in the docu),这仅适用于 .NET Core 2.0+、.NET Standard 2.1+,当然还有 .NET 5+。
即使在最新的 .NET Framework 版本中,上面的代码也会失败:4.8(实际上是 的最后一个版本.NET 框架!)。
如果您在 Console 应用程序中尝试上述代码,例如,运行 .NET Core 1.1 或更低版本,或者 .NET Framework 4.8 或更低会抛出以下异常:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Operator '*' 不能应用于'System.TimeSpan' 和'int''类型的操作数
为什么不在 .NET Framework 中?
为了尝试理解为什么某些功能会添加到.Net Core而不是.NET Framework,看到what Immo says很有启发性:
.NET Core 是 .NET 的开源、跨平台和快速发展版本。由于它的并行特性,它可以进行我们不能冒险应用回 .NET Framework 的更改。这意味着 .NET Core 将随着时间的推移获得 .NET Framework 无法获得的新 API 和语言功能。在 Build 中,我们演示了文件 API 如何在 .NET Core 上更快。如果我们将这些相同的更改放入 .NET Framework 中,我们可能会破坏现有的应用程序,而我们不想这样做。
【讨论】:
Immo 的引用与向TimeSpan
类型添加新运算符完全无关。它不能破坏任何现有的代码,因为没有旧的实现。也许存在代码许可问题,但没有技术原因 .NET Framework 也不能进行此更改。【参考方案2】:
TimeSpan.Multiply
已抵达 .NET Core,看起来它将抵达 .NET Standard 2.1:
https://docs.microsoft.com/en-us/dotnet/api/system.timespan.op_multiply?view=netstandard-2.1
var result = 3.0 * TimeSpan.FromSeconds(3);
【讨论】:
【参考方案3】:对于那些希望复制和粘贴的人:
namespace Utility
public static class TimeSpanExtension
/// <summary>
/// Multiplies a timespan by an integer value
/// </summary>
public static TimeSpan Multiply(this TimeSpan multiplicand, int multiplier)
return TimeSpan.FromTicks(multiplicand.Ticks * multiplier);
/// <summary>
/// Multiplies a timespan by a double value
/// </summary>
public static TimeSpan Multiply(this TimeSpan multiplicand, double multiplier)
return TimeSpan.FromTicks((long)(multiplicand.Ticks * multiplier));
示例用法:
using Utility;
private static void Example()
TimeSpan t = TimeSpan.FromSeconds(30).Multiply(5);
t
将结束为 150 秒。
【讨论】:
扩展方法是解决这类问题最方便的方法。 multiplier 参数可以是 long 类型,无需额外费用。 如果它对任何人有用,我选择添加溢出检查,抛出 if long.MaxValue / multiplier multiplicand.Ticks,用于 int 乘数。由于通过将双倍转换为长在后楼层中实现,因此相同的逻辑应该适用于双倍乘数。【参考方案4】:这里的问题是你想乘以时间跨度。最简单的解决方法是使用刻度。例如。
var ticks = TimeSpan.FromMinutes(1).Ticks;
var newTimeSpan = TimeSpan.FromTicks(ticks*5);
【讨论】:
【参考方案5】:可以使用TimeSpan的内部数据,即tick。
TimeSpan day = TimeSpan.FromDays(1);
TimeSpan week = TimeSpan.FromTicks(day.Ticks * 7);
【讨论】:
【参考方案6】:From this article
TimeSpan duration = TimeSpan.FromMinutes(1);
duration = TimeSpan.FromTicks(duration.Ticks * 12);
Console.WriteLine(duration);
【讨论】:
谢谢我用TimeSpan.FromTicks((long)(duration.Ticks*multiplier))
我宁愿使用扩展方法。就像 Stephen Hewlett 在他对这个问题的回答中所建议的那样。
@MikedeKlerk 同意,但这更像是语法糖。 OP 仍然需要知道答案的根源,以便它可以应用于任何方法、扩展与否【参考方案7】:
使用记号:
http://www.personal.psu.edu/wbk2/blogs/personal_blog/dotnet-stuff-timespan-multiplication-and-division.html
【讨论】:
【参考方案8】:TimeSpan
结构不为*
运算符提供重载,因此您必须自己执行此操作:
var result = TimeSpan.FromTicks(duration.Ticks * 5);
【讨论】:
【参考方案9】:您需要指定要乘以 5 的成员 -> TimeSpan.TotalMinutes * 5
【讨论】:
这确实有效 - 但更好的通用解决方案是将刻度乘以恕我直言。 不,TimeSpan 是一个标量。T * 5
也应该乘以小时和秒。
@HenkHolterman 但TotalMinutes
是以分钟表示的时间跨度的总持续时间,因此如果时间跨度表示一小时零十分三十秒,TotalMinutes 将返回 70.5。
@HenkHolterman 正如 phoog 所指出的,TotalMinutes
属性是一个 Double,它给出了整个 TimeSpan 的总分钟数,同时考虑了所有其他字段。尽管Ticks
看起来确实是一种更好的方法,但此解决方案的工作原理相同。但请注意,如果您想向用户展示一些有意义的信息,那么稍后需要将 Ticks 转换为分钟。
同意,我对句子的第一部分做出了反应。 TotalMinutes 并不是真正的合成成员。以上是关于在 .NET 中乘以时间跨度的主要内容,如果未能解决你的问题,请参考以下文章
TCP 错误代码 10061:无法连接到 net.tcp://。连接尝试持续了 00:00:01.0156241 的时间跨度