1

この質問は何度も聞かれたことは知っていますが、私の質問には少しひねりがあります。仕事にはさまざまなシフトがあり、2 つの文字列shiftStartshiftEndがあります。(例: それぞれ「6:00:00 PM」と「03:00:00 AM」)。これは正午から朝までを表します。DateTime.Now がこの期間内にあるかどうかを通知する関数を作成しようとしています。

注: シフトは何でもかまいません... 朝から正午、正午から朝、固定時間 (8 時間など)はありません。

static bool NowWithinShiftTime("6:00:00 PM", "03:00:00 AM")

以下は私が試したことですが、何をしてもロジックが見つからないようです...助けてください...

static bool NowWithinShiftTime(string shiftStart, string shiftEnd)
    {
        DateTime startDate;
        DateTime endDate;
        DateTime now = DateTime.Now; 

        TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay;
        TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay;

        if (startTime < endTime) // same day
        {
            startDate = new DateTime(now.Year, now.Month, now.Day) + startTime;
            endDate = new DateTime(now.Year, now.Month, now.Day) + endTime;
        }
        else // next day
        {
            startDate = new DateTime(now.Year, now.Month, now.AddDays(-1).Hour) + startTime;
            endDate = DateTime.Today.AddDays(1) + endTime;
        }
        if (now >= startDate && now <= endDate)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
4

5 に答える 5

5

まず、すべてのビジネス ロジックが時間関連の型だけを扱うようにします。(個人的には、この作業にはNoda TimeライブラリとそのLocalTime型を使用しますが...) 解析は呼び出しコードで行うことができます。

ロジックはかなり単純です。「終了時間」が実際に「開始時間」の前にある場合は、2 つのラウンドを切り替えて結果を反転するだけです。結局のところ、1 日を「シフト時間」と「非シフト時間」に分けているだけです...そして、午前 3 時から午後 8 時までのシフトが「オフ」の場合は、(たとえば) 午後 8 時から午前 3 時までのシフトが「オン」になります。

例えば:

public bool NowWithinShiftTime(TimeSpan startTimeOfDay, TimeSpan endTimeOfDay)
{
    if (startTimeOfDay > endTimeOfDay)
    {
        return !NowWithinShiftTime(endTimeOfDay, startTimeOfDay);
    }
    TimeSpan now = DateTime.Now.TimeOfDay;
    return startTimeOfDay <= now && now < endTimeOfDay;
}

ノート:

  • 隣接する間隔がある場合、任意の値が正確に 1 になるように、間隔に適している傾向があるため、これを意図的に半閉じにしました。必要なものを正確に確認してください。ただし、1 日に 2 つの正確な時点にのみ関連します。
  • このコードは現在、テストが困難です。「時計」の概念をインターフェイスに抽象化して、偽の時計をテストに使用できるようにすることをお勧めします。(Noda Time がこれを行い、適切な を提供しますFakeClock。)
于 2013-09-30T18:42:14.063 に答える
1

私はあなたがそこに90%いると信じています:

static bool NowWithinShiftTime(string shiftStart, string shiftEnd)
{
    DateTime startDate;
    DateTime endDate;
    DateTime now = DateTime.Now; 

    TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay;
    TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay;

    if (startTime < endTime) // same day
    {
        startDate = DateTime.Today + startTime;
        endDate = DateTime.Today + endTime;
    }
    else // next day
    {
        startDate = DateTime.Today  + startTime;
        endDate = DateTime.Today.AddDays(1) + endTime;
    }
    if (now >= startDate && now <= endDate)
    {
        return true;
    }
    else
    {
        return false;
    }
}

これが機能することを示すアイデアがあります:http://ideone.com/rdb867

于 2013-09-30T18:40:37.397 に答える
1

これはうまくいくはずです

static bool NowWithinShiftTime(string shiftStart, string shiftEnd)
{
   DateTime now = DateTime.Now;
   DateTime startDate = DateTime.Parse(shiftStart);
   DateTime endDate = DateTime.Parse(shiftEnd);

   if (endDate < startDate)
   {
        endDate = endDate.AddDays(1);
   }

   return now >= startDate && now <= endDate;
}
于 2013-09-30T18:44:51.077 に答える
0

これはうまくいくはずです:

bool IsWithinTimeRange(DateTime dateToCompare, DateTime startDate, DateTime endDate)
{
    TimeSpan timeToCompare = dateToCompare.TimeOfDay;
    TimeSpan start = startDate.TimeOfDay;
    TimeSpan end = endDate.TimeOfDay;

    if (start < end)
        return timeToCompare >= start && timeToCompare <= end;
    else
        return !(end < timeToCompare && timeToCompare < start);
}
于 2013-09-30T18:42:21.737 に答える