2009-03-08 11 views

उत्तर

12

एक आसान एक लाइनर नहीं खोजा जा सका लेकिन इस एक काम करता है:

static DateTime LastDayOfWeekInMonth(DateTime day, DayOfWeek dow) 
{ 
    DateTime lastDay = new DateTime(day.Year, day.Month, 1).AddMonths(1).AddDays(-1); 
    DayOfWeek lastDow = lastDay.DayOfWeek; 

    int diff = dow - lastDow; 

    if (diff > 0) diff -= 7; 

    System.Diagnostics.Debug.Assert(diff <= 0); 

    return lastDay.AddDays(diff); 
} 
+0

इसे पसंद है, धन्यवाद हेनक। मामूली बिंदु - आप अंतिम को हटा सकते हैं। एडडेज़ (-1) और "अगर (diff> 0)" को "if (diff> = 0)" में बदलें - इस प्रकार 1 डेटाटाइम को हटा दें। मैडडे ऑपरेशन। – Ryan

+1

रयान, हाँ, यह 1 सेशन बचाता है लेकिन यह संकलक अनुकूलित कर सकता है कि यह किस सीमा पर है। और अवधारणात्मक रूप से "महीने का अंतिम दिन" अगले महीने के पहले दिन "दिमाग पर आसान है"। तो मैं सामान्य रूप से इसे अनुकूलित नहीं करता। –

6

अगले महीने में पहला दिन प्राप्त करें, फिर उस महीने के पहले गणित सप्ताहांत को ढूंढें। सात दिन वापस जाएं और आप corrent महीने के अंतिम सप्ताह में है कि काम करने के दिन पर कर रहे हैं:

DateTime date = new DateTime(2009, 3, 12); 
DayOfWeek day = DayOfWeek.Sunday; 

DateTime nextMonth = new DateTime(date.Year, date.Month, 1).AddMonths(1); 
while (nextMonth.DayOfWeek != day) { 
    nextMonth = nextMonth.AddDays(1); 
} 
DateTime lastInMonth = nextMonth.AddDays(-7); 

(आप कुछ गणित है कि के संख्यात्मक मान के आधार पर जोड़ने के लिए दिनों की गणना के साथ पाश बदल सकते DayOfWeek मान, लेकिन यह अधिक सीधे आगे है।)

संपादित करें:
आप निश्चित रूप से वर्तमान माह में अंतिम दिन भी प्राप्त कर सकते हैं, फिर जब तक आपको सही सप्ताह का दिन न मिल जाए तब तक पीछे की ओर लूप करें।

+0

@ गुफा, इसे पकड़ने के लिए धन्यवाद। मैं बस जवाब देने वाला पहला व्यक्ति बनने की कोशिश कर रहा था इसलिए मेरा तर्क था! अच्छा। –

11

http://datetimeextensions.codeplex.com/ एक अंतिम (सप्ताह का दिन) विस्तार विधि उसके लिए आपको

टेस्ट शामिल :-)

यह कर देगा है
+0

चालाक कार्यान्वयन, और एक विस्तार मीठा होगा। मैं इसे कुछ विशिष्ट मोरों के लिए नाम बदल दूंगा। यह तिथि हो सकती है। LastDayOfWeekForMonth Date.LastDayOfWeekForYear या Date.LastDayOfWeekCentury Date.LastDayOfWeekForMillenium –

+0

ग्रेट लाइब्रेरी, धन्यवाद टीएफडी! दुर्भाग्य से मैं इसका उपयोग इस प्रकार नहीं कर सकता क्योंकि मैं .NET 2.0 को लक्षित कर रहा हूं इसलिए मैंने हेनक्स के जवाब को चिह्नित किया है, लेकिन इसके लिए आपको बहुत सारे अपवॉट मिल गए हैं। – Ryan

+0

परीक्षण विफल हुआ, डेटटाइम डीटी = डेटटाइम। आज। AddMonths (1) .स्ट (DayOfWeek.Tursday); Assert.AreEqual (नया दिनांक समय (2012, 4, 26), डीटी); – Vincent

1

इस प्रयास करें: अंतिम दिन में शुरू करने और वापस गिनती जब तक आप दिन आप के लिए

static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow) 
    { 
     DateTime looperDate = new DateTime(dt.Year, dt.Month, 1) 
            .AddMonths(1).AddDays(-1); 
     while (looperDate.DayOfWeek!=dow)        
      looperDate =looperDate.AddDays(-1);    
     return looperDate; 
देख रहे हैं हिट

संपादित करें: पुराने संस्करण को पुनर्प्राप्त किया गया डेंग टिप्पणी में प्रतिक्रिया दे रहा है।

static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow) 
    { 
     //set start of loop 
     DateTime looperDate = new DateTime(dt.Year, dt.Month, 1); 
     //initialze return value 
     DateTime returnDate = dt; 
     //loop until the month is over 
     while (looperDate.Month == dt.Month) 
     { 
      //if the current DayOfWeek is the date you're looking for 
      if (looperDate.DayOfWeek == dow) 
       //remember it. 
       returnDate = looperDate; 
      //increase day 
      looperDate=looperDate.AddDays(1); 
     } 
     return returnDate; 
    } 
+0

यह आपकी सरलता की परिभाषा है? –

+0

हाँ, यदि आपके पास एक बेहतर विचार है, तो आपका जवाब कहां है? – Sorskoot

+0

मुझे आपका पहला संस्करण पसंद आया। इस बारे में सोचना मुश्किल है।और मुझे बहुत संदेह है कि जब तक आप इन गणनाओं में से एक गैजिलियन नहीं कर रहे थे तब तक इसका कोई पता लगाने योग्य प्रदर्शन लाभ हो सकता था। मैं पुराने संस्करण में सुझाव देने जा रहा था कि आप इसे आसान बनाने के लिए एक समय में केवल 7 दिन जोड़ सकते हैं। –

4
static DateTime LastDateOfWeekForMonth(DayOfWeek weekday, int month, int year) 
{ 
    DateTime d = new DateTime(year, month, 1).AddMonths(1); 
    while (!(d.DayOfWeek == weekday && d.Month == month)) 
    { 
     d = d.AddDays(-1); 
    } 
    return d; 
} 
+0

इस पर डाउनवोट क्यों? मैंने रखा "!" में! –

+0

मुझे लगता है कि डाउनवोट अनुमान है क्योंकि इस तरह के किसी चीज़ के लिए लूप का उपयोग इष्टतम होने की संभावना नहीं है - लेकिन कम से कम आप महीने के अंत से शुरू कर रहे हैं और अधिकतम 6 पुनरावृत्तियों के पीछे काम कर रहे हैं। – Ryan

+0

ऑप्टिमाइज़ करने के लिए, अगर dayofweek> wednesday, इसे @ गुफा का तरीका करें, अन्यथा, मेरा :) –

1
public DateTime GetLastDayOfMonth(int year, int month, DayOfWeek dayOfWeek) 
    { 
     var daysInMonth = DateTime.DaysInMonth(year, month); 
     var lastDay = new DateTime(year, month, daysInMonth); 

     while (lastDay.DayOfWeek != dayOfWeek) 
     { 
      lastDay = lastDay.AddDays(-1); 
     } 

     return lastDay; 
    } 
0
static DateTime GetDayOfWeekInMonthFromWeekIndex(this DateTime date, DayOfWeek dow, int weekIndex) 
{ 
    if (weekIndex > 4) 
     return LastDayOfWeekInMonth(date, dow); 

    DateTime newDate = new DateTime(date.Year, date.Month, 1); 
    DayOfWeek newDow = newDate.DayOfWeek; 
    int diff = dow - newDow; 
    diff += ((weekIndex - 1) * 7); 
    return newDate.AddDays(diff); 
} 
1

यहाँ दोनों LastDayOfMonth() और LastDayOfMonth (सप्ताह का दिन) के साथ साथ इकाई परीक्षण है, जो @Paul फ्रायर द्वारा How to find the 3rd Friday in a month with C#? में "पिछले शुक्रवार" कार्यान्वयन से प्रेरित थे है:

/** 
    /// <summary>An extension method that returns the last day of the month.</summary> 
    /// <param name="d">A date within the month to calculate.</param> 
    /// <returns>The last day of the current month.</returns> 
    **/ 
    public static DateTime LastDayOfMonth(this DateTime d) 
    { 
     DateTime nextMonth = new DateTime(d.Year, d.Month, 1).AddMonths(1); 
     return nextMonth.AddDays(-1); 
    } 

    /** 
    /// <summary>An extension method that returns the last <see cref="DayOfWeek"> of the month.</summary> 
    /// <param name="d">A date within the month to calculate.</param> 
    /// <returns>The last day of the current month.</returns> 
    **/ 
    public static DateTime LastDayOfMonth(this DateTime d, DayOfWeek dayOfWeek) 
    { 
     DateTime lastDayOfMonth = d.LastDayOfMonth(); 
     int vector = (((int)lastDayOfMonth.DayOfWeek - (int)dayOfWeek + DaysInWeek) % DaysInWeek); 
     return lastDayOfMonth.AddDays(-vector); 
    } 

#region LastDayOfMonth Tests 

    [TestCase("1/1/2011", "1/31/2011")] 
    [TestCase("2/1/2009", "2/28/2009")] //Leap Year 
    [TestCase("2/1/2008", "2/29/2008")] //Leap Year 
    [TestCase("3/10/2011", "3/31/2011")] 
    [TestCase("4/20/2011", "4/30/2011")] 
    [TestCase("5/15/2011", "5/31/2011")] 
    [TestCase("6/30/2011", "6/30/2011")] 
    [TestCase("12/1/2011", "12/31/2011")] 
    public void LastDayOfMonthReturnsCorrectDay(string startingDate, string expectedDate) 
    { 
     //Arrange 
     DateTime testDate = DateTime.Parse(startingDate); 
     DateTime expected = DateTime.Parse(expectedDate); 

     //Act 
     DateTime actual = testDate.LastDayOfMonth(); 

     //Assert 
     Assert.That(actual, Is.EqualTo(expected)); 
    } 

    [TestCase("1/1/2011", DayOfWeek.Monday, "1/31/2011")] 
    [TestCase("2/1/2009", DayOfWeek.Saturday, "2/28/2009")] 
    [TestCase("2/1/2009", DayOfWeek.Sunday, "2/22/2009")] 
    [TestCase("2/1/2008", DayOfWeek.Friday, "2/29/2008")] //Leap Year 
    [TestCase("2/1/2008", DayOfWeek.Thursday, "2/28/2008")] //Leap Year 
    [TestCase("3/10/2011", DayOfWeek.Wednesday, "3/30/2011")] 
    [TestCase("4/20/2011", DayOfWeek.Friday, "4/29/2011")] 
    [TestCase("4/20/2011", DayOfWeek.Saturday, "4/30/2011")] 
    [TestCase("5/15/2011", DayOfWeek.Tuesday, "5/31/2011")] 
    [TestCase("5/15/2011", DayOfWeek.Saturday, "5/28/2011")] 
    [TestCase("9/30/2011", DayOfWeek.Sunday, "9/25/2011")] 
    [TestCase("12/1/2011", DayOfWeek.Monday, "12/26/2011")] 
    public void LastDayOfMonthReturnsCorrectDayOfWeek(string startingDate, DayOfWeek dayOfWeek, string expectedDate) 
    { 
     //Arrange 
     DateTime testDate = DateTime.Parse(startingDate); 
     DateTime expected = DateTime.Parse(expectedDate); 

     //Act 
     DateTime actual = testDate.LastDayOfMonth(dayOfWeek); 

     //Assert 
     Assert.That(actual, Is.EqualTo(expected)); 
    }  

    #endregion 
संबंधित मुद्दे