2014-12-09 5 views
1

У меня есть форма, которая дает мне time_in и time_out часы всех сотрудников. Time_in и time_out также таблицы sql. В основном форма возвращает значения таблицы базы данных. То, что я хотел бы сделать, - показать рабочий час. Рабочий час может быть получен с отличием от time_out до time_in. У меня есть два текстовых поля, отображающих время и Time_out. Третий должен отображать рабочий час.Как найти разницу во времени между двумя моментами в C#

Вот что у меня есть для значения time_out в среду:

//Selected TimeOutWednesday 
     SqlCommand TimeOutWednesdayMain = cs.CreateCommand(); 
     TimeOutWednesdayMain.CommandText = "SELECT CONVERT(VARCHAR(8), time_out, 108) AS time_out FROM job_punch_card WHERE emp_key='" + listBoxNames.SelectedValue.ToString() + "'and punch_day= DATEADD(week, DATEDIFF(day, 0, getdate())/7, 2)"; 
     Object TimeOutWednesdayMainTemp = TimeOutWednesdayMain.ExecuteScalar(); 
     txtTimeInWed.Text = TimeOutWednesdayMainTemp.ToString(); 

Этот код дает мне time_out на среду для выбранного пользователя из моего списка. У меня есть тот же код для time_in. Что я не мог сделать, так это выяснить, как найти рабочий час? Как я могу показать свой рабочий час в ярлыке или текстовом поле, как у меня выше?

+1

Почему бы не использовать запрос, который затягивает время, время и разницу в часах? Также я предполагаю, что 'time_in' и' time_out' являются 'DateTime', это правильно? – juharr

+5

Ваш код открыт для SQL-инъекции –

+0

Исправить. Как получить разницу в sql? – GoGo

ответ

3

Типы DateTime в ОС являются Simples Целые значения, вы должны сделать арифметическую операцию и получить часы или TotalHours:
часов получить целую часть разницы (не проигрывают разобрать ваши текстовые поля):

DateTime time_in; 
DateTime.TryParse(time_in_TextBox.Text, out time_in); 

DateTime time_out; 
DateTime.TryParse(time_out_TextBox.Text, out time_out); 

int hours = (time_in - time_out).Hours; 


TotalHours получить двойное значение с точным различием в DateTimes:

DateTime time_in; 
DateTime.TryParse(time_in_TextBox.Text, out time_in); 

DateTime time_out; 
DateTime.TryParse(time_out_TextBox.Text, out time_out); 

double totalHours = (time_in - time_out).TotalHours; 
+0

Именно это я и ищу. Все ответы работают, но мне кажется, что это легко. Спасибо, парни! – GoGo

2

Я не знаю, если вы настроены на выполнение разницы во времени в SQL, но вот как вы можете это сделать на C# - хотя вам нужно будет преобразовать объект datetime, а не просто время (по крайней мере в этом примере).

См https://dotnetfiddle.net/DSuHmH:

using System; 

public class Program 
{ 
    public static void Main() 
    { 
     DateTime startTime = new DateTime(2014, 1, 1, 1, 5, 1); 
     DateTime endTime = new DateTime(2014, 1, 1, 5, 10, 55); 

     TimeSpan ts = endTime - startTime; 

     Console.WriteLine(ts); // returns "04:05:54" 
    } 
} 

конкретно получить часы использовать:

ts.Hours; 

Для выполнения в SQL вы можете сделать что-то вроде следующего - снова вам нужно конвертировать время в datetime, а затем вы можете использовать функцию датиффа.

См: http://sqlfiddle.com/#!6/b7a7c/7

select convert(datetime, '2014-01-01 ' + startTime, 101), 
     convert(datetime, '2014-01-01 ' + endTime, 101), 
     datediff(
      hh, 
      convert(datetime, '2014-01-01 ' + startTime, 101), 
      convert(datetime, '2014-01-01 ' + endTime, 101) 
     ) 
from test 

Обратите внимание, что в приведенных выше примерах я использую произвольную дату для выполнения создания действительного DateTime

+0

Да. Я должен получить время начала и окончания с сервера sql. – GoGo

+1

Обратите внимание, что 'TimeSpan.Hours' получает часовую часть' TimeSpan'. OP может захотеть вместо этого использовать «TimeSpan.TotalHours». – juharr

+1

@ Karatay, вы все еще можете сделать это в этом случае, это просто предназначено для использования в качестве примера – Kritner

2

Вы можете получить разницу во времени, в течение нескольких минут, используя это:

DATEDIFF(MINUTE, @punch_day, @time_out) 

Это вернет общие минуты между двумя датами. Если вам нужны часы, разделите его на 60. Если вам нужны дни, разделите их на (60*24). Если вам нужны недели, разделите его на (60*24*7). Если вам нужны годы, разделите его на (60*24*365). Надеюсь, вы получите эту идею!

Заканчивать этот пример:

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 

SELECT @StartDate = '12/9/2014 11:04am' 
SELECT @EndDate = '12/10/2014 1:38pm' 
SELECT DATEDIFF(MINUTE, @StartDate, @EndDate) AS TotalMinutes, 
     DATEDIFF(MINUTE, @StartDate, @EndDate)/60 AS TotalHours, 
     DATEDIFF(MINUTE, @StartDate, @EndDate)/(60*24) AS TotalDays 
+0

, почему бы просто не использовать 'lateiff (hh ....)' в этом случае, а не вычислять часы на основе минут? это частичные часы, на которые вы смотрите? – Kritner

+0

@ Kritner - Он мог, но я предполагаю, что он захочет его за считанные минуты, чтобы он мог вычислять оставшиеся минуты, используя оператор модуля '%'. Плюс этот путь, он только делает один удар на сервер базы данных, против одного хита в течение нескольких часов, один удар за минуты и т. Д. – Icemanind

2

Вы должны быть в состоянии сделать это в одном запросе. Это также показывает лучшие практики работы с ADO.Net, включая размещение ваших объектов sql в использовании операторов и передачу значений в ваш запрос в качестве параметра. Кроме того, вам нужно будет использовать ExecuteReader, чтобы получить более одного значения обратно, и вы можете добавить проверку на получение более или менее 1 строки.

using (var cs = new SqlConnection("your connection string")) 
{ 
    cs.Open(); 
    using (var command = cs.CreateCommand()) 
    { 
     command.CommandText = 
      @"SELECT 
        time_in, 
        time_out, 
        DATEDIFF(minute, time_in, time_out) As minutesWorked 
       FROM job_punch_card 
       WHERE [email protected] 
        and punch_day= DATEADD(week, DATEDIFF(day, 0, getdate())/7, 2)"; 
     command.Parameters.AddWithValue(
      "@EMPKEY", 
      listBoxNames.SelectedValue.ToString()); 

     using (var reader = command.ExecuteReader()) 
     { 
      if (!reader.HasRows) 
      { 
       // There was no match for your key 
      } 

      reader.Read(); 

      DateTime timeIn = reader.GetDateTime(0); 
      DateTime timeOut = reader.GetDateTime(1); 
      int minutesWorked = reader.GetInt32(2); 

      if (reader.Read()) 
      { 
       // There was more than one match on key 
      } 
     } 
    } 
} 
Смежные вопросы