将时间添加到日期时间,但不包括周末,并且应介于工作时间之间

本文关键字:时间 于工作 工作 之间 日期 添加 不包括 周末 | 更新日期: 2023-09-27 18:25:29

我试图在日期中添加小时,但希望新日期不包括周末,并且只能在9.00到17.00之间。

示例:

第一种情况:

if my date is 23/02/2012 16:00:00.
if I add 4 hours to that my new date should be 24/02/2012 12:00:00 (which will be within working hours)

第二种情况:

if my date is 24/02/2012 09:00:00 (which is a friday)
if I add 24 hours then the new date should be 27/02/2012 09:00:00 (which would be monday next week at 9am)

到目前为止,我得到了这个,但被卡住了,因为这不计入过去的任何日期,比如通过的日期是2012年2月10日(上周星期五):

   private static void ExcludeWeekend(Datetime dt)
    {
        DateTime todaysDate = DateTime.Today;
        DateTime dueDate = null;
                if (dueDate.DayOfWeek == DayOfWeek.Friday)
                {
                    dueDate.AddHours(48);
                }
                else if (dueDate.DayOfWeek == DayOfWeek.Saturday)
                {
                    dueDate.AddHours(72);
                }
    }

将时间添加到日期时间,但不包括周末,并且应介于工作时间之间

您可以使用.NET:的时间段库中的类CalendarDateAdd

// ----------------------------------------------------------------------
public void CalendarDateAddSample()
{
  CalendarDateAdd calendarDateAdd = new CalendarDateAdd();
  // use only weekdays
  calendarDateAdd.AddWorkingWeekDays();
  // setup working hours
  calendarDateAdd.WorkingHours.Add( new HourRange( new Time( 09 ), new Time( 17 ) ) );
  DateTime start = new DateTime( 2012, 2, 23 ); // start date
  TimeSpan offset = new TimeSpan( 4, 0, 0 ); // 4 hours
  DateTime? end = calendarDateAdd.Add( start, offset ); // end date
  Console.WriteLine( "start: {0}", start );
  Console.WriteLine( "offset: {0}", offset );
  Console.WriteLine( "end: {0}", end );
} // CalendarDateAddSample
 static DateTime AddWithinWorkingHours(DateTime start, TimeSpan offset)
 {
    const int hoursPerDay = 8;
    const int startHour = 9;
    // Don't start counting hours until start time is during working hours
    if (start.TimeOfDay.TotalHours > startHour + hoursPerDay)
       start = start.Date.AddDays(1).AddHours(startHour);
    if (start.TimeOfDay.TotalHours < startHour)
       start = start.Date.AddHours(startHour);
    if (start.DayOfWeek == DayOfWeek.Saturday)
       start.AddDays(2);
    else if (start.DayOfWeek == DayOfWeek.Sunday)
       start.AddDays(1);
    // Calculate how much working time already passed on the first day
    TimeSpan firstDayOffset = start.TimeOfDay.Subtract(TimeSpan.FromHours(startHour));
    // Calculate number of whole days to add
    int wholeDays = (int)(offset.Add(firstDayOffset).TotalHours / hoursPerDay);
    // How many hours off the specified offset does this many whole days consume?
    TimeSpan wholeDaysHours = TimeSpan.FromHours(wholeDays * hoursPerDay);
    // Calculate the final time of day based on the number of whole days spanned and the specified offset
    TimeSpan remainder = offset - wholeDaysHours;
    // How far into the week is the starting date?
    int weekOffset = ((int)(start.DayOfWeek + 7) - (int)DayOfWeek.Monday) % 7;
    // How many weekends are spanned?
    int weekends = (int)((wholeDays + weekOffset) / 5);
    // Calculate the final result using all the above calculated values
    return start.AddDays(wholeDays + weekends * 2).Add(remainder);
 }
    var d1 = DateTime.Now;
    var ts = TimeSpan.FromHours(40);
    var d2 = d1 + ts;
    if(d2.DayOfWeek == DayOfWeek.Saturday) {
        d2 = d2.AddDays(2);
    }else if(d2.DayOfWeek == DayOfWeek.Sunday){
        d2 = d2.AddDays(1);
    }

如果你真的想让它成为一个扩展:

var d2 = DateTime.Now.AddSkipWeekend(TimeSpan.FromHours(40));
static class DateExtensions { 
    public static DateTime AddSkipWeekend(this DateTime date1, TimeSpan ts){
        DateTime d2 = date1 + ts;
        if(d2.DayOfWeek == DayOfWeek.Saturday) {
            d2 = d2.AddDays(2);
        } else if(d2.DayOfWeek == DayOfWeek.Sunday) {
            d2 = d2.AddDays(1);
        }
        return d2;
    }
}

编辑:刚刚实现您的非工作时间要求:

var d2 = DateTime.Now.AddSkipWeekend(TimeSpan.FromHours(50),TimeSpan.FromHours(9),TimeSpan.FromHours(17));
public static DateTime AddSkipWeekend(this DateTime date1, TimeSpan addTime, TimeSpan workStart, TimeSpan workEnd)
{
    DateTime d2 = date1 + addTime;
    if(d2.TimeOfDay < workStart) {
        d2 = d2.Add(workStart - d2.TimeOfDay);
    } else if(d2.TimeOfDay > workEnd) {
        d2 = d2.Add(TimeSpan.FromHours(12) - d2.TimeOfDay);
    }
    if(d2.DayOfWeek == DayOfWeek.Saturday) {
        d2 = d2.AddDays(2);
    } else if(d2.DayOfWeek == DayOfWeek.Sunday) {
        d2 = d2.AddDays(1);
    }
    return d2;
}

试试这个:

public static DateTime Add(DateTime dt, TimeSpan t)
{
    while (true)
    {
        dt = Max(dt, dt.Date.AddHours(9));
        DateTime x = Min(dt + t, dt.Date.AddHours(17));
        // Console.WriteLine("{0} -> {1} ({2})", dt, x, x - dt);
        t -= x - dt;
        dt = x;
        if (t == TimeSpan.Zero) { return dt; }
        do { dt = dt.Date.AddDays(1); } while (dt.IsWeekendDay());
    }
}

此处的Helper方法。

示例1:

var result = Add(DateTime.Parse("23/02/2012 16:00:00"), TimeSpan.FromHours(4));
// result == {24/02/2012 12:00:00}
23/02/2012 16:00:00 -> 23/02/2012 17:00:00 (01:00:00)
24/02/2012 09:00:00 -> 24/02/2012 12:00:00 (03:00:00)

示例2:

var result = Add(DateTime.Parse("24/02/2012 09:00:00"), TimeSpan.FromHours(24));
// result == {28/02/2012 17:00:00}
24/02/2012 09:00:00 -> 24/02/2012 17:00:00 (08:00:00)
27/02/2012 09:00:00 -> 27/02/2012 17:00:00 (08:00:00)
28/02/2012 09:00:00 -> 28/02/2012 17:00:00 (08:00:00)

这不是一个优雅的解决方案,但它似乎有效。

DateTime AddHoursIgnoreWeekend(DateTime startDate, int hours)
{
    DateTime endDate = startDate;
    for (int i = 0; i < hours; i++) {
        endDate = endDate.AddHours(1);
        if (endDate.DayOfWeek == DayOfWeek.Saturday || endDate.DayOfWeek == DayOfWeek.Sunday) 
        {
            i--;
        }
    }
    return endDate;
 }