C# 日期时间在午夜重置

C# 日期时间在午夜重置,c#,datetime,C#,Datetime,嗨,我正在visual studio上使用C#web应用程序 我编写了代码,以便能够区分时间是否在6am-2pm-2pm-10pm和10pm-6am之间 对于6-2-2-10次,代码运行就像做梦一样,但是对于晚上10点到早上6点。。代码可以正常运行到午夜,然后它将我的计数器重置为0,并保持在0直到早上6点。。我弄不明白为什么会这样。。有人有解决办法吗 public DateTime Shiftstart { get; set; } public DateTime Shiftend { get;

嗨,我正在visual studio上使用C#web应用程序

我编写了代码,以便能够区分时间是否在
6am-2pm
-
2pm-10pm
10pm-6am
之间

对于6-2-2-10次,代码运行就像做梦一样,但是对于晚上10点到早上6点。。代码可以正常运行到午夜,然后它将我的计数器重置为0,并保持在0直到早上6点。。我弄不明白为什么会这样。。有人有解决办法吗

public DateTime Shiftstart { get; set; }

public DateTime Shiftend { get; set; }

public string Itemseriesmaster { get; set; }

public string SeriesMasterId { get; set; }

public void CalcShiftPeriod() //constructor
{
    DateTime now = DateTime.Now; //date time now
    int currentHour = now.Hour; //hour now
    int shiftHourStart;

    if (currentHour >= 6 && currentHour <= 13) 
    {
        shiftHourStart = 6;
    }
    else if  (currentHour >= 14 && currentHour <= 21)
    {
        shiftHourStart = 14;
    }
    else 
    {
        shiftHourStart = 22;
    }


    Shiftstart = now.Date.AddHours(shiftHourStart);
    Shiftend = Shiftstart.AddHours(7);
    Shiftend = Shiftend.AddMinutes(59);
    Shiftend = Shiftend.AddSeconds(59);
}

您必须区分从0到5的
currentHour
和从22到23的
currentHour

例如,考虑<代码> CurruthOuts<代码>为1。您的计算表明班次在当天的22:00开始(

now.Date.AddHours(22)
),这显然是错误的,因为班次已经在前一天的22:00开始

因此,从
currentHour
0到5,您必须从
Shiftstart
中减去一天


一种可能的方法是将
currentHour
shiftHourStart
设置为
-2
,使
currentHour
介于0和5之间

if (currentHour < 6)
{
    shiftHourStart = -2;
}
else if (currentHour >= 6 && currentHour <= 13) 
{
    shiftHourStart = 6;
}
else if  (currentHour >= 14 && currentHour <= 21)
{
    shiftHourStart = 14;
}
else 
{
    shiftHourStart = 22;
}
if(当前小时<6)
{
shiftHourStart=-2;
}

否则,如果(currentHour>=6&¤tHour=14&¤tHour错误在于将小时数添加到当前日期中

Shiftstart = now.Date.AddHours(shiftHourStart);
23:59,您将在“2018-11-06”中增加22小时

一分钟过去了

00:00时,“2018-11-07”将增加22小时

这意味着你的开始时间在这一分钟内移动了24小时

您可以将此场景作为if语句的一部分加以区分。请参见下面的注释a)和b)

int currentHour=now.Hour;
DateTime date=now.date;//a) 这是今天在大多数情况下。。。
int-shiftHourStart;
如果(当前小时>=6&¤tHour=14&¤tHour=22)
{
shiftHourStart=22;
}
其他的
{
//午夜至早上6点
date=date.AddDays(-1);//b),但在本例中不是
shiftHourStart=22;
}

首先将您的时间存储在
时间跨度中
如果明天的班次在30分钟开始和结束,这将为您提供更大的灵活性。然后将这些
Timespan
存储在表示时间范围的类中。如果你有他们的清单,那就列个清单。它将有助于阅读和维护您的代码。现在,这是一个魔术数字早午餐

为了检查某个时间是否在某个范围内,我使用了:

public static bool IsBetween(TimeSpan time, TimeSpan start, TimeSpan end)
    => (start <= end) ? time >= start && time <= end : time >= start || time <= end;


internal void TestMethod()
{
    var timeSlots = new[] {
        new TimeFrame { start= new TimeSpan(6,0,0) , end = new TimeSpan(13,0,0) },
        new TimeFrame { start= new TimeSpan(14,0,0) , end = new TimeSpan(21,0,0) },
        new TimeFrame { start= new TimeSpan(22,0,0) , end = new TimeSpan(6,0,0) }
    };

    var today = DateTime.Today;
    var dayHours = Enumerable.Range(0, 24).Select(x => today.AddHours(x)).ToList();

    foreach (var currentDateTime in dayHours)
    {
        var matchingRanges = timeSlots.Where(x => IsBetween(currentDateTime .TimeOfDay, x.start, x.end));
        if (matchingRanges.Any())
        {
            var temp = matchingRanges.First();
            Console.WriteLine($"-> {currentDateTime } is in range {temp.start}-{temp.end}");                
            Console.WriteLine($"\t ShiftHours= {temp.start}-{temp.end.Subtract(new TimeSpan(0, 0, 1))}");
        }
        else
        {
            Console.WriteLine($"no Match for {currentDateTime }");
        }
    }
}
public static bool IsBetween(TimeSpan time、TimeSpan start、TimeSpan end)
=>(start=start&&time=start | |今天的时间。AddHours(x)).ToList();
foreach(var currentDateTime,以天小时为单位)
{
var matchingRanges=timeslot.Where(x=>IsBetween(currentDateTime.TimeOfDay,x.start,x.end));
if(matchingRanges.Any())
{
var temp=matchingRanges.First();
Console.WriteLine($“->{currentDateTime}在范围{temp.start}-{temp.end})内);
Console.WriteLine($“\t ShiftHours={temp.start}-{temp.end.Subtract(新的时间跨度(0,0,1))}”);
}
其他的
{
WriteLine($“与{currentDateTime}不匹配”);
}
}
}

您添加了一条关于午夜测试的注释,其中包括一个TestMethod,我在其中创建了一天中的所有时间(从00小时到23小时),以便您可以轻松地看到发生了什么。

从您发布的代码中看,问题的原因并不明显,这对于确定当前班次来说似乎很好。提供一个可以重现您观察到的问题的最小完整示例。在22小时的情况下,您可能需要从
现在.Date
中减去-1天,但如果没有上下文,这是很难说的。“代码正在计算打包的总单位,工作正常,并在给定的”。。。同时显示此代码如果我传入一些前一个日期的静态日期和时间,那么晚上10点到早上6点的班次会正确显示所有的数字,但是当它在服务器上实时运行时,它会在午夜重置为0,并一直保持到早上6点。我使用
public static bool TimeInRange(TimeSpan time,TimeSpan start,TimeSpan end)=>(start=start&&time=start | | time感谢大家的回复,我将尝试上面的方法。我想我必须等到午夜来,直到我可以测试这个?“我想我必须等到午夜来,直到我可以测试这个?”测试时间到了。你可以用你想要的小时数创建日期时间。谢谢,我也会尝试。很抱歉我缺乏知识,但我需要在代码中做些什么才能让它像你的建议一样工作?@FelicityPerry你只需在现有语句之前预先编写if语句。我已经更新了答案。@FelicityPerry,当你为测试添加问题时ing,我有一个问题,这段代码清楚吗?我需要用and if/else或三元来格式化ISBEVER逻辑吗?LinQ清楚吗?
        int currentHour = now.Hour;
        DateTime date = now.Date; // a) This is today in most cases...

        int shiftHourStart;

        if (currentHour >= 6 && currentHour <= 13)
        {
            shiftHourStart = 6;
        }
        else if (currentHour >= 14 && currentHour <= 21)
        {
            shiftHourStart = 14;
        }
        else if (currentHour >= 22)
        {
            shiftHourStart = 22;
        }
        else
        {
            // midnight to 6am
            date = date.AddDays(-1); // b) But not in this case
            shiftHourStart = 22;
        }
public static bool IsBetween(TimeSpan time, TimeSpan start, TimeSpan end)
    => (start <= end) ? time >= start && time <= end : time >= start || time <= end;


internal void TestMethod()
{
    var timeSlots = new[] {
        new TimeFrame { start= new TimeSpan(6,0,0) , end = new TimeSpan(13,0,0) },
        new TimeFrame { start= new TimeSpan(14,0,0) , end = new TimeSpan(21,0,0) },
        new TimeFrame { start= new TimeSpan(22,0,0) , end = new TimeSpan(6,0,0) }
    };

    var today = DateTime.Today;
    var dayHours = Enumerable.Range(0, 24).Select(x => today.AddHours(x)).ToList();

    foreach (var currentDateTime in dayHours)
    {
        var matchingRanges = timeSlots.Where(x => IsBetween(currentDateTime .TimeOfDay, x.start, x.end));
        if (matchingRanges.Any())
        {
            var temp = matchingRanges.First();
            Console.WriteLine($"-> {currentDateTime } is in range {temp.start}-{temp.end}");                
            Console.WriteLine($"\t ShiftHours= {temp.start}-{temp.end.Subtract(new TimeSpan(0, 0, 1))}");
        }
        else
        {
            Console.WriteLine($"no Match for {currentDateTime }");
        }
    }
}