सवाल AddBusinessDays और GetBusinessDays जोड़ें


मुझे 2 सुरुचिपूर्ण पूर्ण कार्यान्वयन की आवश्यकता है

public static DateTime AddBusinessDays(this DateTime date, int days)
{
 // code here
}

and 

public static int GetBusinessDays(this DateTime start, DateTime end)
{
 // code here
}

ओ (1) बेहतर (कोई लूप नहीं)।

संपादित करें:  व्यावसायिक दिनों से मेरा मतलब है कार्य दिवस (सोमवार, मंगलवार, बुधवार, गुरुवार, शुक्रवार)। कोई छुट्टियां नहीं, केवल सप्ताहांत बाहर रखा गया।

मेरे पास पहले से ही कुछ बदसूरत समाधान हैं जो काम करने लगते हैं लेकिन मुझे आश्चर्य है कि ऐसा करने के शानदार तरीके हैं। धन्यवाद


यह वही है जो मैंने अभी तक लिखा है। यह सभी मामलों में काम करता है और नकारात्मक भी करता है। अभी भी GetBusinessDays कार्यान्वयन की आवश्यकता है

public static DateTime AddBusinessDays(this DateTime startDate,
                                         int businessDays)
{
    int direction = Math.Sign(businessDays);
    if(direction == 1)
    {
        if(startDate.DayOfWeek == DayOfWeek.Saturday)
        {
            startDate = startDate.AddDays(2);
            businessDays = businessDays - 1;
        }
        else if(startDate.DayOfWeek == DayOfWeek.Sunday)
        {
            startDate = startDate.AddDays(1);
            businessDays = businessDays - 1;
        }
    }
    else
    {
        if(startDate.DayOfWeek == DayOfWeek.Saturday)
        {
            startDate = startDate.AddDays(-1);
            businessDays = businessDays + 1;
        }
        else if(startDate.DayOfWeek == DayOfWeek.Sunday)
        {
            startDate = startDate.AddDays(-2);
            businessDays = businessDays + 1;
        }
    }

    int initialDayOfWeek = (int)startDate.DayOfWeek;

    int weeksBase = Math.Abs(businessDays / 5);
    int addDays = Math.Abs(businessDays % 5);

    if((direction == 1 && addDays + initialDayOfWeek > 5) ||
         (direction == -1 && addDays >= initialDayOfWeek))
    {
        addDays += 2;
    }

    int totalDays = (weeksBase * 7) + addDays;
    return startDate.AddDays(totalDays * direction);
}

76
2018-06-25 15:48


मूल


क्या तारीखों के रूप में अजीब कुछ के रूप में कुछ सुरुचिपूर्ण समाधान हैं? - Wyatt Barnett
Donno। इसीलिए मैंने पूछा। - Adrian Zanescu
क्या आप छुट्टियों से सहमत हैं? - James Conigliaro
क्या आप छुट्टियों से सहमत हैं? - जेम्स Conigliaro। नहीं - Adrian Zanescu
मदद करने की कोशिश कर रहे लोगों को वोट देना एक जीतने की रणनीति नहीं है। - Jamie Ide


जवाब:


आपके पहले फ़ंक्शन के लिए नवीनतम प्रयास:

public static DateTime AddBusinessDays(DateTime date, int days)
{
    if (days < 0)
    {
        throw new ArgumentException("days cannot be negative", "days");
    }

    if (days == 0) return date;

    if (date.DayOfWeek == DayOfWeek.Saturday)
    {
        date = date.AddDays(2);
        days -= 1;
    }
    else if (date.DayOfWeek == DayOfWeek.Sunday)
    {
        date = date.AddDays(1);
        days -= 1;
    }

    date = date.AddDays(days / 5 * 7);
    int extraDays = days % 5;

    if ((int)date.DayOfWeek + extraDays > 5)
    {
        extraDays += 2;
    }

    return date.AddDays(extraDays);

}

दूसरा कार्य, GetBusinessDays, निम्नानुसार कार्यान्वित किया जा सकता है:

public static int GetBusinessDays(DateTime start, DateTime end)
{
    if (start.DayOfWeek == DayOfWeek.Saturday)
    {
        start = start.AddDays(2);
    }
    else if (start.DayOfWeek == DayOfWeek.Sunday)
    {
        start = start.AddDays(1);
    }

    if (end.DayOfWeek == DayOfWeek.Saturday)
    {
        end = end.AddDays(-1);
    }
    else if (end.DayOfWeek == DayOfWeek.Sunday)
    {
        end = end.AddDays(-2);
    }

    int diff = (int)end.Subtract(start).TotalDays;

    int result = diff / 7 * 5 + diff % 7;

    if (end.DayOfWeek < start.DayOfWeek)
    {
        return result - 2;
    }
    else{
        return result;
    }
}

118
2018-06-25 16:14



दूसरे के लिए, एक समाधान दिनांक और तारीख + दिनों के बीच अंतर लेना है। यह अच्छा है कि यह गारंटी देता है कि दो कार्य ठीक से सिंक हो जाएंगे, और यह अनावश्यकता को हटा देगा। - Brian
@ पैट्रिक: अब तय किया जाना चाहिए - आशा है कि आपको संपादन पर ध्यान नहीं दिया जाएगा। (अगर मैंने कुछ मूर्खतापूर्ण किया है तो बस रोलबैक।) - Noldorin
हाँ, हम अंत में वहां पहुंचे। (मैं अपने छोटे योगदान के लिए 'हम' कहता हूं!) प्रयास के लिए वोट दिया गया। - Noldorin
मतदान किया हुआ। मुझे कुछ कोड-टिप्पणियां पसंद आएगी ताकि मुझे इसके माध्यम से जाने में मदद मिल सके। - PeterX
डेटटाइम। एडडेज नकारात्मक संख्याओं के साथ काम करता है। यह सही पैटर्न का सही ढंग से पालन नहीं करता है क्योंकि AddBusinessDays के साथ नकारात्मक संख्याओं का उपयोग करने से गैर-व्यावसायिक दिनों का चयन किया जा सकता है। - Ristogod


का उपयोग करते हुए फ्लुएंट डेटटाइम:

var now = DateTime.Now;
var dateTime1 = now.AddBusinessDays(3);
var dateTime2 = now.SubtractBusinessDays(5);

निम्नानुसार आंतरिक कोड है

    /// <summary>
    /// Adds the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be added.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime AddBusinessDays(this DateTime current, int days)
    {
        var sign = Math.Sign(days);
        var unsignedDays = Math.Abs(days);
        for (var i = 0; i < unsignedDays; i++)
        {
            do
            {
                current = current.AddDays(sign);
            }
            while (current.DayOfWeek == DayOfWeek.Saturday ||
                current.DayOfWeek == DayOfWeek.Sunday);
        }
        return current;
    }

    /// <summary>
    /// Subtracts the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be subtracted.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime SubtractBusinessDays(this DateTime current, int days)
    {
        return AddBusinessDays(current, -days);
    }

56
2017-09-04 13:12



यह एकमात्र समाधान है जो वास्तव में मेरे लिए काम करता है जब VB.Net में परिवर्तित किया जाता है - Nicholas Head
ओपी ने कोई लूप का अनुरोध नहीं किया, जबकि यह स्पष्ट रूप से लूप है। कम से कम कुशल तरीके से कुछ करने के बारे में कुछ भी सुरुचिपूर्ण नहीं है। - Neolisk


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

namespace Extensions.DateTime
{
    public static class BusinessDays
    {
        public static System.DateTime AddBusinessDays(this System.DateTime source, int businessDays)
        {
            var dayOfWeek = businessDays < 0
                                ? ((int)source.DayOfWeek - 12) % 7
                                : ((int)source.DayOfWeek + 6) % 7;

            switch (dayOfWeek)
            {
                case 6:
                    businessDays--;
                    break;
                case -6:
                    businessDays++;
                    break;
            }

            return source.AddDays(businessDays + ((businessDays + dayOfWeek) / 5) * 2);
        }
    }
}

उदाहरण:

using System;
using System.Windows.Forms;
using Extensions.DateTime;

namespace AddBusinessDaysTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label1.Text = DateTime.Now.AddBusinessDays(5).ToString();
            label2.Text = DateTime.Now.AddBusinessDays(-36).ToString();
        }
    }
}

11
2017-08-06 12:55



परिणाम स्रोत संदिग्ध है अगर स्रोत शनिवार या रविवार है। उदाहरण के लिए: शनिवार + 1 व्यावसायिक दिन मंगलवार में परिणाम, जहां मैं सोमवार की अपेक्षा करता हूं। - Slauma
@ स्लुमा: कनाडा में अधिकांश व्यवसाय संचालित होते हैं। +1 बिजनेस डे = "अगला बिजनेस डे", जो शनिवार मंगलवार के मामले में है। सोमवार "एक ही व्यापार दिवस" ​​होगा। - Neolisk
@ स्लुमा प्रोग्राम इरादे के रूप में काम करता है। इसके बारे में तर्कसंगत सोचें। अगर शनिवार को कुछ व्यवसाय संबंधित हो जाता है, और आपको व्यवसाय के दिन के दौरान लोगों के प्रति प्रतिक्रिया करने के लिए 1 व्यावसायिक दिन की अनुमति देनी होगी, तो क्या उन्हें यह बताना होगा कि इसे सोमवार तक किया जाना चाहिए ?! - Heliac


मेरे लिए मुझे एक समाधान होना था जो सप्ताहांत छोड़ देगा और नकारात्मक या सकारात्मक में जाएगा। मेरा मानदंड था कि अगर यह आगे बढ़े और सप्ताहांत में उतरे तो उसे सोमवार को आगे बढ़ने की आवश्यकता होगी। अगर यह वापस जा रहा था और सप्ताहांत में उतरा तो उसे शुक्रवार को कूदना होगा।

उदाहरण के लिए:

  • बुधवार - 3 व्यावसायिक दिन = पिछले शुक्रवार
  • बुधवार + 3 व्यावसायिक दिन = सोमवार
  • शुक्रवार - 7 व्यावसायिक दिन = पिछले बुधवार
  • मंगलवार - 5 व्यावसायिक दिन = पिछले मंगलवार

खैर, आप विचार समझ गए ;)

मैंने इस विस्तार वर्ग को लिखना समाप्त कर दिया

public static partial class MyExtensions
{
    public static DateTime AddBusinessDays(this DateTime date, int addDays)
    {
        while (addDays != 0)
        {
            date = date.AddDays(Math.Sign(addDays));
            if (MyClass.IsBusinessDay(date))
            {
                addDays = addDays - Math.Sign(addDays);
            }
        }
        return date;
    }
}

यह इस विधि का उपयोग करता है जिसे मैंने सोचा था कि कहीं और उपयोग करने के लिए उपयोगी होगा ...

public class MyClass
{
    public static bool IsBusinessDay(DateTime date)
    {
        switch (date.DayOfWeek)
        {
            case DayOfWeek.Monday:
            case DayOfWeek.Tuesday:
            case DayOfWeek.Wednesday:
            case DayOfWeek.Thursday:
            case DayOfWeek.Friday:
                return true;
            default:
                return false;
        }
    }
}

यदि आप इससे परेशान नहीं होना चाहते हैं तो आप बस प्रतिस्थापित कर सकते हैं if (MyClass.IsBusinessDay(date)) अगर के साथ if ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))

तो अब आप कर सकते हैं

var myDate = DateTime.Now.AddBusinessDays(-3);

या

var myDate = DateTime.Now.AddBusinessDays(5);

कुछ परीक्षणों के परिणाम यहां दिए गए हैं:

परीक्षण अपेक्षित परिणाम
बुधवार -4 व्यावसायिक दिन गुरुवार गुरुवार
बुधवार -3 शुक्रवार शुक्रवार शुक्रवार
बुधवार +3 व्यावसायिक दिन सोमवार सोमवार
शुक्रवार -7 व्यावसायिक दिन बुधवार बुधवार
मंगलवार -5 मंगलवार मंगलवार मंगलवार
शुक्रवार +1 बिजनेस दिन सोमवार सोमवार
शनिवार +1 बिजनेस दिन सोमवार सोमवार
रविवार -1 व्यापार दिवस शुक्रवार शुक्रवार
सोमवार -1 व्यावसायिक दिन शुक्रवार शुक्रवार
सोमवार +1 बिजनेस दिन मंगलवार मंगलवार
सोमवार सोमवार सोमवार +0 व्यावसायिक दिन सोमवार सोमवार

6
2017-09-17 15:27



अच्छा काम! यह लिखने के लिए धन्यवाद। - Jean-Paul


अंतर्राष्ट्रीयकरण के साथ, यह मुश्किल है। जैसा कि एसओएफ पर अन्य धागे में उल्लिखित है, छुट्टियां देश से देश और यहां तक ​​कि प्रांत से प्रांत तक भिन्न होती हैं। ज्यादातर सरकारें अपनी छुट्टियों को पांच साल से अधिक समय तक निर्धारित नहीं करती हैं।


2
2018-06-25 16:04



मैं समझ नहीं पा रहा हूं कि किसी ने एश को क्यों कम किया: यह सच है कि यह पूछा गया कि इसका जवाब क्या नहीं है, लेकिन ऐश पूरी तरह से सही है, मेरे पास एक ही समस्या है: मेरे सॉफ़्टवेयर को यूरोप (सोम-सूर्य) और अफ्रीका / एशिया (शनि-शुक्र)। इसे कम करने के लिए, किसी को गधे होना चाहिए (जानवर, बस मामले में) जो उसकी नाक से परे नहीं देख सकता है: ऐसा लगता है कि ऐसे लोग हैं जो ज्ञान से डरते हैं, बस जानना और पसंद नहीं करना चाहते उनकी आश्वस्त अज्ञानता पर बने रहने के लिए: लेकिन वे पहले स्थान पर एजेड की सेवा नहीं करते हैं (और स्वयं भी, लेकिन यह उनका स्वयं का व्यवसाय है) - M.Turrini
मैं (ओपी) डाउनवॉटेड क्योंकि मैंने सोचा कि मैंने इस सवाल में स्पष्ट किया है कि बाधाएं क्या हैं और ऐसा लगता है कि ऐश ने ध्यान नहीं दिया है। मैं क्षमा चाहता हूं अगर इससे किसी को महसूस होता है लेकिन सिर्फ एक डाउनवोट है - Adrian Zanescu
@ एजेड: मूल प्रश्न में आपने अंतर्राष्ट्रीयकरण की बाधाओं का जिक्र किया था? - Ash Machine
@AshMachine, बिल्कुल। उसने नहीं किया - jwg
छुट्टियां देश से देश में भिन्न होती हैं, लेकिन इस प्रश्न के पास छुट्टियों से कोई लेना देना नहीं है। इसे सप्ताहांत के साथ करना है, जो समस्या विवरण में स्पष्ट रूप से बताया गया है। यह एक टिप्पणी होनी चाहिए थी। - Neolisk


public static DateTime AddBusinessDays(this DateTime date, int days)
{
    date = date.AddDays((days / 5) * 7);

    int remainder = days % 5;

    switch (date.DayOfWeek)
    {
        case DayOfWeek.Tuesday:
            if (remainder > 3) date = date.AddDays(2);
            break;
        case DayOfWeek.Wednesday:
            if (remainder > 2) date = date.AddDays(2);
            break;
        case DayOfWeek.Thursday:
            if (remainder > 1) date = date.AddDays(2);
            break;
        case DayOfWeek.Friday:
            if (remainder > 0) date = date.AddDays(2);
            break;
        case DayOfWeek.Saturday:
            if (days > 0) date = date.AddDays((remainder == 0) ? 2 : 1);
            break;
        case DayOfWeek.Sunday:
            if (days > 0) date = date.AddDays((remainder == 0) ? 1 : 0);
            break;
        default:  // monday
            break;
    }

    return date.AddDays(remainder);
}

1
2018-06-25 16:42





मैं जवाब के लिए देर से आ रहा हूं, लेकिन मैंने कामकाजी दिनों पर सरल संचालन करने के लिए आवश्यक सभी अनुकूलन के साथ एक छोटी पुस्तकालय बनाई है ... मैं इसे यहां छोड़ देता हूं: कार्य दिवस प्रबंधन


1
2018-04-08 13:56



दुर्भाग्यवश यह जीएनयू लाइसेंस प्राप्त है इसलिए किसी वाणिज्यिक ऐप के लिए "कानूनी जहर" है। कोई भी मौका आप इसे "एमआईटी" या "अपाचे" में आराम करेंगे? - Tony O'Hagan
कुछ स्थैतिक सूचियां शायद सरणी होनी चाहिए (लिंक्ड सूचियों की बजाय)। - Tony O'Hagan
मैंने अभी एमआईटी को लाइसेंस बदल दिया है (मैं उस चीज़ पर कुछ भी अवरुद्ध नहीं करना चाहता हूं)। मैं आपके अन्य प्रस्ताव को देखूंगा। - Boneless
अच्छा, देश द्वारा कार्य दिवस प्रबंधन देखना दिलचस्प होगा क्योंकि कुछ देशों में सोमवार से शुक्रवार तक अन्य कार्य दिवस हो सकते हैं। - serializer