1

我知道这个问题已经被问过很多次了,但我的有一个小小的转折。工作中有许多不同的班次,我有两个字符串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类型来完成这项工作,但是......)解析可以在调用代码中进行。

逻辑相当简单:如果“结束时间”实际上早于“开始时间”,那么只需切换两轮并反转结果。毕竟,您只是将一天分为“轮班时间”和“不轮班时间”......每当凌晨 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;
}

笔记:

  • 我故意将其设为半封闭,因为这往往适用于间隔,因此如果您有相邻的间隔,任何给定的值都会恰好落入一个。准确检查您想要的内容,尽管它仅与每天这两个确切的时间点相关。
  • 该代码目前很难测试:我鼓励您将“时钟”的概念抽象到接口中,这样您就可以使用假时钟进行测试。(Noda Time 会为您执行此操作,并提供适当的FakeClock.)
于 2013-09-30T18:42:14.063 回答
5

你可以坚持TimeSpan

static bool NowWithinShiftTime(string shiftStart, string shiftEnd)
{
    TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay;
    TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay;
    TimeSpan now = DateTime.Now.TimeOfDay;

    if (startTime < endTime)
        return now >= startTime && now <= endTime;
    else
        return now >= startTime || now <= endTime;
}
于 2013-09-30T18:36:58.183 回答
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 回答
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;
    }
}

这是一个证明它有效的ideone:http: //ideone.com/rdb867

于 2013-09-30T18:40:37.397 回答
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 回答