如何在 C# 中添加两个具有负号的时间跨度值?

How to add two time span values having negative sign in c#?

我的 table 中有两列,即员工出勤的工作时间和加班时间,如果有人在 9 点钟签到并签到,员工必须工作的总时间为九 (9) 小时11 点外出,然后系统自动计算 his/her 工作时间和加班时间,现在在这种情况下,工作时间为 2 小时,加班时间为负数,例如 -7:00:00 小时,因为员工休假 7比实际时间早几个小时,我将这个负值存储为 "varchar" 在数据库中,以方便用户了解员工在给定时间工作得更多,或者 less.Now 我需要添加这些额外的员工小时数以创建月份摘要但我不知道如何添加这些负时间跨度,当我将其转换为时间格式时,由于负号,系统无法转换它。

我从数据库中读取后计算工作时间总和:

wrkhrs=wrkhrs.Add(Convert.ToDateTime(dr["WorkHrs"].ToString()).TimeOfDay);

我找到了一些减法代码:

TimeSpan exthrs = org_work.Subtract(tot_work);

但如果时间跨度为负号,则它不起作用。 如果任何人有任何想法,请分享。提前致谢。

编辑:

public Tuple<string,string>  Calculate_Hours(int id,DateTime strt, DateTime end)
        {
            TimeSpan wrkhrs = new TimeSpan(0, 0, 0);
            TimeSpan exthrs=new TimeSpan(0,0,0);
            //select * from vw_Rept_Attend where UserID ='" + id + "' and convert(date,AtnDate) between '" + strt.Date + "' and '" + end.Date + "'
            cmd = new SqlCommand("sp_Calculate_Hours_For_Report", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@id", id);
            cmd.Parameters.AddWithValue("@startdate", strt.Date);
            cmd.Parameters.AddWithValue("@end", end.Date);
            conn.Open();
            dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                if (dr["WorkHrs"].ToString().Length>0)
                   wrkhrs=wrkhrs.Add(Convert.ToDateTime(dr["WorkHrs"].ToString()).TimeOfDay);
               if (!dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
                {
                    exthrs = exthrs.Add(Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay);
                }
                else if (dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
                {
                    string ext = dr["ExtraHrs"].ToString().Substring(dr["ExtraHrs"].ToString().LastIndexOf("-") +1);
                    exthrs = exthrs.Subtract(Convert.ToDateTime(ext).TimeOfDay);
                }
            }
            conn.Close();
            dr.Close();
           return new Tuple<string, string>(string.Format("{0:00}:{1:00}:{2:00}", (int)TimeSpan.Parse(wrkhrs.ToString()).TotalHours, Math.Abs((int)TimeSpan.Parse(wrkhrs.ToString()).Minutes), Math.Abs((int)TimeSpan.Parse(wrkhrs.ToString()).Seconds)), string.Format("{0:00}:{1:00}:{2:00}", (int)TimeSpan.Parse(exthrs.ToString()).TotalHours, Math.Abs((int)TimeSpan.Parse(exthrs.ToString()).Minutes), Math.Abs((int)TimeSpan.Parse(exthrs.ToString()).Seconds)));

        }

并将上述函数调用为:

var mytuple = Calculate_Hours(id,Convert.ToDateTime(dtStart.Text), Convert.ToDateTime(dtEnd.Text));
string tot_workHrs= mytuple.Item1;
string tot_ExtHrs=  mytuple.Item2;

以上是我检索正确输出的逻辑,如果有人有任何问题,请随时通过对此发表新评论来问我 post。

现在希望这对所有人都有帮助....

1。 使用 TimeSpan.Duration():

https://msdn.microsoft.com/en-us/library/system.timespan.duration(v=vs.110).aspx

"Returns a new TimeSpan object whose value is the absolute value of the current TimeSpan object"

2。 或者来自 HERE 的一些代码:

static string ToHMString(TimeSpan timespan) { 
    if (timespan.Ticks < 0) return "-" + ToHMString(timespan.Negate());

    return timespan.TotalHours.ToString("#0") + ":" + timespan.Minutes.ToString("00");
}

Console.WriteLine(ToHMString(TimeSpan.FromHours(3)));       //Prints "3:00"
Console.WriteLine(ToHMString(TimeSpan.FromHours(-27.75)));  //Prints "-28:45"

首先,在数据库中将 time/duration 值存储为 string 是个坏主意。

其次,.Net TimeSpan 结构完全能够表示负持续时间并正确计算。

建议:

  1. 将您的负面持续时间作为 time/duration 值存储在数据库中。如果您的数据库没有支持负值的持续时间类型,请添加布尔值 "This value is negative"

  2. 在您的 C# 代码中使用 TimeSpan 和常用运算符:+-

这是否满足您的需求?

string[] sample = new string[] { "2.1", "-7.0", "1.0" };

TimeSpan total =
    sample
        .Select(s => TimeSpan.FromHours(double.Parse(s)))
        .Aggregate((ts0, ts1) => ts0.Add(ts1));

我得到的 total-03:54:00 作为 TimeSpan