दो तिथियों के बीच व्यावसायिक दिनों की संख्या की गणना करें?


95

में सी #, मैं कैसे की संख्या की गणना कर सकते हैं व्यापार दो तिथियों के बीच (या काम करने के दिन) दिनों?


1
यहां C # में एक उदाहरण दिया गया है जो घंटों के रूप में भी फैलता है। codeproject.com/KB/datetime/CalculatingBusinessHours.aspx
WesleyJohnson


4
तो क्या आप छुट्टियों को छोड़ सकते हैं?
pxl

जवाबों:


120

मैंने पहले भी ऐसा काम किया है और मुझे इसका हल मिल गया है। मैं बीच में सभी दिनों की गणना करने से बचूंगा जब यह परिहार्य होगा, जो कि यहां है। जैसा कि मैंने ऊपर दिए गए एक उत्तर में देखा था, मैं डेटटाइम इंस्टेंस का एक गुच्छा बनाने का उल्लेख नहीं करता हूं। यह वास्तव में प्रसंस्करण शक्ति की बर्बादी है। विशेष रूप से वास्तविक दुनिया की स्थिति में, जब आपको कई महीनों के समय अंतराल की जांच करनी होगी। नीचे दिए गए टिप्पणियों के साथ, मेरा कोड देखें।

    /// <summary>
    /// Calculates number of business days, taking into account:
    ///  - weekends (Saturdays and Sundays)
    ///  - bank holidays in the middle of the week
    /// </summary>
    /// <param name="firstDay">First day in the time interval</param>
    /// <param name="lastDay">Last day in the time interval</param>
    /// <param name="bankHolidays">List of bank holidays excluding weekends</param>
    /// <returns>Number of business days during the 'span'</returns>
    public static int BusinessDaysUntil(this DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays)
    {
        firstDay = firstDay.Date;
        lastDay = lastDay.Date;
        if (firstDay > lastDay)
            throw new ArgumentException("Incorrect last day " + lastDay);

        TimeSpan span = lastDay - firstDay;
        int businessDays = span.Days + 1;
        int fullWeekCount = businessDays / 7;
        // find out if there are weekends during the time exceedng the full weeks
        if (businessDays > fullWeekCount*7)
        {
            // we are here to find out if there is a 1-day or 2-days weekend
            // in the time interval remaining after subtracting the complete weeks
            int firstDayOfWeek = (int) firstDay.DayOfWeek;
            int lastDayOfWeek = (int) lastDay.DayOfWeek;
            if (lastDayOfWeek < firstDayOfWeek)
                lastDayOfWeek += 7;
            if (firstDayOfWeek <= 6)
            {
                if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval
                    businessDays -= 2;
                else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval
                    businessDays -= 1;
            }
            else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval
                businessDays -= 1;
        }

        // subtract the weekends during the full weeks in the interval
        businessDays -= fullWeekCount + fullWeekCount;

        // subtract the number of bank holidays during the time interval
        foreach (DateTime bankHoliday in bankHolidays)
        {
            DateTime bh = bankHoliday.Date;
            if (firstDay <= bh && bh <= lastDay)
                --businessDays;
        }

        return businessDays;
    }

Slauma द्वारा संपादित, अगस्त 2011

बहुत बढ़िया जवाब! हालांकि थोड़ा बग है। मैं इस उत्तर को संपादित करने की स्वतंत्रता लेता हूं क्योंकि 2009 के बाद से उत्तरदाता अनुपस्थित है।

ऊपर DayOfWeek.Sundayदिया गया कोड मानता है कि ऐसा मूल्य है 7जो मामला नहीं है। मूल्य वास्तव में है 0। यह गलत गणना की ओर जाता है यदि उदाहरण के लिए firstDayऔर lastDayदोनों एक ही रविवार हैं। 1इस मामले में विधि वापस आती है लेकिन यह होनी चाहिए 0

इस बग के लिए सबसे आसान निर्धारण: लाइनों के ऊपर कोड में बदलें, जहां firstDayOfWeekऔर lastDayOfWeekनिम्नलिखित द्वारा घोषित किए गए हैं:

int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday 
    ? 7 : (int)firstDay.DayOfWeek;
int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday
    ? 7 : (int)lastDay.DayOfWeek;

अब परिणाम है:

  • शुक्रवार से शुक्रवार -> 1
  • शनिवार से शनिवार -> 0
  • रविवार से रविवार -> 0
  • शुक्रवार से शनिवार -> १
  • शुक्रवार से रविवार -> १
  • शुक्रवार से सोमवार -> 2
  • शनिवार से सोमवार -> 1
  • रविवार से सोमवार -> 1
  • सोमवार से सोमवार -> 1

1
+1 यह शायद सबसे आसान और सबसे कारगर तरीका है, (C ++ से आने वाला मेरा समाधान TimeSpan के समर्थन का उपयोग नहीं करता है, C # कुछ कार्यों को इतना आसान बना देता है)। BankHolidays एक अच्छा स्पर्श भी है!
RedGlyph

2
यह भी सुनिश्चित करें कि बैंक की छुट्टियां निम्नानुसार हैं: यदि (firstDay <= bh && bh <= lastDay && bh.IsWorkingDay ())
Tawani

5
विधि के लिए धन्यवाद। हालांकि, अगर मुझे बयान में बैंक छुट्टियों के विकल्प / पुनरावृत्ति में निम्नलिखित को जोड़ना पड़ा, तो && !(bh.DayOfWeek == DayOfWeek.Sunday || bh.DayOfWeek == DayOfWeek.Saturday), अन्यथा यह एक ही दिन में दो बार घटित होगा, अगर एक सप्ताह के अंत में छुट्टी आती है।
क्रिस्टियनबी

मैंने Linq स्टेटमेंट के लिए अंतिम लूप बदल दिया: businessDays - = bankHolidays.Select (bankHoliday => bankHoliday.Date) .Count (bh => firstDay <= bh && b </ lastDay);
JoanComasFdz

1
इसके अलावा वे ऐसे देश हैं जिनके पास शनिवार, रविवार में सप्ताहांत नहीं है। अधिक जानकारी के लिए यह लिंक देखें: en.wikipedia.org/wiki/Workweek_and_weekend
Gatej Alexandru

104

ठीक। मुझे लगता है कि यह सही उत्तर पोस्ट करने का समय है:

public static double GetBusinessDays(DateTime startD, DateTime endD)
{
    double calcBusinessDays =
        1 + ((endD - startD).TotalDays * 5 -
        (startD.DayOfWeek - endD.DayOfWeek) * 2) / 7;

    if (endD.DayOfWeek == DayOfWeek.Saturday) calcBusinessDays--;
    if (startD.DayOfWeek == DayOfWeek.Sunday) calcBusinessDays--;

    return calcBusinessDays;
}

मूल स्रोत:

http://alecpojidaev.wordpress.com/2009/10/29/work-days-calculation-with-c/

PS समाधान ऊपर किसी कारण के लिए मुझे बनाने के लिए तैनात हैं।


10
अच्छा काम है, लेकिन शायद DayOfWeek enums का उपयोग करने के बजाय उन्हें डाली में डाल दिया?
नव

3
गंभीरता से, सबसे अच्छा समाधान वहाँ। चीयर्स एलेक
Mizmor

6
ध्यान दें कि भले ही यह फ़ंक्शन एक दोहरा रिटर्न देता है, यह केवल पूरे व्यावसायिक दिनों को देने के लिए विश्वसनीय होना चाहिए । यह आंशिक समय के लिए सही जवाब नहीं देता है जब समय शामिल होता है।
Pakman

4
बस टिप्पणी करने के लिए, के साथ '1 +' यह मान लिया गया है शुरू जब तक पहले दिन के अंत अंतिम दिन का, बिना '1 +' यह मान लिया गया है अंत तक पहले दिन के अंत अंतिम दिन का। मुझे यह पता लगाने में थोड़ा समय लगा, क्योंकि मैं अंतिम दिन की शुरुआत तक पहले दिन की शुरुआत कर रहा था , जिससे मुझे और अधिक समझ में आया।
जेफ्री वैन डे वुर्स्ट

11
यह वह जगह है नहीं सही जवाब। दिन 4 बजे तक बाहर हो सकते हैं। लगभग सही है, सप्ताहांत के आसपास शुरू होने और समाप्त होने के दिन को ध्यान में नहीं रखते हैं, जो सबसे कठिन बिट है। प्रारंभ - अंत कोष्ठक के अंदर भी नहीं होना चाहिए। यह समस्या से कोई लेना देना नहीं है। इस समाधान का 60% समय गलत है
उल्लू

47

मुझे पता है कि यह प्रश्न पहले से ही हल है, लेकिन मुझे लगा कि मैं एक और अधिक सरल-सटीक उत्तर प्रदान कर सकता हूं जो भविष्य में अन्य आगंतुकों की मदद कर सकता है।

यहाँ मेरा यह ले रहा है:

public int GetWorkingDays(DateTime from, DateTime to)
{
    var dayDifference = (int)to.Subtract(from).TotalDays;
    return Enumerable
        .Range(1, dayDifference)
        .Select(x => from.AddDays(x))
        .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
}

यह मेरा मूल सबमिशन था:

public int GetWorkingDays(DateTime from, DateTime to)
{
    var totalDays = 0;
    for (var date = from; date < to; date = date.AddDays(1))
    {
        if (date.DayOfWeek != DayOfWeek.Saturday
            && date.DayOfWeek != DayOfWeek.Sunday)
            totalDays++;
    }

    return totalDays;
}

"जहां" इसे छोटा करने के लिए "गिनती" हो सकती है
बजे

1
बहुत स्पष्ट, और प्रगणित समाधान बैंक की छुट्टियों को खत्म करने के लिए खुद को उधार देते हैं। वे हालांकि थोक में बहुत धीमे हैं; LINQPad में 1 मिलियन चलना पाश में 90 दिन अंतराल के लिए कार्य दिवसों की गणना करने पर इस समाधान का उपयोग करने में 10s लगते हैं, और स्वीकृत उत्तर या एलेक पॉजिदेव के बहुत अच्छे एक का उपयोग करके केवल 0.2 के बारे में।
Whelkaholism

समावेशी होने के लिए, कोड होना चाहिए: Enumerable लौटें ।Range (0, dayDifference + 1) ...
Edza

अतीत में दिन नहीं लौटते। जैसे -18 कार्य दिवस।
११

@iwtu यह मानता है कि to > from । शायद यही समस्या है?
अल्फा

22

डेटटाइम पर एक्सटेंशन विधि को इस तरह परिभाषित करें:

public static class DateTimeExtensions
{
    public static bool IsWorkingDay(this DateTime date)
    {
        return date.DayOfWeek != DayOfWeek.Saturday
            && date.DayOfWeek != DayOfWeek.Sunday;
    }
}

फिर, तारीखों की एक विस्तृत सूची को फ़िल्टर करने के लिए एक क्लॉज़ का उपयोग कहाँ होता है:

var allDates = GetDates(); // method which returns a list of dates

// filter dates by working day's  
var countOfWorkDays = allDates
     .Where(day => day.IsWorkingDay())
     .Count() ;

क्या आप अभी आगे नहीं बढ़ेंगे और टाइमपास को भी आगे बढ़ाएंगे ताकि आप उसका उपयोग कर सकें - क्योंकि उन्होंने कहा कि वह दो तारीखों के बीच की दूरी का उपयोग करना चाहते हैं और तारीखों की सूची नहीं?
वेस्ले जॉनसन

दो तिथियों के बीच की दूरी दिन की संख्या है, इसलिए गणना () पर्याप्त है।
कारल्स कंपनी

3
मुझे यकीन नहीं है कि यह एक उपयुक्त उत्तर क्यों है ... उसके पास अलग-अलग दिनों की सूची नहीं है, उसके पास दो तारीखें हैं और वह उन दोनों के बीच व्यावसायिक दिनों की संख्या का पता लगाना चाहता है। इस समाधान का उपयोग करने के लिए आपको एक और फ़ंक्शन प्रदान करना होगा जो ट्वीप के बीच हर तारीख की सूची तैयार करता है।
एडम रॉबिन्सन

1
adam, यह एक सरल उदाहरण है जिसमें न्यूनतम मात्रा में कोड है जो एक अवधारणा को प्रदर्शित करने के लिए आवश्यक है। अपने मूल उत्तर में, मैंने एक लूप को भी शामिल किया, जिसने allDates सूची को पॉप्युलेट किया, जिसे मैंने "गेटडेट्स" फ़ंक्शन में समाप्त कर दिया है। IsWorkingDay परीक्षण को आसानी से LINQ स्टेटमेंट और उस लूप से बाहर ले जाया जा सकता है। मुझे व्यक्तिगत रूप से पसंद है कि अब यह कैसे है क्योंकि यह बहुत मानवीय है जो कि हो रहा है।
क्वर्टी

10
व्हेन टू काउंट को बदलकर और गणना को समाप्त करके छोटा किया जा सकता है
पुनरावर्ती

12

मैंने बैंक की छुट्टियों को ध्यान में रखते हुए निम्नलिखित कोड का उपयोग किया:

public class WorkingDays
{
    public List<DateTime> GetHolidays()
    {
        var client = new WebClient();
        var json = client.DownloadString("https://www.gov.uk/bank-holidays.json");
        var js = new JavaScriptSerializer();
        var holidays = js.Deserialize <Dictionary<string, Holidays>>(json);
        return holidays["england-and-wales"].events.Select(d => d.date).ToList();
    }

    public int GetWorkingDays(DateTime from, DateTime to)
    {
        var totalDays = 0;
        var holidays = GetHolidays();
        for (var date = from.AddDays(1); date <= to; date = date.AddDays(1))
        {
            if (date.DayOfWeek != DayOfWeek.Saturday
                && date.DayOfWeek != DayOfWeek.Sunday
                && !holidays.Contains(date))
                totalDays++;
        }

        return totalDays;
    }
}

public class Holidays
{
    public string division { get; set; }
    public List<Event> events { get; set; }
}

public class Event
{
    public DateTime date { get; set; }
    public string notes { get; set; }
    public string title { get; set; }
}

और यूनिट टेस्ट:

[TestClass]
public class WorkingDays
{
    [TestMethod]
    public void SameDayIsZero()
    {
        var service = new WorkingDays();

        var from = new DateTime(2013, 8, 12);

        Assert.AreEqual(0, service.GetWorkingDays(from, from));

    }

    [TestMethod]
    public void CalculateDaysInWorkingWeek()
    {
        var service = new WorkingDays();

        var from = new DateTime(2013, 8, 12);
        var to = new DateTime(2013, 8, 16);

        Assert.AreEqual(4, service.GetWorkingDays(from, to), "Mon - Fri = 4");

        Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 13)), "Mon - Tues = 1");
    }

    [TestMethod]
    public void NotIncludeWeekends()
    {
        var service = new WorkingDays();

        var from = new DateTime(2013, 8, 9);
        var to = new DateTime(2013, 8, 16);

        Assert.AreEqual(5, service.GetWorkingDays(from, to), "Fri - Fri = 5");

        Assert.AreEqual(2, service.GetWorkingDays(from, new DateTime(2013, 8, 13)), "Fri - Tues = 2");
        Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 12)), "Fri - Mon = 1");
    }

    [TestMethod]
    public void AccountForHolidays()
    {
        var service = new WorkingDays();

        var from = new DateTime(2013, 8, 23);

        Assert.AreEqual(0, service.GetWorkingDays(from, new DateTime(2013, 8, 26)), "Fri - Mon = 0");

        Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 27)), "Fri - Tues = 1");
    }
}

आप 1 दिन के लिए "@" से (var date = from.AddDays (1), <= to, date = date.AddDays (1)) जोड़कर गणना क्यों शुरू करते हैं?
ओनसेल उमूट टूरर

6

खैर इसको पीट-पीटकर मार डाला गया है। :) हालाँकि मैं अभी भी एक और उत्तर देने जा रहा हूँ क्योंकि मुझे कुछ अलग चाहिए था। यह समाधान इस मायने में अलग है कि यह एक बिजनेस टाइमस्पैन लौटाता है शुरुआत और अंत के बीच , और आप दिन के व्यापार घंटे निर्धारित कर सकते हैं, और छुट्टियां जोड़ सकते हैं। तो आप यह गणना करने के लिए उपयोग कर सकते हैं कि क्या यह एक दिन के भीतर, दिन भर में, सप्ताहांत में और यहाँ तक कि छुट्टियों के दौरान भी होता है। और आप केवल व्यावसायिक दिनों को प्राप्त कर सकते हैं या केवल प्राप्त किए गए टाइमफ़ैन ऑब्जेक्ट से आपको ज़रूरत नहीं है। और जिस तरह से यह दिनों की सूचियों का उपयोग करता है, आप देख सकते हैं कि गैर-कार्य दिवसों की सूची को जोड़ना कितना आसान होगा यदि यह विशिष्ट सत और सूर्य नहीं है। और मैंने एक साल तक परीक्षण किया, और यह सुपर फास्ट लगता है।

मुझे उम्मीद है कि कोड चिपकाना सटीक होगा। लेकिन मुझे पता है कि यह काम करता है।

public static TimeSpan GetBusinessTimespanBetween(
    DateTime start, DateTime end,
    TimeSpan workdayStartTime, TimeSpan workdayEndTime,
    List<DateTime> holidays = null)
{
    if (end < start)
        throw new ArgumentException("start datetime must be before end datetime.");

    // Just create an empty list for easier coding.
    if (holidays == null) holidays = new List<DateTime>();

    if (holidays.Where(x => x.TimeOfDay.Ticks > 0).Any())
        throw new ArgumentException("holidays can not have a TimeOfDay, only the Date.");

    var nonWorkDays = new List<DayOfWeek>() { DayOfWeek.Saturday, DayOfWeek.Sunday };

    var startTime = start.TimeOfDay;

    // If the start time is before the starting hours, set it to the starting hour.
    if (startTime < workdayStartTime) startTime = workdayStartTime;

    var timeBeforeEndOfWorkDay = workdayEndTime - startTime;

    // If it's after the end of the day, then this time lapse doesn't count.
    if (timeBeforeEndOfWorkDay.TotalSeconds < 0) timeBeforeEndOfWorkDay = new TimeSpan();
    // If start is during a non work day, it doesn't count.
    if (nonWorkDays.Contains(start.DayOfWeek)) timeBeforeEndOfWorkDay = new TimeSpan();
    else if (holidays.Contains(start.Date)) timeBeforeEndOfWorkDay = new TimeSpan();

    var endTime = end.TimeOfDay;

    // If the end time is after the ending hours, set it to the ending hour.
    if (endTime > workdayEndTime) endTime = workdayEndTime;

    var timeAfterStartOfWorkDay = endTime - workdayStartTime;

    // If it's before the start of the day, then this time lapse doesn't count.
    if (timeAfterStartOfWorkDay.TotalSeconds < 0) timeAfterStartOfWorkDay = new TimeSpan();
    // If end is during a non work day, it doesn't count.
    if (nonWorkDays.Contains(end.DayOfWeek)) timeAfterStartOfWorkDay = new TimeSpan();
    else if (holidays.Contains(end.Date)) timeAfterStartOfWorkDay = new TimeSpan();

    // Easy scenario if the times are during the day day.
    if (start.Date.CompareTo(end.Date) == 0)
    {
        if (nonWorkDays.Contains(start.DayOfWeek)) return new TimeSpan();
        else if (holidays.Contains(start.Date)) return new TimeSpan();
        return endTime - startTime;
    }
    else
    {
        var timeBetween = end - start;
        var daysBetween = (int)Math.Floor(timeBetween.TotalDays);
        var dailyWorkSeconds = (int)Math.Floor((workdayEndTime - workdayStartTime).TotalSeconds);

        var businessDaysBetween = 0;

        // Now the fun begins with calculating the actual Business days.
        if (daysBetween > 0)
        {
            var nextStartDay = start.AddDays(1).Date;
            var dayBeforeEnd = end.AddDays(-1).Date;
            for (DateTime d = nextStartDay; d <= dayBeforeEnd; d = d.AddDays(1))
            {
                if (nonWorkDays.Contains(d.DayOfWeek)) continue;
                else if (holidays.Contains(d.Date)) continue;
                businessDaysBetween++;
            }
        }

        var dailyWorkSecondsToAdd = dailyWorkSeconds * businessDaysBetween;

        var output = timeBeforeEndOfWorkDay + timeAfterStartOfWorkDay;
        output = output + new TimeSpan(0, 0, dailyWorkSecondsToAdd);

        return output;
    }
}

और यहाँ परीक्षण कोड है: ध्यान दें कि आपको इस फ़ंक्शन को काम करने के लिए टेस्ट कोड के लिए डेटहेल्पर नामक कक्षा में रखना होगा ।

[TestMethod]
public void TestGetBusinessTimespanBetween()
{
    var workdayStart = new TimeSpan(8, 0, 0);
    var workdayEnd = new TimeSpan(17, 0, 0);

    var holidays = new List<DateTime>()
    {
        new DateTime(2018, 1, 15), // a Monday
        new DateTime(2018, 2, 15) // a Thursday
    };

    var testdata = new[]
    {
        new
        {
            expectedMinutes = 0,
            start = new DateTime(2016, 10, 19, 9, 50, 0),
            end = new DateTime(2016, 10, 19, 9, 50, 0)
        },
        new
        {
            expectedMinutes = 10,
            start = new DateTime(2016, 10, 19, 9, 50, 0),
            end = new DateTime(2016, 10, 19, 10, 0, 0)
        },
        new
        {
            expectedMinutes = 5,
            start = new DateTime(2016, 10, 19, 7, 50, 0),
            end = new DateTime(2016, 10, 19, 8, 5, 0)
        },
        new
        {
            expectedMinutes = 5,
            start = new DateTime(2016, 10, 19, 16, 55, 0),
            end = new DateTime(2016, 10, 19, 17, 5, 0)
        },
        new
        {
            expectedMinutes = 15,
            start = new DateTime(2016, 10, 19, 16, 50, 0),
            end = new DateTime(2016, 10, 20, 8, 5, 0)
        },
        new
        {
            expectedMinutes = 10,
            start = new DateTime(2016, 10, 19, 16, 50, 0),
            end = new DateTime(2016, 10, 20, 7, 55, 0)
        },
        new
        {
            expectedMinutes = 5,
            start = new DateTime(2016, 10, 19, 17, 10, 0),
            end = new DateTime(2016, 10, 20, 8, 5, 0)
        },
        new
        {
            expectedMinutes = 0,
            start = new DateTime(2016, 10, 19, 17, 10, 0),
            end = new DateTime(2016, 10, 20, 7, 5, 0)
        },
        new
        {
            expectedMinutes = 545,
            start = new DateTime(2016, 10, 19, 12, 10, 0),
            end = new DateTime(2016, 10, 20, 12, 15, 0)
        },
        // Spanning multiple weekdays
        new
        {
            expectedMinutes = 835,
            start = new DateTime(2016, 10, 19, 12, 10, 0),
            end = new DateTime(2016, 10, 21, 8, 5, 0)
        },
        // Spanning multiple weekdays
        new
        {
            expectedMinutes = 1375,
            start = new DateTime(2016, 10, 18, 12, 10, 0),
            end = new DateTime(2016, 10, 21, 8, 5, 0)
        },
        // Spanning from a Thursday to a Tuesday, 5 mins short of complete day.
        new
        {
            expectedMinutes = 1615,
            start = new DateTime(2016, 10, 20, 12, 10, 0),
            end = new DateTime(2016, 10, 25, 12, 5, 0)
        },
        // Spanning from a Thursday to a Tuesday, 5 mins beyond complete day.
        new
        {
            expectedMinutes = 1625,
            start = new DateTime(2016, 10, 20, 12, 10, 0),
            end = new DateTime(2016, 10, 25, 12, 15, 0)
        },
        // Spanning from a Friday to a Monday, 5 mins beyond complete day.
        new
        {
            expectedMinutes = 545,
            start = new DateTime(2016, 10, 21, 12, 10, 0),
            end = new DateTime(2016, 10, 24, 12, 15, 0)
        },
        // Spanning from a Friday to a Monday, 5 mins short complete day.
        new
        {
            expectedMinutes = 535,
            start = new DateTime(2016, 10, 21, 12, 10, 0),
            end = new DateTime(2016, 10, 24, 12, 5, 0)
        },
        // Spanning from a Saturday to a Monday, 5 mins short complete day.
        new
        {
            expectedMinutes = 245,
            start = new DateTime(2016, 10, 22, 12, 10, 0),
            end = new DateTime(2016, 10, 24, 12, 5, 0)
        },
        // Spanning from a Saturday to a Sunday, 5 mins beyond complete day.
        new
        {
            expectedMinutes = 0,
            start = new DateTime(2016, 10, 22, 12, 10, 0),
            end = new DateTime(2016, 10, 23, 12, 15, 0)
        },
        // Times within the same Saturday.
        new
        {
            expectedMinutes = 0,
            start = new DateTime(2016, 10, 22, 12, 10, 0),
            end = new DateTime(2016, 10, 23, 12, 15, 0)
        },
        // Spanning from a Saturday to the Sunday next week.
        new
        {
            expectedMinutes = 2700,
            start = new DateTime(2016, 10, 22, 12, 10, 0),
            end = new DateTime(2016, 10, 30, 12, 15, 0)
        },
        // Spanning a year.
        new
        {
            expectedMinutes = 143355,
            start = new DateTime(2016, 10, 22, 12, 10, 0),
            end = new DateTime(2017, 10, 30, 12, 15, 0)
        },
        // Spanning a year with 2 holidays.
        new
        {
            expectedMinutes = 142815,
            start = new DateTime(2017, 10, 22, 12, 10, 0),
            end = new DateTime(2018, 10, 30, 12, 15, 0)
        },
    };

    foreach (var item in testdata)
    {
        Assert.AreEqual(item.expectedMinutes,
            DateHelper.GetBusinessTimespanBetween(
                item.start, item.end,
                workdayStart, workdayEnd,
                holidays)
                .TotalMinutes);
    }
}

5

यह समाधान पुनरावृत्ति से बचा जाता है, दोनों + ve और -ve कार्यदिवसों के अंतर के लिए काम करता है और सप्ताह के दिनों की गिनती की धीमी विधि के खिलाफ प्रतिगमन के लिए एक इकाई परीक्षण सूट शामिल है। मैंने कार्यदिवस को जोड़ने के लिए एक संक्षिप्त विधि भी शामिल की है जो एक ही गैर-पुनरावृत्त तरीके से काम करता है।

यूनिट परीक्षण कुछ हजार तिथि संयोजनों को कवर करते हैं ताकि छोटे और बड़े दोनों तिथि सीमाओं के साथ सभी प्रारंभ / अंत कार्यदिवसों के संयोजन का परीक्षण किया जा सके।

महत्वपूर्ण : हम यह धारणा बनाते हैं कि हम शुरुआत की तारीख को छोड़कर और अंतिम तिथि सहित दिनों की गिनती कर रहे हैं। यह महत्वपूर्ण है जब कार्यदिवस की गिनती विशिष्ट शुरुआत / अंत दिनों के रूप में हो जिसमें आप शामिल हों / परिणाम को प्रभावित करें। यह भी सुनिश्चित करता है कि दो बराबर दिनों के बीच का अंतर हमेशा शून्य हो और हम केवल पूर्ण कार्य दिवसों को शामिल करें क्योंकि आमतौर पर आप चाहते हैं कि उत्तर चालू तिथि (किसी भी समय) पर किसी भी समय के लिए सही हो और पूर्ण समाप्ति तिथि शामिल करें (जैसे एक नियत तारीख)।

नोट: इस कोड को छुट्टियों के लिए एक अतिरिक्त समायोजन की आवश्यकता है लेकिन उपरोक्त धारणा को ध्यान में रखते हुए, इस कोड को प्रारंभ तिथि पर छुट्टियों को बाहर करना होगा।

कार्यदिवस जोड़ें:

private static readonly int[,] _addOffset = 
{
  // 0  1  2  3  4
    {0, 1, 2, 3, 4}, // Su  0
    {0, 1, 2, 3, 4}, // M   1
    {0, 1, 2, 3, 6}, // Tu  2
    {0, 1, 4, 5, 6}, // W   3
    {0, 1, 4, 5, 6}, // Th  4
    {0, 3, 4, 5, 6}, // F   5
    {0, 2, 3, 4, 5}, // Sa  6
};

public static DateTime AddWeekdays(this DateTime date, int weekdays)
{
    int extraDays = weekdays % 5;
    int addDays = weekdays >= 0
        ? (weekdays / 5) * 7 + _addOffset[(int)date.DayOfWeek, extraDays]
        : (weekdays / 5) * 7 - _addOffset[6 - (int)date.DayOfWeek, -extraDays];
    return date.AddDays(addDays);
}

कार्यदिवस अंतर की गणना करें:

static readonly int[,] _diffOffset = 
{
  // Su M  Tu W  Th F  Sa
    {0, 1, 2, 3, 4, 5, 5}, // Su
    {4, 0, 1, 2, 3, 4, 4}, // M 
    {3, 4, 0, 1, 2, 3, 3}, // Tu
    {2, 3, 4, 0, 1, 2, 2}, // W 
    {1, 2, 3, 4, 0, 1, 1}, // Th
    {0, 1, 2, 3, 4, 0, 0}, // F 
    {0, 1, 2, 3, 4, 5, 0}, // Sa
};

public static int GetWeekdaysDiff(this DateTime dtStart, DateTime dtEnd)
{
    int daysDiff = (int)(dtEnd - dtStart).TotalDays;
    return daysDiff >= 0
        ? 5 * (daysDiff / 7) + _diffOffset[(int) dtStart.DayOfWeek, (int) dtEnd.DayOfWeek]
        : 5 * (daysDiff / 7) - _diffOffset[6 - (int) dtStart.DayOfWeek, 6 - (int) dtEnd.DayOfWeek];
}

मैंने पाया कि स्टैक ओवरफ्लो पर अधिकांश अन्य समाधान या तो धीमे (पुनरावृत्त) या अत्यधिक जटिल थे और कई सीधे सादे गलत थे। नैतिक कहानी है ... जब तक उस पर भरोसा न करें आपने इसे पूरी तरह से जांच नहीं लिया है !!

यूनिट परीक्षण NUnit Combinatorial परीक्षण और ShouldBe NUnit एक्सटेंशन पर आधारित है ।

[TestFixture]
public class DateTimeExtensionsTests
{
    /// <summary>
    /// Exclude start date, Include end date
    /// </summary>
    /// <param name="dtStart"></param>
    /// <param name="dtEnd"></param>
    /// <returns></returns>
    private IEnumerable<DateTime> GetDateRange(DateTime dtStart, DateTime dtEnd)
    {
        Console.WriteLine(@"dtStart={0:yy-MMM-dd ddd}, dtEnd={1:yy-MMM-dd ddd}", dtStart, dtEnd);

        TimeSpan diff = dtEnd - dtStart;
        Console.WriteLine(diff);

        if (dtStart <= dtEnd)
        {
            for (DateTime dt = dtStart.AddDays(1); dt <= dtEnd; dt = dt.AddDays(1))
            {
                Console.WriteLine(@"dt={0:yy-MMM-dd ddd}", dt);
                yield return dt;
            }
        }
        else
        {
            for (DateTime dt = dtStart.AddDays(-1); dt >= dtEnd; dt = dt.AddDays(-1))
            {
                Console.WriteLine(@"dt={0:yy-MMM-dd ddd}", dt);
                yield return dt;
            }
        }
    }

    [Test, Combinatorial]
    public void TestGetWeekdaysDiff(
        [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)]
        int startDay,
        [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)]
        int endDay,
        [Values(7)]
        int startMonth,
        [Values(7)]
        int endMonth)
    {
        // Arrange
        DateTime dtStart = new DateTime(2016, startMonth, startDay);
        DateTime dtEnd = new DateTime(2016, endMonth, endDay);

        int nDays = GetDateRange(dtStart, dtEnd)
            .Count(dt => dt.DayOfWeek != DayOfWeek.Saturday && dt.DayOfWeek != DayOfWeek.Sunday);

        if (dtEnd < dtStart) nDays = -nDays;

        Console.WriteLine(@"countBusDays={0}", nDays);

        // Act / Assert
        dtStart.GetWeekdaysDiff(dtEnd).ShouldBe(nDays);
    }

    [Test, Combinatorial]
    public void TestAddWeekdays(
        [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)]
        int startDay,
        [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)]
        int weekdays)
    {
        DateTime dtStart = new DateTime(2016, 7, startDay);
        DateTime dtEnd1 = dtStart.AddWeekdays(weekdays);     // ADD
        dtStart.GetWeekdaysDiff(dtEnd1).ShouldBe(weekdays);  

        DateTime dtEnd2 = dtStart.AddWeekdays(-weekdays);    // SUBTRACT
        dtStart.GetWeekdaysDiff(dtEnd2).ShouldBe(-weekdays);
    }
}

इसके लिए विचार एसक्यूएल समाधान से आया था जो मुझे स्टैक ओवरफ्लो पर मिला था। उनका विचार ठोस था लेकिन दुख की बात यह है कि यह एक बग था। यह + ve मानों के लिए काम करता है लेकिन उनकी लुकिंग टेबल मैपिंग -ve मानों के लिए गलत थी।
टोनी ओ'हागन

4

उस उद्देश्य के लिए कुछ कोड यहां है, जिसमें सनी छुट्टियां हैं लेकिन आप गिन सकते हैं कि किन छुट्टियों को गिनना है। ध्यान दें कि मैंने एक सीमा जोड़ी है जिसे आप हटाना चाहते हैं, लेकिन यह एक वेब-आधारित प्रणाली के लिए था और मैं नहीं चाहता था कि कोई भी इस प्रक्रिया को हॉग करने के लिए किसी बड़ी तारीख में प्रवेश करे

  public static int GetWorkdays(DateTime from ,DateTime to)
    {
        int limit = 9999;
        int counter = 0;
        DateTime current = from;
        int result = 0;

        if (from > to)
        {
            DateTime temp = from;
            from = to;
            to = temp;
        }

        if (from >= to)
        {
            return 0;
        }


        while (current <= to && counter < limit)
        {
            if (IsSwedishWorkday(current))
            {
                result++;
            }
            current = current.AddDays(1);
            counter++;

        }
        return result;
    }


    public static bool IsSwedishWorkday(DateTime date)
    {
        return (!IsSwedishHoliday(date) && date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday);
    }

    public static bool IsSwedishHoliday(DateTime date)
    {
        return (
        IsSameDay(GetEpiphanyDay(date.Year), date) ||
        IsSameDay(GetMayDay(date.Year), date) ||
        IsSameDay(GetSwedishNationalDay(date.Year), date) ||
        IsSameDay(GetChristmasDay(date.Year), date) ||
        IsSameDay(GetBoxingDay(date.Year), date) ||
        IsSameDay(GetGoodFriday(date.Year), date) ||
        IsSameDay(GetAscensionDay(date.Year), date) ||
        IsSameDay(GetAllSaintsDay(date.Year), date) ||
        IsSameDay(GetMidsummersDay(date.Year), date) ||
        IsSameDay(GetPentecostDay(date.Year), date) ||
        IsSameDay(GetEasterMonday(date.Year), date) ||
        IsSameDay(GetNewYearsDay(date.Year), date) ||
        IsSameDay(GetEasterDay(date.Year), date)
        );
    }

    // Trettondagen
    public static DateTime GetEpiphanyDay(int year)
    {
        return new DateTime(year, 1, 6);
    }

    // Första maj
    public static DateTime GetMayDay(int year)
    {
        return new DateTime(year,5,1);
    }

    // Juldagen
    public static DateTime GetSwedishNationalDay(int year)
    {
        return new DateTime(year, 6, 6);
    }


    // Juldagen
    public static DateTime GetNewYearsDay(int year)
    {
        return new DateTime(year,1,1);
    }

    // Juldagen
    public static DateTime GetChristmasDay(int year)
    {
        return new DateTime(year,12,25);
    }

    // Annandag jul
    public static DateTime GetBoxingDay(int year)
    {
        return new DateTime(year, 12, 26);
    }


    // Långfredagen
    public static DateTime GetGoodFriday(int year)
    {
        return GetEasterDay(year).AddDays(-3);
    }

    // Kristi himmelsfärdsdag
    public static DateTime GetAscensionDay(int year)
    {
        return GetEasterDay(year).AddDays(5*7+4);
    }

    // Midsommar
    public static DateTime GetAllSaintsDay(int year)
    {
        DateTime result = new DateTime(year,10,31);
        while (result.DayOfWeek != DayOfWeek.Saturday)
        {
            result = result.AddDays(1);
        }
        return result;
    }

    // Midsommar
    public static DateTime GetMidsummersDay(int year)
    {
        DateTime result = new DateTime(year, 6, 20);
        while (result.DayOfWeek != DayOfWeek.Saturday)
        {
            result = result.AddDays(1);
        }
        return result;
    }

    // Pingstdagen
    public static DateTime GetPentecostDay(int year)
    {
        return GetEasterDay(year).AddDays(7 * 7);
    }

    // Annandag påsk
    public static DateTime GetEasterMonday(int year)
    {
        return GetEasterDay(year).AddDays(1);
    }
    public static DateTime GetEasterDay(int y)
    {
        double c;
        double n;
        double k;
        double i;
        double j;
        double l;
        double m;
        double d;
        c = System.Math.Floor(y / 100.0);
        n = y - 19 * System.Math.Floor(y / 19.0);
        k = System.Math.Floor((c - 17) / 25.0);
        i = c - System.Math.Floor(c / 4) - System.Math.Floor((c - k) / 3) + 19 * n + 15;
        i = i - 30 * System.Math.Floor(i / 30);
        i = i - System.Math.Floor(i / 28) * (1 - System.Math.Floor(i / 28) * System.Math.Floor(29 / (i + 1)) * System.Math.Floor((21 - n) / 11));
        j = y + System.Math.Floor(y / 4.0) + i + 2 - c + System.Math.Floor(c / 4);
        j = j - 7 * System.Math.Floor(j / 7);
        l = i - j;
        m = 3 + System.Math.Floor((l + 40) / 44);// month
        d = l + 28 - 31 * System.Math.Floor(m / 4);// day

        double days = ((m == 3) ? d : d + 31);

        DateTime result = new DateTime(y, 3, 1).AddDays(days-1);

        return result;
    }

फ़ंक्शन issamedate गायब है, लेकिन बस सार्वजनिक स्थैतिक बूल है IsSameDay (DateTime date1, DateTime date2) {return date1.Date == date2.Date; }
चोको स्मिथ

आप नई दिनांक ऑब्जेक्ट्स को त्वरित करने के बजाय एक इंट सरणी लुकअप तालिका का उपयोग कर सकते हैं।
TheRealChx101

3

यहाँ एक त्वरित नमूना कोड है। यह एक वर्ग विधि है, इसलिए केवल आपकी कक्षा के अंदर ही काम करेगी। यदि आप यह चाहते हैं static, तो हस्ताक्षर को private static(या public static) में बदल दें।

    private IEnumerable<DateTime> GetWorkingDays(DateTime sd, DateTime ed)
    {
        for (var d = sd; d <= ed; d = d.AddDays(1))
            if (d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday)
                yield return d;
    }

यह विधि एक लूप वैरिएबल बनाता है d, इसे शुरुआती दिन के लिए प्रारंभ करता है sd, फिर एक दिन प्रत्येक वृद्धि ( d = d.AddDays(1)) द्वारा बढ़ाता है ।

यह उपयोग करके वांछित मान लौटाता है yield, जो ए बनाता है iterator। पुनरावृत्तियों के बारे में अच्छी बात यह है कि वे IEnumerableस्मृति के सभी मूल्यों को नहीं पकड़ते हैं , केवल प्रत्येक को क्रमिक रूप से बुलाते हैं। इसका मतलब यह है कि आप इस विधि को समय-समय पर याददाश्त से बाहर चलने की चिंता किए बिना कह सकते हैं।


1
यह विधि दो तिथियों के बीच व्यावसायिक दिनों की संख्या वापस नहीं करती है, यह दो तिथियों के बीच व्यावसायिक तिथियां लौटाती है। आपके द्वारा प्रस्तावित कोड बहुत साफ है और मुझे उपज का उपयोग पसंद है, लेकिन यह सवाल का जवाब नहीं देता है।
मार्टिन

3

मैंने 2 तारीखों के बीच काम के दिनों की गणना करने के लिए एक आसान, पचाने में आसान एल्गोरिथ्म, और राष्ट्रीय छुट्टियों को बाहर करने के लिए बहुत कुछ खोजा, और आखिरकार मैं इस दृष्टिकोण के साथ जाने का फैसला करता हूं:

public static int NumberOfWorkingDaysBetween2Dates(DateTime start,DateTime due,IEnumerable<DateTime> holidays)
        {
            var dic = new Dictionary<DateTime, DayOfWeek>();
            var totalDays = (due - start).Days;
            for (int i = 0; i < totalDays + 1; i++)
            {
                if (!holidays.Any(x => x == start.AddDays(i)))
                    dic.Add(start.AddDays(i), start.AddDays(i).DayOfWeek);
            }

            return dic.Where(x => x.Value != DayOfWeek.Saturday && x.Value != DayOfWeek.Sunday).Count();
        } 

मूल रूप से मैं प्रत्येक तिथि के साथ जाना चाहता था और अपनी स्थितियों का मूल्यांकन करना चाहता था:

  1. शनिवार नहीं है
  2. संडे नहीं है
  3. राष्ट्रीय अवकाश नहीं है

लेकिन इसके अलावा मैं इसे तारीखों से बचना चाहता था।

1 पूर्ण वर्ष का मूल्यांकन करने के लिए समय को चलाने और मापने के लिए, मुझे निम्नलिखित परिणाम चाहिए:

static void Main(string[] args)
        {
            var start = new DateTime(2017, 1, 1);
            var due = new DateTime(2017, 12, 31);

            var sw = Stopwatch.StartNew();
            var days = NumberOfWorkingDaysBetween2Dates(start, due,NationalHolidays());
            sw.Stop();

            Console.WriteLine($"Total working days = {days} --- time: {sw.Elapsed}");
            Console.ReadLine();

            // result is:
           // Total working days = 249-- - time: 00:00:00.0269087
        }

संपादित करें: एक नई विधि और अधिक सरल:

public static int ToBusinessWorkingDays(this DateTime start, DateTime due, DateTime[] holidays)
        {
            return Enumerable.Range(0, (due - start).Days)
                            .Select(a => start.AddDays(a))
                            .Where(a => a.DayOfWeek != DayOfWeek.Sunday)
                            .Where(a => a.DayOfWeek != DayOfWeek.Saturday)
                            .Count(a => !holidays.Any(x => x == a));

        }

1

मुझे लगता है कि उपरोक्त उत्तरों में से कोई भी वास्तव में सही नहीं है। उनमें से कोई भी सभी विशेष मामलों को हल नहीं करता है जैसे कि तिथियां शुरू होती हैं और सप्ताहांत के मध्य में समाप्त होती हैं, जब तारीख शुक्रवार को शुरू होती है और अगले सोमवार को समाप्त होती है, आदि। इसके बाद, वे सभी गणनाओं को पूरे दौर में पूरा करते हैं। दिन, इसलिए यदि प्रारंभ की तारीख उदाहरण के लिए एक शनिवार के मध्य में है, तो यह गलत परिणाम देते हुए, कार्य दिवसों से पूरे दिन का स्थान ले लेगा ...

वैसे भी, यहां मेरा समाधान है जो काफी कुशल और सरल है और सभी मामलों के लिए काम करता है। शुरुआत और समाप्ति तिथियों के लिए चाल केवल पिछले सोमवार को खोजने के लिए है, और फिर सप्ताहांत के दौरान शुरू होने और समाप्त होने पर एक छोटा सा मुआवजा दें:

public double WorkDays(DateTime startDate, DateTime endDate){
        double weekendDays;

        double days = endDate.Subtract(startDate).TotalDays;

        if(days<0) return 0;

        DateTime startMonday = startDate.AddDays(DayOfWeek.Monday - startDate.DayOfWeek).Date;
        DateTime endMonday = endDate.AddDays(DayOfWeek.Monday - endDate.DayOfWeek).Date;

        weekendDays = ((endMonday.Subtract(startMonday).TotalDays) / 7) * 2;

        // compute fractionary part of weekend days
        double diffStart = startDate.Subtract(startMonday).TotalDays - 5;
        double diffEnd = endDate.Subtract(endMonday).TotalDays - 5;

        // compensate weekenddays
        if(diffStart>0) weekendDays -= diffStart;
        if(diffEnd>0) weekendDays += diffEnd;

        return days - weekendDays;
    }

2
अगर शनिवार और रविवार को बुलाया जाए तो यह रिटर्न -1 है।
Whelkaholism

1

काम करता है और बिना छोरों के

यह विधि किसी भी लूप का उपयोग नहीं करती है और वास्तव में काफी सरल है। यह तिथि सीमा से पूरे सप्ताह तक फैलता है क्योंकि हम जानते हैं कि प्रत्येक सप्ताह में 5 व्यावसायिक दिन हैं। इसके बाद सही परिणाम प्राप्त करने के लिए प्रारंभ और समाप्ति से घटने के लिए व्यावसायिक दिनों की संख्या खोजने के लिए एक लुकअप तालिका का उपयोग करता है। मैंने यह दिखाने के लिए कि क्या चल रहा है, मदद करने के लिए गणना का विस्तार किया है, लेकिन यदि आवश्यक हो तो पूरी चीज को एक पंक्ति में संघनित किया जा सकता है।

वैसे भी, यह मेरे लिए काम करता है और इसलिए मैंने सोचा कि मैं इसे यहाँ पोस्ट करूँगा अगर यह दूसरों की मदद कर सकता है। खुश कोडिंग।

गणना

  • t: तारीखों के बीच कुल दिनों की संख्या (1 यदि न्यूनतम = अधिकतम)
  • ए + बी: कुल सप्ताह पूरे करने के लिए अतिरिक्त दिनों की आवश्यकता है
  • k: 1.4 प्रति सप्ताह कार्यदिवस की संख्या है, अर्थात (t / 7) * 5
  • c: कुल से घटाना कार्यदिवसों की संख्या
  • m: सप्ताह के प्रत्येक दिन के लिए "c" का मान ज्ञात करने के लिए एक लुकअप तालिका का उपयोग किया जाता है

संस्कृति

कोड सोमवार से शुक्रवार कार्य सप्ताह मानता है। अन्य संस्कृतियों के लिए, जैसे कि रविवार से गुरुवार, आपको गणना से पहले की तारीखों की भरपाई करनी होगी।

तरीका

public int Weekdays(DateTime min, DateTime max) 
{       
        if (min.Date > max.Date) throw new Exception("Invalid date span");
        var t = (max.AddDays(1).Date - min.Date).TotalDays;
        var a = (int) min.DayOfWeek;
        var b = 6 - (int) max.DayOfWeek;
        var k = 1.4;
        var m = new int[]{0, 0, 1, 2, 3, 4, 5}; 
        var c = m[a] + m[b];
        return (int)((t + a + b) / k) - c;
}

1
आप 1.4 मूल्य के साथ कश्मीर कैसे प्राप्त कर सकते हैं?
तोशा

0

मैं सिर्फ अपना समाधान साझा करूंगा। यह मेरे लिए काम करता है, शायद मैं अभी नोटिस नहीं करता / जानता हूं कि यह एक बग है। यदि कोई हो तो मैंने पहला अधूरा सप्ताह प्राप्त करके शुरू किया। एक पूरा सप्ताह रविवार से शनिवार तक का था, इसलिए यदि (int) _now.DayOfWeek 0 (रविवार) नहीं था, तो पहला सप्ताह अधूरा था।

मैं पहले सप्ताह के शनिवार के लिए 1 से पहले सप्ताह की गिनती को घटाता हूं और फिर नई गणना में जोड़ता हूं;

फिर मुझे आखिरी अधूरा हफ्ता मिलता है, फिर रविवार के लिए 1 घटाएं और फिर नई गिनती में जोड़ें।

फिर अंत में, पूरे सप्ताह की संख्या 5 (सप्ताह के दिनों) से गुणा करके नई गणना में जोड़ा गया।

public int RemoveNonWorkingDays(int numberOfDays){

            int workingDays = 0;

            int firstWeek = 7 - (int)_now.DayOfWeek;

            if(firstWeek < 7){

                if(firstWeek > numberOfDays)
                    return numberOfDays;

                workingDays += firstWeek-1;
                numberOfDays -= firstWeek;
            }


            int lastWeek = numberOfDays % 7;

            if(lastWeek > 0){

                numberOfDays -= lastWeek;
                workingDays += lastWeek - 1;

            }

            workingDays += (numberOfDays/7)*5;

            return workingDays;
        }

0

मुझे इस कोड का एक ठोस TSQL संस्करण खोजने में समस्या हो रही थी। नीचे अनिवार्य रूप से हॉलिडे टेबल के अतिरिक्त सी # कोड का रूपांतरण है जिसका उपयोग छुट्टियों की पूर्व-गणना के लिए किया जाना चाहिए।

CREATE TABLE dbo.Holiday
(
    HolidayDt       DATE NOT NULL,
    Name            NVARCHAR(50) NOT NULL,
    IsWeekday       BIT NOT NULL,
    CONSTRAINT PK_Holiday PRIMARY KEY (HolidayDt)
)
GO
CREATE INDEX IDX_Holiday ON Holiday (HolidayDt, IsWeekday)

GO

CREATE function dbo.GetBusinessDays
(
     @FirstDay  datetime,
     @LastDay   datetime
) 
RETURNS INT
 AS
BEGIN
    DECLARE @BusinessDays INT, @FullWeekCount INT 
    SELECT  @FirstDay = CONVERT(DATETIME,CONVERT(DATE,@FirstDay))
        ,   @LastDay = CONVERT(DATETIME,CONVERT(DATE,@LastDay))

    IF @FirstDay > @LastDay
        RETURN NULL;

    SELECT @BusinessDays = DATEDIFF(DAY, @FirstDay, @LastDay) + 1 
    SELECT @FullWeekCount = @BusinessDays / 7;

    -- find out if there are weekends during the time exceedng the full weeks
    IF @BusinessDays > (@FullWeekCount * 7)
    BEGIN
    -- we are here to find out if there is a 1-day or 2-days weekend
    -- in the time interval remaining after subtracting the complete weeks
        DECLARE @firstDayOfWeek INT, @lastDayOfWeek INT;
        SELECT @firstDayOfWeek = DATEPART(DW, @FirstDay), @lastDayOfWeek = DATEPART(DW, @LastDay);

        IF @lastDayOfWeek < @firstDayOfWeek
                SELECT @lastDayOfWeek = @lastDayOfWeek + 7;

        IF @firstDayOfWeek <= 6 
            BEGIN
                IF (@lastDayOfWeek >= 7) --Both Saturday and Sunday are in the remaining time interval
                    BEGIN 
                        SELECT @BusinessDays = @BusinessDays - 2
                    END
                ELSE IF @lastDayOfWeek>=6 --Only Saturday is in the remaining time interval
                    BEGIN
                        SELECT @BusinessDays = @BusinessDays - 1
                    END

            END
        ELSE IF @firstDayOfWeek <= 7 AND @lastDayOfWeek >=7 -- Only Sunday is in the remaining time interval
        BEGIN 
            SELECT @BusinessDays = @BusinessDays - 1
        END
    END

    -- subtract the weekends during the full weeks in the interval
    DECLARE @Holidays INT;
    SELECT  @Holidays = COUNT(*) 
    FROM    Holiday 
    WHERE   HolidayDt BETWEEN @FirstDay AND @LastDay 
    AND     IsWeekday = CAST(1 AS BIT)

    SELECT @BusinessDays = @BusinessDays - (@FullWeekCount + @FullWeekCount) -- - @Holidays

    RETURN @BusinessDays
END

0
    int BusinessDayDifference(DateTime Date1, DateTime Date2)
    {
        int Sign = 1;
        if (Date2 > Date1)
        {
            Sign = -1;
            DateTime TempDate = Date1;
            Date1 = Date2;
            Date2 = TempDate;
        }
        int BusDayDiff = (int)(Date1.Date - Date2.Date).TotalDays;
        if (Date1.DayOfWeek == DayOfWeek.Saturday)
            BusDayDiff -= 1;
        if (Date2.DayOfWeek == DayOfWeek.Sunday)
            BusDayDiff -= 1;
        int Week1 = GetWeekNum(Date1);
        int Week2 = GetWeekNum(Date2);
        int WeekDiff = Week1 - Week2;
        BusDayDiff -= WeekDiff * 2;
        foreach (DateTime Holiday in Holidays)
            if (Date1 >= Holiday && Date2 <= Holiday)
                BusDayDiff--;
        BusDayDiff *= Sign;
        return BusDayDiff;
    }

    private int GetWeekNum(DateTime Date)
    {
        return (int)(Date.AddDays(-(int)Date.DayOfWeek).Ticks / TimeSpan.TicksPerDay / 7);
    }

0

यहाँ इस समस्या का एक बहुत ही सरल समाधान है। हम दिन को बढ़ाने के लिए तारीख, अंतिम तिथि और "लूप के लिए" शुरू करते हैं और यह देखने के लिए गणना करते हैं कि क्या यह एक कार्यदिवस या एक सप्ताह के अंत में स्ट्रिंग DayOfWeek में कनवर्ट करके है।

class Program
{
    static void Main(string[] args)
    {
        DateTime day = new DateTime();
        Console.Write("Inser your end date (example: 01/30/2015): ");
        DateTime endDate = DateTime.Parse(Console.ReadLine());
        int numberOfDays = 0;
        for (day = DateTime.Now.Date; day.Date < endDate.Date; day = day.Date.AddDays(1))
        {
            string dayToString = Convert.ToString(day.DayOfWeek);
            if (dayToString != "Saturday" && dayToString != "Sunday") numberOfDays++;
        }
        Console.WriteLine("Number of working days (not including local holidays) between two dates is "+numberOfDays);
    }
}

0

उत्तर और पैच के रूप में अनुशंसित टिप्पणी के आधार पर, साथ ही -> यह संस्करण डेज़ टू बिज़नेस-आवर्स में परिवर्तित करना चाहता है ... कंसाइडर्स उसी दिन घंटे भी।

 /// <summary>
    /// Calculates number of business days, taking into account:
    ///  - weekends (Saturdays and Sundays)
    ///  - bank holidays in the middle of the week
    /// </summary>
    /// <param name="firstDay">First day in the time interval</param>
    /// <param name="lastDay">Last day in the time interval</param>
    /// <param name="bankHolidays">List of bank holidays excluding weekends</param>
    /// <returns>Number of business hours during the 'span'</returns>
    public static int BusinessHoursUntil(DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays)
    {
        var original_firstDay = firstDay;
        var original_lastDay = lastDay;
        firstDay = firstDay.Date;
        lastDay = lastDay.Date;
        if (firstDay > lastDay)
            return -1; //// throw new ArgumentException("Incorrect last day " + lastDay);

        TimeSpan span = lastDay - firstDay;
        int businessDays = span.Days + 1;
        int fullWeekCount = businessDays / 7;
        // find out if there are weekends during the time exceedng the full weeks
        if (businessDays > fullWeekCount * 7)
        {
            // we are here to find out if there is a 1-day or 2-days weekend
            // in the time interval remaining after subtracting the complete weeks
            int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)firstDay.DayOfWeek;
            int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)lastDay.DayOfWeek;

            if (lastDayOfWeek < firstDayOfWeek)
                lastDayOfWeek += 7;
            if (firstDayOfWeek <= 6)
            {
                if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval
                    businessDays -= 2;
                else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval
                    businessDays -= 1;
            }
            else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval
                businessDays -= 1;
        }

        // subtract the weekends during the full weeks in the interval
        businessDays -= fullWeekCount + fullWeekCount;

        if (bankHolidays != null && bankHolidays.Any())
        {
            // subtract the number of bank holidays during the time interval
            foreach (DateTime bankHoliday in bankHolidays)
            {
                DateTime bh = bankHoliday.Date;
                if (firstDay <= bh && bh <= lastDay)
                    --businessDays;
            }
        }

        int total_business_hours = 0;
        if (firstDay.Date == lastDay.Date)
        {//If on the same day, go granular with Hours from the Orginial_*Day values
            total_business_hours = (int)(original_lastDay - original_firstDay).TotalHours;
        }
        else
        {//Convert Business-Days to TotalHours
            total_business_hours = (int)(firstDay.AddDays(businessDays).AddHours(firstDay.Hour) - firstDay).TotalHours;
        }
        return total_business_hours;
    }

0
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime start = new DateTime(2014, 1, 1);
            DateTime stop = new DateTime(2014, 12, 31);

            int totalWorkingDays = GetNumberOfWorkingDays(start, stop);

            Console.WriteLine("There are {0} working days.", totalWorkingDays);
        }

        private static int GetNumberOfWorkingDays(DateTime start, DateTime stop)
        {
            TimeSpan interval = stop - start;

            int totalWeek = interval.Days / 7;
            int totalWorkingDays = 5 * totalWeek;

            int remainingDays = interval.Days % 7;


            for (int i = 0; i <= remainingDays; i++)
            {
                DayOfWeek test = (DayOfWeek)(((int)start.DayOfWeek + i) % 7);
                if (test >= DayOfWeek.Monday && test <= DayOfWeek.Friday)
                    totalWorkingDays++;
            }

            return totalWorkingDays;
        }
    }
}

0

मैंने एक व्यवसायिक सप्ताह को एक पैरामीटर के रूप में समर्थन करने के लिए @Alexander और @Slauma उत्तर में सुधार किया है, उन मामलों के लिए जहां शनिवार का दिन एक व्यावसायिक दिन है, या यहां तक ​​कि ऐसे मामले भी हैं जहां सप्ताह के कुछ दिन हैं जिन्हें व्यावसायिक दिन माना जाता है:

/// <summary>
/// Calculate the number of business days between two dates, considering:
///  - Days of the week that are not considered business days.
///  - Holidays between these two dates.
/// </summary>
/// <param name="fDay">First day of the desired 'span'.</param>
/// <param name="lDay">Last day of the desired 'span'.</param>
/// <param name="BusinessDaysOfWeek">Days of the week that are considered to be business days, if NULL considers monday, tuesday, wednesday, thursday and friday as business days of the week.</param>
/// <param name="Holidays">Holidays, if NULL, considers no holiday.</param>
/// <returns>Number of business days during the 'span'</returns>
public static int BusinessDaysUntil(this DateTime fDay, DateTime lDay, DayOfWeek[] BusinessDaysOfWeek = null, DateTime[] Holidays = null)
{
    if (BusinessDaysOfWeek == null)
        BusinessDaysOfWeek = new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday };
    if (Holidays == null)
        Holidays = new DateTime[] { };

    fDay = fDay.Date;
    lDay = lDay.Date;

    if (fDay > lDay)
        throw new ArgumentException("Incorrect last day " + lDay);

    int bDays = (lDay - fDay).Days + 1;
    int fullWeekCount = bDays / 7;
    int fullWeekCountMult = 7 - WeekDays.Length;
    //  Find out if there are weekends during the time exceedng the full weeks
    if (bDays > (fullWeekCount * 7))
    {
        int fDayOfWeek = (int)fDay.DayOfWeek;
        int lDayOfWeek = (int)lDay.DayOfWeek;

        if (fDayOfWeek > lDayOfWeek)
            lDayOfWeek += 7;

        // If they are the same, we already covered it right before the Holiday subtraction
        if (lDayOfWeek != fDayOfWeek)
        {
            //  Here we need to see if any of the days between are considered business days
            for (int i = fDayOfWeek; i <= lDayOfWeek; i++)
                if (!WeekDays.Contains((DayOfWeek)(i > 6 ? i - 7 : i)))
                    bDays -= 1;
        }
    }

    //  Subtract the days that are not in WeekDays[] during the full weeks in the interval
    bDays -= (fullWeekCount * fullWeekCountMult);
    //  Subtract the number of bank holidays during the time interval
    bDays = bDays - Holidays.Select(x => x.Date).Count(x => fDay <= x && x <= lDay);

    return bDays;
}

0

यहां वह फ़ंक्शन है जो हम दो दिनों के बीच व्यावसायिक दिनों की गणना करने के लिए उपयोग कर सकते हैं। मैं अवकाश सूची का उपयोग नहीं कर रहा हूं क्योंकि यह देश / क्षेत्र को अलग-अलग कर सकता है।

अगर हम इसे वैसे भी उपयोग करना चाहते हैं तो हम तीसरे तर्क को छुट्टी की सूची के रूप में ले सकते हैं और गिनती बढ़ाने से पहले हमें यह जांचना चाहिए कि सूची में क्या नहीं है

public static int GetBussinessDaysBetweenTwoDates(DateTime StartDate,   DateTime EndDate)
    {
        if (StartDate > EndDate)
            return -1;

        int bd = 0;

        for (DateTime d = StartDate; d < EndDate; d = d.AddDays(1))
        {
            if (d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday)
                bd++;
        }

        return bd;
    }

0

मेरा मानना ​​है कि यह एक सरल तरीका हो सकता है:

    public int BusinessDaysUntil(DateTime start, DateTime end, params DateTime[] bankHolidays)
    {
        int tld = (int)((end - start).TotalDays) + 1; //including end day
        int not_buss_day = 2 * (tld / 7); //Saturday and Sunday
        int rest = tld % 7; //rest.

        if (rest > 0)
        {
            int tmp = (int)start.DayOfWeek - 1 + rest;
            if (tmp == 6 || start.DayOfWeek == DayOfWeek.Sunday) not_buss_day++; else if (tmp > 6) not_buss_day += 2;
        }

        foreach (DateTime bankHoliday in bankHolidays)
        {
            DateTime bh = bankHoliday.Date;
            if (!(bh.DayOfWeek == DayOfWeek.Saturday || bh.DayOfWeek == DayOfWeek.Sunday) && (start <= bh && bh <= end))
            {
                not_buss_day++;
            }
        }
        return tld - not_buss_day;
    }

0

यहां अभी तक एक और विचार है - यह विधि किसी भी कार्य सप्ताह और छुट्टियों को निर्दिष्ट करने की अनुमति देती है।

यहाँ विचार यह है कि हम सप्ताह के पहले पहले कार्य दिवस से लेकर सप्ताह के अंतिम सप्ताह के अंत तक की तारीख का मूल पाते हैं। यह हमें पूरे सप्ताह की आसानी से गणना करने में सक्षम बनाता है ( सभी तिथियों पर पुनरावृत्ति के बिना )। इसके बाद हमें बस इतना करना होगा कि इस कोर रेंज के शुरू होने और खत्म होने से पहले काम के दिनों को जोड़ा जाए।

public static int CalculateWorkingDays(
    DateTime startDate, 
    DateTime endDate, 
    IList<DateTime> holidays, 
    DayOfWeek firstDayOfWeek,
    DayOfWeek lastDayOfWeek)
{
    // Make sure the defined working days run contiguously
    if (lastDayOfWeek < firstDayOfWeek)
    {
        throw new Exception("Last day of week cannot fall before first day of week!");
    }

    // Create a list of the days of the week that make-up the weekend by working back
    // from the firstDayOfWeek and forward from lastDayOfWeek to get the start and end
    // the weekend
    var weekendStart = lastDayOfWeek == DayOfWeek.Saturday ? DayOfWeek.Sunday : lastDayOfWeek + 1;
    var weekendEnd = firstDayOfWeek == DayOfWeek.Sunday ? DayOfWeek.Saturday : firstDayOfWeek - 1;
    var weekendDays = new List<DayOfWeek>();

    var w = weekendStart;
    do {
        weekendDays.Add(w);
        if (w == weekendEnd) break;
        w = (w == DayOfWeek.Saturday) ? DayOfWeek.Sunday : w + 1;
    } while (true);


    // Force simple dates - no time
    startDate = startDate.Date;
    endDate = endDate.Date;

    // Ensure a progessive date range
    if (endDate < startDate)
    {
        var t = startDate;
        startDate = endDate;
        endDate = t;
    }

    // setup some working variables and constants
    const int daysInWeek = 7;           // yeah - really!
    var actualStartDate = startDate;    // this will end up on startOfWeek boundary
    var actualEndDate = endDate;        // this will end up on weekendEnd boundary
    int workingDaysInWeek = daysInWeek - weekendDays.Count;

    int workingDays = 0;        // the result we are trying to find
    int leadingDays = 0;        // the number of working days leading up to the firstDayOfWeek boundary
    int trailingDays = 0;       // the number of working days counting back to the weekendEnd boundary

    // Calculate leading working days
    // if we aren't on the firstDayOfWeek we need to step forward to the nearest
    if (startDate.DayOfWeek != firstDayOfWeek)
    {
        var d = startDate;
        do {
            if (d.DayOfWeek == firstDayOfWeek || d >= endDate)
            {
                actualStartDate = d;
                break;  
            }
            if (!weekendDays.Contains(d.DayOfWeek))
            {
                leadingDays++;
            }
            d = d.AddDays(1);
        } while(true);
    }

    // Calculate trailing working days
    // if we aren't on the weekendEnd we step back to the nearest
    if (endDate >= actualStartDate && endDate.DayOfWeek != weekendEnd)
    {
        var d = endDate;
        do {
            if (d.DayOfWeek == weekendEnd || d < actualStartDate)
            {
                actualEndDate = d;
                break;  
            }
            if (!weekendDays.Contains(d.DayOfWeek))
            {
                trailingDays++;
            }
            d = d.AddDays(-1);
        } while(true);
    }

    // Calculate the inclusive number of days between the actualStartDate and the actualEndDate
    var coreDays = (actualEndDate - actualStartDate).Days + 1;
    var noWeeks =  coreDays / daysInWeek;

    // add together leading, core and trailing days
    workingDays +=  noWeeks * workingDaysInWeek;
    workingDays += leadingDays;
    workingDays += trailingDays;

    // Finally remove any holidays that fall within the range.
    if (holidays != null)
    {
        workingDays -= holidays.Count(h => h >= startDate && (h <= endDate));
    }

    return workingDays;
}

0

चूंकि मैं टिप्पणी नहीं कर सकता। स्वीकृत समाधान के साथ एक और मुद्दा है जहां बैंक की छुट्टियां सप्ताहांत में स्थित होने पर भी घटा दी जाती हैं। यह देखते हुए कि कैसे अन्य इनपुट की जाँच की जाती है, यह केवल फिटिंग है कि यह भी है।

इसलिए, इस प्रकार होना चाहिए:

    // subtract the number of bank holidays during the time interval
    foreach (DateTime bankHoliday in bankHolidays)
    {
        DateTime bh = bankHoliday.Date;

        // Do not subtract bank holidays when they fall in the weekend to avoid double subtraction
        if (bh.DayOfWeek == DayOfWeek.Saturday || bh.DayOfWeek == DayOfWeek.Sunday)
                continue;

        if (firstDay <= bh && bh <= lastDay)
            --businessDays;
    }

0

यहां एक दृष्टिकोण है यदि आप एमवीसी का उपयोग कर रहे हैं। मैंने राष्ट्रीय छुट्टियों या किसी भी उत्सव के दिनों की गणना की है ताकि इसे छुट्टियों से बाहर लाने से रोका जा सके जिसे आपको एक बनाने की आवश्यकता होगी।

        foreach (DateTime day in EachDay(model))
        {
            bool key = false;
            foreach (LeaveModel ln in holidaycalendar)
            {
                if (day.Date == ln.Date && day.DayOfWeek != DayOfWeek.Saturday && day.DayOfWeek != DayOfWeek.Sunday)
                {
                    key = true; break;
                }
            }
            if (day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday)
            {
                key = true;
            }
            if (key != true)
            {
                leavecount++;
            }
        }

लीमोडेल यहां एक सूची है


0

यहाँ एक सहायक कार्य है जो मैंने उस कार्य के लिए लिखा था।
यह outपैरामीटर के माध्यम से सप्ताहांत की गिनती भी लौटाता है ।
यदि आप चाहें तो अलग-अलग सप्ताहांत दिनों का उपयोग करने वाले देशों के लिए "सप्ताहांत" दिनों को अनुकूलित कर सकते हैं या छुट्टियों को weekendDays[]वैकल्पिक पैरामीटर को शामिल कर सकते हैं :

public static int GetNetworkDays(DateTime startDate, DateTime endDate,out int totalWeekenDays, DayOfWeek[] weekendDays = null)
{
    if (startDate >= endDate)
    {
        throw new Exception("start date can not be greater then or equel to end date");
    }

    DayOfWeek[] weekends = new DayOfWeek[] { DayOfWeek.Sunday, DayOfWeek.Saturday };
    if (weekendDays != null)
    {
        weekends = weekendDays;
    }

    var totaldays = (endDate - startDate).TotalDays + 1; // add one to include the first day to
    var counter = 0;
    var workdaysCounter = 0;
    var weekendsCounter = 0;

    for (int i = 0; i < totaldays; i++)
    {

        if (weekends.Contains(startDate.AddDays(counter).DayOfWeek))
        {
            weekendsCounter++;
        }
        else
        {
            workdaysCounter++;
        }

        counter++;
    }

    totalWeekenDays = weekendsCounter;
    return workdaysCounter;
}

0

मैं निम्नलिखित समाधान के साथ आया था

var dateStart = new DateTime(2019,01,10);
var dateEnd = new DateTime(2019,01,31);

var timeBetween = (dateEnd - dateStart).TotalDays + 1;
int numberOf7DayWeeks = (int)(timeBetween / 7);
int numberOfWeekendDays = numberOf7DayWeeks * 2;
int workingDays =(int)( timeBetween - numberOfWeekendDays);

if(dateStart.DayOfWeek == DayOfWeek.Saturday || dateEnd.DayOfWeek == DayOfWeek.Sunday){
    workingDays -=2;
}       
if(dateStart.DayOfWeek == DayOfWeek.Sunday || dateEnd.DayOfWeek == DayOfWeek.Saturday){
    workingDays -=1;
}

0

आपको बस समय सीमा में प्रत्येक दिन के माध्यम से पुनरावृत्त करना होगा और काउंटर से एक दिन घटाना होगा अगर इसका शनिवार या रविवार हो।

    private float SubtractWeekend(DateTime start, DateTime end) {
        float totaldays = (end.Date - start.Date).Days;
        var iterationVal = totalDays;
        for (int i = 0; i <= iterationVal; i++) {
            int dayVal = (int)start.Date.AddDays(i).DayOfWeek;
            if(dayVal == 6 || dayVal == 0) {
                // saturday or sunday
                totalDays--;
            }
        }
        return totalDays;
    }

0
public static int CalculateBusinessDaysInRange(this DateTime startDate, DateTime endDate, params DateTime[] holidayDates)
{
    endDate = endDate.Date;
    if(startDate > endDate)
        throw new ArgumentException("The end date can not be before the start date!", nameof(endDate));
    int accumulator = 0;
    DateTime itterator = startDate.Date;
    do 
    {
        if(itterator.DayOfWeek != DayOfWeek.Saturday && itterator.DayOfWeek != DayOfWeek.Sunday && !holidayDates.Any(hol => hol.Date == itterator))
        { accumulator++; }
    } 
    while((itterator = itterator.AddDays(1)).Date <= endDate);
    return accumulator
}

मैं केवल यह पोस्ट कर रहा हूं क्योंकि सभी उत्कृष्ट उत्तरों के बावजूद, गणित में से कोई भी मेरे लिए समझ में नहीं आया। यह निश्चित रूप से एक KISS विधि है कि काम करते हैं और काफी पोषणीय होना चाहिए। यदि आप 2-3 महीने से अधिक की सीमा की गणना कर रहे हैं तो यह सबसे प्रभावी तरीका नहीं होगा। हम बस यह निर्धारित करते हैं कि यह शनिवार या रविवार है या तारीख किसी छुट्टी की तारीख है। यदि यह नहीं है, तो हम एक व्यावसायिक दिन जोड़ते हैं। अगर है तो सब ठीक है।

मुझे यकीन है कि यह LINQ के साथ और भी सरल हो सकता है, लेकिन इस तरह से समझना बहुत आसान है।


0

व्यावसायिक दिनों की गणना के लिए एक और दृष्टिकोण, छुट्टियों पर विचार नहीं करना, लेकिन दिन के समय को ध्यान में रखते हुए दिन की एक आंशिक राशि लौटाना:

public static double GetBusinessDays(DateTime startD, DateTime endD)
{
    while (IsWeekend(startD))
        startD = startD.Date.AddDays(1);

    while (IsWeekend(endD))
        endD = endD.Date.AddDays(-1);

    var bussDays = (endD - startD).TotalDays -
        (2 * ((int)(endD - startD).TotalDays / 7)) -
        (startD.DayOfWeek > endD.DayOfWeek ? 2 : 0);

    return bussDays;
}

public static bool IsWeekend(DateTime d)
{
    return d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday;
}

आप इसे यहां देख सकते हैं: https://rextester.com/ASHRS53997


-1

यह एक सामान्य समाधान है।

startdayvalue प्रारंभ दिनांक की दिन संख्या है।

सप्ताहांत का दिन सप्ताह के अंत का दिन अंक है।

दिन संख्या - MON - 1, TUE - 2, ... SAT - 6, SUN -7।

अंतर दो तिथियों के बीच अंतर है ।।

उदाहरण: प्रारंभ तिथि: 4 अप्रैल, 2013, अंतिम तिथि: 14 अप्रैल, 2013

अंतर: १०, दिन का आरंभ: ४, सप्ताहांत का दिन: is: (अगर सूरते आपके लिए सप्ताहांत है।)

यह आपको छुट्टियों की संख्या देगा।

कार्य दिवस नहीं = (अंतर + 1) - Holiday1

    if (startdayvalue > weekendday_1)
    {

        if (difference > ((7 - startdayvalue) + weekendday_1))
        {
            holiday1 = (difference - ((7 - startdayvalue) + weekendday_1)) / 7;
            holiday1 = holiday1 + 1;
        }
        else
        {
            holiday1 = 0;
        }
    }
    else if (startdayvalue < weekendday_1)
    {

        if (difference > (weekendday_1 - startdayvalue))
        {
            holiday1 = (difference - (weekendday_1 - startdayvalue)) / 7;
            holiday1 = holiday1 + 1;
        }
        else if (difference == (weekendday_1 - startdayvalue))
        {
            holiday1 = 1;
        }
        else
        {
            holiday1 = 0;
        }
    }
    else
    {
        holiday1 = difference / 7;
        holiday1 = holiday1 + 1;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.