不同格式日期的总小时数。C#

不同格式日期的总小时数。C#,c#,algorithm,sum,C#,Algorithm,Sum,我有个问题。我需要在一个代码中计算在办公室工作的小时数。我从SQL server获取的日期没有问题,但我有不同的格式。例如:2019年。92314:54:23,2019.09.23 14:54:23或2019-09-23 14:54:23;我想总结一下结果中的工作时间。不管是哪一年。下面是一个例子: try { string betölt = "SELECT * from munkaorak where"; if (cbTech.

我有个问题。我需要在一个代码中计算在办公室工作的小时数。我从SQL server获取的日期没有问题,但我有不同的格式。例如:2019年。92314:54:232019.09.23 14:54:232019-09-23 14:54:23;我想总结一下结果中的工作时间。不管是哪一年。下面是一个例子:

try
        {

            string betölt = "SELECT * from munkaorak where";
            if (cbTech.Text != "")
            {
                betölt += " Munkaszam='" + cbMunka.Text + "' AND Részfolyamat='" + cbRész.Text + "' AND TechKod='" + cbTech.Text + "'";
            }
            else if (cbRész.Text != "")
            {
                betölt += " Munkaszam='" + cbMunka.Text + "' AND Részfolyamat='" + cbRész.Text + "'";
            }
            else if(cbMunka.Text !="")
            {
                betölt += " Munkaszam='" + cbMunka.Text + "'";
            }
            betölt += " order by ID DESC";
            MySqlCommand name = new MySqlCommand(betölt, kapcsolat);
            kapcsolat.Open();
            olvasó = name.ExecuteReader();
            int összora = 0;

            if (olvasó.HasRows)
            {
                while (olvasó.Read())
                {
                    if (olvasó.GetString(7) != "Befejezés: ")
                    {
                        string[] aha = olvasó.GetString(6).Split(' ');
                        string kezdes = aha[4];
                        string[] kezd = kezdes.Split(':');
                        int kezdoido = Convert.ToInt32(kezd[0]) * 60 * 60 + Convert.ToInt32(kezd[1]) * 60 + Convert.ToInt32(kezd[2]);

                        int befejezoido = 0;
                        string aha22 = "";
                        if (olvasó.GetString(7).IndexOf('-') >= 0)
                        {
                            string[] aha2 = olvasó.GetString(7).Split(' ');
                            string befejezes = aha2[1];
                            string[] bef = befejezes.Split(':');
                            aha22 = aha2[0].Split('-')[2];
                            befejezoido = Convert.ToInt32(bef[0]) * 60 * 60 + Convert.ToInt32(bef[1]) * 60 + Convert.ToInt32(bef[2]);
                        }
                        else
                        {
                            string[] aha2 = olvasó.GetString(7).Split(' ');
                            string befejezes = aha2[4];
                            string[] bef = befejezes.Split(':');
                            aha22 = aha2[3];
                            befejezoido = Convert.ToInt32(bef[0]) * 60 * 60 + Convert.ToInt32(bef[1]) * 60 + Convert.ToInt32(bef[2]);
                        }                          

                        string dolgozott = "";
                        if (aha[3].Replace(".", "") == aha22.Replace(".", ""))
                        {
                            dolgozott = mpbolora(befejezoido - kezdoido);
                            összora += befejezoido - kezdoido;
                        }
                        else
                        {
                            dolgozott = mpbolora((86400 - kezdoido) + befejezoido);
                            összora += (86400 - kezdoido) + befejezoido;
                        }
                        string validalo = "";
                        try
                        {
                            string[] validal = olvasó.GetString(9).Split(' ');
                            validalo = validal[0] + " " + validal[1] + " " + validal[2] + validal[3] + validal[4] + " " + validal[5];
                        }
                        catch
                        {
                            validalo = olvasó.GetString(9);
                        }
                        string munkafolyamat = olvasó.GetString(3) + "-" + olvasó.GetString(4) + "-" + olvasó.GetString(5);
                        string[] sorok = { olvasó.GetString(2), dolgozott, olvasó.GetString(6).Replace("Kezdés: ", ""), olvasó.GetString(7).Replace("Befejezés: ", ""), olvasó.GetString(8), validalo, munkafolyamat };
                        var lv = new ListViewItem(sorok);
                        lvStat.Items.Add(lv);
                    }


                }
            }
            else
            {
                kapcsolat.Close();
                MessageBox.Show("Nincs adat!", "Figyelem");
            }
            kapcsolat.Close();
            lblÖssz.Text = "Összesen ledolgozott órák: " + mpbolora(összora);
        }
        catch (Exception a)
        {
            MessageBox.Show(a.Message);
            kapcsolat.Close();
        }
        kapcsolat.Close();
它起作用了,但当不同的格式出现时,它就不起作用了,因为“-”或空格。请帮忙

C#
中,提供了一系列方法将包含多种格式的日期时间的字符串转换为统一的
DateTime
对象。这些方法可以识别相当多的标准日期时间格式,如果您的格式与它们不同,您甚至可以提供自己的格式

  • DateTime.Parse()
    -将字符串转换为
    DateTime
    对象。如果操作失败,它将抛出一个异常
  • DateTime.TryParse()
    -仅在可能的情况下将字符串转换为
    DateTime
    对象。如果成功,则返回
    true
    ;如果失败,则返回
    false
  • DateTime.TryParseExact()
    -将指定格式的字符串转换为
    DateTime
    对象。如果成功,则返回
    true
    ,否则返回
    false
在您的情况下,您可以使用
DateTime.TryParse()
(建议不要简单地使用
DateTime.Parse()
,除非您完全确定格式正确),如下所示:

一旦转换为
DateTime
对象,它就不再具有与之关联的格式。它是一个
结构
,因此只有成员变量和方法。因此,要计算总小时数等,您可以使用提供的方法

假设您想计算一天工作开始和结束之间的时间。您可以将这些对象转换为
DateTime
对象,然后从其他对象中减去一个,这将为您提供一个
TimeSpam
对象

var dtStrStart = "2019.09.23 08:23:12";
var dtStrEnd = "2019.09.23 16:17:28";

DateTime.TryParse(dtStrStart, out DateTime dtStart);
DateTime.TryParse(dtStrEnd, out DateTime dtEnd);

var diff = dtEnd - dtStart;
现在,这里的
TimeSpan
对象是
diff
,它将为您提供一组以小时、分钟等为单位的属性

Console.WriteLine(diff.Days);
Console.WriteLine(diff.Hours);
Console.WriteLine(diff.Minutes);
Console.WriteLine(diff.Seconds);
Console.WriteLine(diff.Milliseconds);
TimeSpan.Days
TimeSpan.Minutes
等将以天、分钟等为单位显示时间

Console.WriteLine(diff.Days);
Console.WriteLine(diff.Hours);
Console.WriteLine(diff.Minutes);
Console.WriteLine(diff.Seconds);
Console.WriteLine(diff.Milliseconds);
输出:

0

七,

54

十六,

0

TimeSpan.TotalMinutes
etc将以各自的单位显示整个时间段

Console.WriteLine(diff.TotalDays);
Console.WriteLine(diff.TotalHours);
Console.WriteLine(diff.TotalMinutes);
Console.WriteLine(diff.TotalSeconds);
Console.WriteLine(diff.TotalMilliseconds);
输出:

0.329351851852

7.904444

474.266667

28456

28456000


相反,在数据库中存储数据时,必须再次使用标准格式,如
datetime
datetime2
。建议您使用
datetime2
,。

您的代码应该更像这样:

    try
    {

        MySqlCommand name = new MySqlCommand("SELECT * from munkaorak WHERE Munkaszam=@m", kapcsolat);
        name.Parameters.AddWithValue("@m", cbMunka.Text);

        if (cbRész.Text != "")
        {
            name.CommandText += " AND Részfolyamat=@r";
            name.Parameters.AddWithValue("@r", cbRész.Text);
        }

        if (cbTech.Text != "")
        {
            name.CommandText += " AND TechKod=@t";
            name.Parameters.AddWithValue("@t", cbTech.Text);
        }

        name.CommandText += " order by ID DESC"; //is it really necessary?
        MySqlDataAdapter da = new MySqlDataAdapter(name);

        DataTable dt = new DataTable();
        da.Fill(dt);


        foreach(DataRow ro in dt.Rows){

          string fromStr = ro["YOUR_FROM_DATE_COLUMN_NAME"].ToString();

          //cope with dates in varying formats
          //by replacing all non-numeric chars with nothing
          fromStr = Regex.Replace(fromStr, @"[^0-9]", "");

          //now our dates of [2019. 09. 23. 14:54:23], [2019.09.23 14:54:23] or [2019-09-23 14:54:23]
          //just become 20190923145423
          DateTime fromDt = DateTime.ParseExact(fromStr, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);


          string toStr = ro["YOUR_TO_DATE_COLUMN_NAME"].ToString();

          toStr = Regex.Replace(toStr, @"[^0-9]", "");

          DateTime toDt = DateTime.ParseExact(toStr, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);


          //total hours worked
          (toDt - fromDt).TotalHours;


        }
   }
希望这看起来简单多了

在这里您看到的不是……

  • 有风险的SQL注入黑客攻击可能性-永远不要将值连接到SQL中。始终在中连接一个参数,然后为该参数指定一个值。总是
  • 难以阅读,冗长的字符串串联-看起来很糟糕,如果可以,请尽量避免
  • 数据库连接打开和关闭-使用dataadapter时,无需对数据库连接进行微观管理,因为它可以为您打开和关闭
  • 充满神奇数字的数据阅读器代码-GetString(7),hmmm。。那是进入时间还是退出时间?GetInt(4)-是年龄吗?那一年?在这里,我们去掉了所有带有列序号的datareader GetXX调用,并用可以通过字符串名称索引的行填充DataTable(类似于2D数组)。它仍然不如它所能做的那么好(强类型的数据表更好),但这比用幻数填充代码,并以最模糊、弱类型的方式处理所有内容要好得多
  • 笨拙的时间处理-日期解析已经过时了,因为将字符串逐数字拉入位,将其转换为int,将它们乘以几秒和几小时,这样就可以对它们进行操作,这既繁琐又难以读取——通过将这些字符串解析为它们本来应该存储的数据类型来消除它们;你需要记录事情发生的日期和时间。尽量转换数据库,以便正确存储这些内容,然后再将字符串转换为DateTime
  • 使用秒来区分日期:使用时间跨度计算意味着无需将时间转换为秒、做粗略的数学计算、放弃所有时区概念或夏令时更改等;通过使用相互减去的日期,您可以在两个日期之间获得一个时间段,该时间段考虑了诸如夏令时时钟变化之类的因素。或者甚至能够有一个日期是明天,或者是未来的X天。可能对这个应用程序不重要,但总有一天它会

如果您有MySQL 8,您可以在DB中执行正则表达式替换。甚至可以将数据库转换为diff并对日期求和。。不过,我们不能就这一点提出任何建议,因为我们不知道列名

将日期存储为字符串和使用字符串concat构建sql命令是您真正需要从编码生命中清除的两件事。将日期转换为C#
日期时间
对象。将数据库中的日期转换为
datetime2
,第一个小点;mysql没有datetime2type@CaiusJard:我错了。我没有注意到上面的“
My
”<代码>日期时间没错。回答得很好。一个小点;MySQL没有datetime2数据type@CaiusJard说得好。老实说,我没有太多地研究
SQL
部分,我假设OP使用的是
SQLServer
,但我想这一点仍然成立。他们应该使用该平台中的任何标准格式