Суммируйте часы от разных форматированных дат. C # - PullRequest
0 голосов
/ 07 октября 2019

У меня проблема. Мне нужно суммировать часы, отработанные в офисе, в коде. Даты, которые я получаю с SQL-сервера, это не проблема, но у меня разные форматы. Например: 2019. 09. 23. 14: 54: 23 , 2019.09.23 14: 54: 23 или 2019-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();

Он работал, но когда появлялись разные форматы, он не работал из-за '-' или пробелов. Пожалуйста, помогите!

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Ваш код должен выглядеть примерно так:

    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. Всегда объединяйте параметр в, а затем присваивайте значение параметру. Всегда
  • Трудно читать, длинная конкатенация строк - выглядит ужасно, всегда избегайте этого, если можете
  • Открытие и закрытие соединения БД - микроуправлениеСоединение с базой данных не требуется при использовании адаптера данных, потому что он открывается и закрывается для вас
  • Код DataReader, заполненный магическими числами - GetString (7), хммм .. было время, когдавремя вышло? GetInt (4) - это был возраст? Год? Здесь мы избавляемся от всех вызовов GetXX для чтения данных с их порядковыми номерами столбцов и заполняем DataTable (что-то вроде 2D-массива) строками, которые можно индексировать по именам строк. Это все еще не так хорошо, как могло бы быть (строго типизированные DataTables лучше), но это огромный скачок, лучше, чем заполнять код магическими числами и работать со всем самым неясным, слабо типизированным способом
  • Неуклюжая обработка времени - это пошло на пользу разбора Даты, потому что вытягивать строки в биты номер за номером, преобразовывать их в целые числа, умножать их на секунды и часы, чтобы ими можно было манипулировать, утомительно и трудно читать - убратьсо всем этим путем синтаксического анализа этих строк для типов данных , которые они должны были хранить, как прежде всего ;вам нужно записать дату и время, когда это происходит. Старайтесь изо всех сил преобразовать эту БД, чтобы эти вещи правильно сохранялись, и до тех пор конвертируйте ваши строки в DateTime
  • Различая даты с использованием секунд : использование вычислений TimeSpan означает, что нет необходимости преобразовывать вещи всекунды, сделать грубую математику, отбросить все понятия о часовых поясах, или изменения летнего времени и т.д .;используя даты, вычтенные друг из друга, вы получаете промежуток времени между этими датами, который учитывает такие вещи, как переход на летнее время. Или даже возможность иметь одну дату, которая наступит завтра, или X дней в будущем. Может не иметь значения для этого приложения, но однажды оно может ..

Если у вас есть MySQL 8, вы можете заменить регулярное выражение в БД. Может даже заставить БД различать и суммировать даты. Мы не можем дать никаких рекомендаций по этому вопросу, потому что мы не знаем имен столбцов

1 голос
/ 07 октября 2019

В C# имеется множество методов для преобразования строк, содержащих дату и время во многих форматах, в единый объект DateTime. Эти методы могут распознавать довольно много стандартных форматов даты и времени, и если ваши отличаются от них, вы даже можете предоставить свой собственный.

  • DateTime.Parse() - преобразует строку в объект DateTime. Если операция завершится неудачно, будет выдано исключение.
  • DateTime.TryParse() - Преобразует строку в DateTime объект , только если это возможно . Возвращает true в случае успеха и false в случае неудачи.
  • DateTime.TryParseExact() - Преобразует строку в указанном формате в объект DateTime. Возвращает true в случае успеха и false в противном случае.

В вашем случае вы можете использовать DateTime.TryParse() (что рекомендуется вместо простого использования DateTime.Parse(), если вы не абсолютно уверены в форматеправильно) вот так:

var dtStr1 = " 2019. 09. 23. 14:54:23";
var dtStr2 = "2019.09.23 14:54:23";
var dtStr3 = "2019-09-23 14:54:23";

DateTime.TryParse(dtStr1, out DateTime dt1);
DateTime.TryParse(dtStr2, out DateTime dt2);
DateTime.TryParse(dtStr3, out DateTime dt3);

После преобразования в объект DateTime с ним больше не ассоциируется формат. Это structure, и, следовательно, имеет только переменные-члены и методы. Таким образом, для расчета общего количества часов и т. Д. Вы можете использовать предоставленные методы.

Допустим, вы хотите рассчитать время между началом и окончанием рабочего дня. Вы можете преобразовать их в 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, будетдаст вам кучу свойств с разницей в часах, минутах и ​​т. д.

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

7

54

16

0

TimeSpan.TotalMinutes и т. Д. Даст вам весь период времени в соответствующих единицах.

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

Вывод:

0.329351851851852

7.90444444444444

474.266666666667

28456

28456000

И наоборот, когда вы храните данные в базе данных, вы должны сноваиспользуйте стандартный формат, например datetime или datetime2. Рекомендуется использовать datetime2, подробнее здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...