从 TimeSpan 小时计算天数
Posted
技术标签:
【中文标题】从 TimeSpan 小时计算天数【英文标题】:Calculating days from TimeSpan hours 【发布时间】:2013-08-20 10:02:48 【问题描述】:我有 1 个文本框,用户将输入小时数。目前,如果他们输入 26 小时,由于 TimeSpan 的 HH 限制,我们会收到错误消息。该值将存储在 SQL Server 2008 Time(7) 字段中。
如何让它识别超过 23 小时?不能将其存储为小数,因为程序的另一部分要求此字段为 time(7) 字段。
TimeSpan estiamtedHours;
private void btnSave_Click(object sender, EventArgs e)
estimatedHours = TimeSpan.Parse(tbEstHours.Text);
time(7) 字段也有 24 小时的限制,最好的方法是解决这个问题,因为另一种表单上的秒表需要 Time(7)。
谢谢
【问题讨论】:
26
是一个有效值吗?您应该将其解析为 int 然后检查它是否超过 23。如果超过 24 小时,猜测该值也不会保存在数据库中
【参考方案1】:
如果你知道输入值是一个小时值作为浮点数,你可以使用TimeSpan.FromHours()
:
TimeSpan estiamtedHours;
private void btnSave_Click(object sender, EventArgs e)
estimatedHours = TimeSpan.FromHours(Double.Parse(tbEstHours.Text));
【讨论】:
你必须将字符串转换为 int / double 这会抛出异常 Ops,使用解析更新。这当然仍然需要验证和错误处理,但原来的(处理无效/否定/等)也是如此。【参考方案2】:将文本解析为 int
并将该 int
作为 TimeSpan 构造函数中的 hours
参数传递。
int hours;
if (Int32.TryParse(tbEstHours.Text, out hours))
TimeSpan ts = new TimeSpan(hours, 0, 0);
您也可以对分钟和秒执行相同的操作。或者,如果您只需要几个小时,您可以以相同的方式使用 TimeSpan.FromHours
而不是 TimeSpan
构造函数。
【讨论】:
我会使用它,因为它可以防止用户在程序中间输入错误。即 2a6 如果您只是解析它,它将异常。但使用 Double.TryParse 以获得更好的精度。 即使这样可行,我猜时间字段需要持续时间并且会失败超过 24 小时。如果我错了,请纠正我 @V4Vendetta - 我可能会误解你,但如果你使用TotalHours
属性,它应该返回 26 小时(而不是 Hours
,它会在循环时返回 2)。跨度>
@keyboardP 不,实际上我的意思是,即使它是一个有效的时间跨度,它也不会插入到数据库中,因为它是一个时间字段,时间跨度的创建或解析不是实际问题,而是如何将其限制为 24 小时周期
@V4Vendetta - 啊,我明白你的意思了。在这种情况下,似乎没有 SQL 等价物。它必须以另一种格式存储或存储在此处提到的不同字段中***.com/questions/8503132/…【参考方案3】:
小心。 TimeSpan
用于测量经过的持续时间,而 SQL Server 中的 time
专门用于测量时间。这是两个不同的概念。
有时这些会混淆。例如,DateTime.TimeOfDay
是一个TimeSpan
类型——这违背了它的设计。这是一个合理的折衷方案,因为 .Net 中没有 Time
类型,它可以适合。
但是 24 小时或更长时间的 TimeSpan
不适合 SQL Server time
字段。
另外,TimeSpan
基于标准天数。您可以使用TimeSpan.FromHours(26)
创建一个,它将代表“1 天 2 小时”。如果您拨打TimeSpan.FromHours(26).ToString()
,它将是"1.02:00:00"
。
如果您要存储经过的持续时间(不是一天中的某个时间),则在 .Net 中使用 TimeSpan
,但在 SQL Server 中使用整数类型。确定您想要精度的单位,这将帮助您选择数据类型。
例如,您可以使用 SQL Server bigint
类型存储 TimeSpan.Ticks
的完整精度。但您可能会使用int
存储TimeSpan.TotalSeconds
。加载时,可以使用TimeSpan.FromSeconds
回到TimeSpan
类型。
还要注意TimeSpan
可以是负数,表示时间倒退。
顺便说一句,如果您使用 Noda Time 库 - 这些概念将被分为 Duration
和 LocalTime
类型。
如果您所追求的是一种解析像"26:00:00"
这样的字符串的方法,那么您不能使用TimeSpan
来做到这一点。但是你可以使用Noda Time:
// starting from this string
string s = "26:00:00";
// Parse as a Duration using the Noda Time Pattern API
DurationPattern pattern = DurationPattern.CreateWithInvariantCulture("H:mm:ss");
Duration d = pattern.Parse(s).Value;
Debug.WriteLine(pattern.Format(d)); // 26:00:00
// if you want a TimeSpan, you can still get one.
TimeSpan ts = d.ToTimeSpan();
Debug.WriteLine(ts); // 1.02:00:00
【讨论】:
【参考方案4】:解析输入后,使用FromHours
方法:
double hours
if (double.TryParse(tbEstHours.Text, out hours)
TimeSpan time = TimeSpan.FromHours(hours);
【讨论】:
@DarrenDavies 哈哈,是的。看起来你从未离开过队友;)【参考方案5】:TimeSpan.Parse Method 期望输入格式为
[ws][-] d | [d.]hh:mm[:ss[.ff]] [ws]
其中 hh 是小时部分,范围从 0 到 23。
例如,
TimeSpan.Parse("5")
5 天退货,
TimeSpan.Parse("5:14")
返回 5 小时 14 分钟。
如果您只想让用户输入小时数,您可以简单地将输入解析为整数并从中构造一个 TimeSpan:
TimeSpan result = TimeSpan.FromHours(int.Parse("26"));
// result == 1.02:00:00
(使用int.TryParse 进行用户输入。)
如果您希望您的用户同时输入小时和分钟(例如26:14
),那么您需要自己实现一些解析方法。
【讨论】:
【参考方案6】:由于其他答案没有解决这个问题
这里关注的是数据库中的时间列,它需要一个有效的持续时间,即 limited to the 24 hr 时间,而 TimeSpan
可以让它们超过 24 小时限制。
因此,理想情况下,您应该将值解析为 int(使用 int.Parse
或 int.TryParse
),然后检查它是否小于 24,然后创建适当的 TimeSpan
【讨论】:
是的,这是我没有考虑过的问题。如果输入 3.30,int.Parse 将不起作用。 Time(7) 是必需的,因为另一种形式使用秒表来倒计时该值。以上是关于从 TimeSpan 小时计算天数的主要内容,如果未能解决你的问题,请参考以下文章
MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数
oracle中计算两个日期的相差天数月数年数小时数分钟数秒数等
MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数