我如何只工作时间日期时间和时间添加

时间:2015-06-10 11:54:17

标签: c# datetime timespan

我的代码如下。我希望用户在我显示2天2小时后选择10.06.2015 09:00 - 12.06.2015 13:00

但是我想在09:00 - 18:00之间的工作日和工作时间,10.06.2015 09:00 - 12.06.2015 13:00我希望仅显示2.5天的用户。

我该怎么办?

DateTime t1 = dateTimePicker1.Value.Date;
DateTime t2 = dateTimePicker2.Value.Date;

string s1 = textBox9.Text;
string s2 = textBox10.Text;

DateTime dt1 = t1.AddMinutes(DateTime.Parse(s1).TimeOfDay.TotalMinutes);
DateTime dt2 = t2.AddMinutes(DateTime.Parse(s2).TimeOfDay.TotalMinutes);

var fark = dt2 - dt1;

    label1.Text =
String.Format("{0}{1}{2}",       
fark.Days > 0 ? string.Format("{0} gün", fark.Days) : "",
fark.Hours > 0 ? string.Format("{0} saat ", fark.Hours) : "",
fark.Minutes > 0 ? string.Format("{0} dakika ", fark.Minutes) : "").Trim();

4 个答案:

答案 0 :(得分:0)

嗯,你可以假设该范围内的任何日子,除了第一个和最后一个是完整的工作日。所以你需要(AllDaysInRange -2)+ HoursInfirstDay + HoursInLastDay。

TimeSpan ts = t2 - t1;
ts.Days = ts.Days - 2; //Allow for the 2 end days

int Day1Hours = t1.Hours - 9;//This removes any hours between 00.00 and 09.00
if (day1Hours > 9) //Then the user was working past 18.00
    ts.Days = ts.Days+1
else
    ts.Hours = ts.Hours + day1Hours;

int Day2Hours = t2.Hours - 9;//This removes any hours between 00.00 and 09.00
if (day2Hours > 9) //Then the user was working past 18.00
    ts.Days = ts.Days+1
else
    ts.Hours = ts.Hours + day2Hours;

如果你可以让它工作(我已经从内存中写了),那么我将包装代码以将结束日的小时数转换为方法而不是重复它。

答案 1 :(得分:0)

根据DateTime Picker In WinForm How To Pick Time?帖子,你可以改变你的DateTimePicker,也可以随时间运行。

要限制用户可以选择的范围,您可以修改ValueChanged事件或为其编写自己的验证。 可能最简单的是:

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        if (dateTimePicker1.Value.Hour < 10) // the 10 is just a random number, you can change it to your own limit
            dateTimePicker1.Value = this.dateTimePicker1.Value.AddHours(10 - dateTimePicker1.Value.Hour);
    }

根据工作时间计算你的2,5天,我会写一个函数来处理这个责任,如:

private int TimeInWorkingHours(DateTime start, DateTime end, int firstHour, int lastHour)
    {
        int days = Math.Min(end.Subtract(start).Days - 2, 0) ;
        int hoursInADay = lastHour - firstHour;

        int result = days * hoursInADay;

        result += start.Hour - firstHour;
        result += lastHour - end.Hour;

        return result;
    }

这样您就可以使用开始日期和结束日期调用TimeInWorkingHours(...)函数,同时提供您的第一个和最后一个工作时间。

首先计算工作天数,然后计算边界小时数。通过这种方式,您可以获得工作时间,然后按工作时间除以获得工作时间。

答案 2 :(得分:0)

试试这个

bool IsWorkingDay(DateTime dt)
{
    int year = dt.Year;
    Dictionary<DateTime, object> holidays = new Dictionary<DateTime, object>();
    holidays.Add(new DateTime(year, 1, 1), null);
    holidays.Add(new DateTime(year, 1, 6), null);
    holidays.Add(new DateTime(year, 4, 25), null);
    holidays.Add(new DateTime(year, 5, 1), null);
    holidays.Add(new DateTime(year, 6, 2), null);
    holidays.Add(new DateTime(year, 8, 15), null);
    holidays.Add(new DateTime(year, 11, 1), null);
    holidays.Add(new DateTime(year, 12, 8), null);
    holidays.Add(new DateTime(year, 12, 25), null);
    holidays.Add(new DateTime(year, 12, 26), null);
    DateTime easterMonday = EasterSunday(year).AddDays(1);
    if (!holidays.ContainsKey(easterMonday))
        holidays.Add(easterMonday, null);

    if (!holidays.ContainsKey(dt.Date))
        if (dt.DayOfWeek > DayOfWeek.Sunday && dt.DayOfWeek < DayOfWeek.Saturday)
            return true;

    return false;
}

string WorkingTime(DateTime dt1, DateTime dt2)
{
    // Adjust begin datetime
    if (IsWorkingDay(dt1))
    {
        if (dt1.TimeOfDay < TimeSpan.FromHours(9))
            dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0);
        else if (dt1.TimeOfDay > TimeSpan.FromHours(13) && dt1.TimeOfDay < TimeSpan.FromHours(14))
            dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 14, 0, 0);
        else if (dt1.TimeOfDay > TimeSpan.FromHours(18))
            dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0).AddDays(1);
    }
    else
        dt1 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 9, 0, 0).AddDays(1);

    // Adjust end datetime
    if (IsWorkingDay(dt2))
    {
        if (dt2.TimeOfDay < TimeSpan.FromHours(9))
            dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0).AddDays(-1);
        else if (dt2.TimeOfDay > TimeSpan.FromHours(18))
            dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0);
        else if (dt2.TimeOfDay > TimeSpan.FromHours(13) && dt2.TimeOfDay < TimeSpan.FromHours(14))
            dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 13, 0, 0);
    }
    else
        dt2 = new DateTime(dt2.Year, dt2.Month, dt2.Day, 18, 0, 0).AddDays(-1);

    double days = 0;
    double hours = 0;
    double minutes = 0;

    if (dt2 > dt1)
    {
        // Move dt1 forward to reach dt2 day chacking for working days
        while (dt1.DayOfYear < dt2.DayOfYear)
        {
            if (IsWorkingDay(dt1))
                days++;
            dt1 = dt1.AddDays(1);
        }

        // Now get the worked hours as if were on the same day in the same manner
        TimeSpan sdwt = dt2 - dt1;
        if (dt1.TimeOfDay < TimeSpan.FromHours(13) && dt2.TimeOfDay > TimeSpan.FromHours(14))
            sdwt -= TimeSpan.FromHours(1);
        if (sdwt == TimeSpan.FromHours(8))
            days++;
        else
        {
            hours = sdwt.Hours;
            minutes = sdwt.Minutes;
        }
    }

    // There is a pause in between so adjust if the interval include it

    var totalminutes = (days * 8 * 60 + hours * 60 + minutes);

    string res = String.Format("{0} days {1} hours {2} minutes",
        days,
        hours,
        minutes);
    string totRes = String.Format("{0} days {1} hours {2} minutes",
        totalminutes / 8 / 60,
        totalminutes / 8,
        totalminutes);

    return res + "\r\n" + totRes;
}

答案 3 :(得分:0)

试试这个

private void GetProperOfficeHours(ref DateTime date)
    {
        int minHour = 9, maxHour = 17;

        if (date.Hour < minHour) //if earlier than office hours - start from 9am
        {
            date = date + new TimeSpan(9, 0, 0);
        }
        else if (date.Hour > maxHour) //if later than office hours - go to next day 9am
        {
            date = date.AddDays(1) + new TimeSpan(9, 0, 0);
        }
    }

然后......

//assuming firstDate & lastDate have date and time
        int[] weekendDays = new int[2] { 0, 6 }; // Sunday and Saturday

        GetProperOfficeHours(ref firstDate);
        GetProperOfficeHours(ref lastDate);

        while (weekendDays.Contains((int)firstDate.DayOfWeek))
        {
            //get next date
            firstDate = firstDate.AddDays(1);
        }

        while (weekendDays.Contains((int)lastDate.DayOfWeek))
        {
            //get prev date
            lastDate = lastDate.AddDays(-1);
        }

        double hourDiff = Math.Abs(firstDate.Hour - lastDate.Hour) / 8.0; //8 office hours
        double dayDifference = 0;
        while (firstDate.Date <= lastDate.Date) //Loop and skip weekends
        {
            if (!weekendDays.Contains((int)firstDate.DayOfWeek)) //can also check for holidays here
                dayDifference++;

            firstDate = firstDate.AddDays(1);
        }

        dayDifference = dayDifference + hourDiff;

可能需要一些调整,希望你觉得它有用。