問題

私はAttendanceアプリケーションを作成しており、出席ログがスケジュールの1時間以内にあるかどうかを確認する方法を探しています

Employee1には2019年1月31日のスケジュール@ 00:30がありますが、事前に到着してチェックインするため、ログには2019年1月30日@ 23:45でチェックインします。だから私は、従業員が1時間前または1時間後にログインした場合、彼のログイン時間になることを発見しようとしています。彼が2019年1月30日から23:30日まで2019年1月31日までログインできるように。

私が現時点で行ったことは、これらを処理する4つのDateTime変数がありますが、動作していないようです。

これは私の従業員クラスです

 public class Emp1
    {
        public int ID { get; set; }
        public DateTime In { get; set; }
        public DateTime Out { get; set; }
        public DateTime dateTime1 { get; set; }
        public DateTime dateTime2 { get; set; }
        public DateTime dateTime3 { get; set; }
        public DateTime dateTime4 { get; set; }
    }
 

私の実際のAttendance Logsクラス

 public class Actual
    {
        public int ID { get; set; }
        public DateTime ActualLog { get; set; }
        public int LogStatus { get; set; }
        public DateTime date { get; set; }
    }
 

これは私の従業員スケジュールの設定方法に関する私のコードです

 List<Emp1> em = new List<Emp1>();

                foreach (DataRow row in empContainer.Rows)
                {
                    em.Add(new Emp1()
                    {
                        ID = Convert.ToInt32(row[0].ToString()),
                        In = Convert.ToDateTime(row[1].ToString()),
                        Out = Convert.ToDateTime(row[2].ToString()),
                        dateTime1 = Convert.ToDateTime(row[1].ToString()).AddHours(1),
                        dateTime2 = Convert.ToDateTime(row[1].ToString()).AddHours(-1),
                        dateTime3 = Convert.ToDateTime(row[2].ToString()).AddHours(1),
                        dateTime4 = Convert.ToDateTime(row[2].ToString()).AddHours(-1)
                    });
                }
 

これは私のDataGridにデータを設定する私の現在のLINQステートメントです

 public void Main()
        {
            List<Emp1> emps;
            List<Actual> actuals;

            actuals = emp.GetActual(@"C:\Users\IT\Desktop\Sample\SampleActual.dat");
            emps = GetEmpSched();



            var final = (from a1 in actuals
                         join a2 in actuals on a1.ID equals a2.ID
                         join t1 in emps on a1.ID equals t1.ID
                         join t2 in emps on a2.ID equals t2.ID
                         where ((a1.LogStatus == 0) && (a2.LogStatus == 1)) && ((t1.In == t2.In) && (t1.Out==t2.Out)) && ((t1.dateTime1 > a1.ActualLog) && (a1.ActualLog > t1.dateTime2)) && ((t2.dateTime3 > a2.ActualLog) && (a2.ActualLog > t2.dateTime4))
                         select new
                         {
                             User_ID = t1.ID,
                             Scheduled_In = t1.In,
                             Actual_Login = a1.ActualLog,
                             Scheduled_Out = t2.Out,
                             Actual_Out = a2.ActualLog
                         }).Distinct(). ToList();

            tbContainer = StaticClasses.ToDataTable(final);

            dgvAttendance.ItemsSource = emp.CalculateEmployeeAttendance(tbContainer);
        }
 

これは私の従業員スケジュールソースです

Employee Schedule

これは私の従業員の攻撃ログです

Attendance Logs

あなたが見ているように、私は余分な時間またはそれ以下の時間を処理するために追加した4つの余分なDateTime変数を持っていますが、それでも私はアイデアがないので動作しません。

これは現在の出力です Actual Output

だから私は自分の条件のためにデータがありませんが、うまく動作するはずですが、間違った出力を生成します。

なぜこれが起こっているのですか?

私を助ける答えは素晴らしいだろう。ありがとう

  ベストアンサー

私はあなたが難しい方法を試していると思う、これはもっと簡単なはずです。

実際のログイン時間をスケジュールされたログと比較し、それが1時間以内であるかどうかを確認するには、両方をサブストラクションして違いを確認してください。

それはC#で簡単です:

     var scheduledLogIn = new TimeSpan(8, 0, 0);
    var actualLogIn = new DateTime(2019, 1, 31, 8, 15, 27);

    var delay = (actualLogIn.TimeOfDay - scheduledLogIn).Duration();

    if (delay.TotalHours < 1)
    {
        // It's ok
    } else
    {
        // more than 1h earlier or late!
    }
 

実際に早いか遅いかを確認したい場合は、Durationを削除し、TotalHoursが負/正かどうかを確認します。

  同じタグがついた質問を見る

c#listlinqdatetime