2010-06-17 13 views
12

जोड़ने DateTime.AddMonths मान लें, मैं फरवरी 2010 की 28 है और इस तिथि के लिए एक महीने जोड़ने AddMonths(1) ...
का उपयोग कर परिणामस्वरूप तारीख मार्च 28, लेकिन नहीं 31 है मार्च, जो मैं चाहता हूं।
क्या थोड़ा सा ट्विक करने का कोई तरीका है, इसलिए यह कस्टम कोड जोड़ने के बिना काम करता है?
केवल नहीं महीने दिनों

संपादित करें: मुझे एक महीने के आखिरी दिन की आवश्यकता नहीं है, वास्तव में मुझे एक महीने जोड़ने की जरूरत है, लेकिन जब एक महीने का आखिरी दिन, मुझे अगले महीने का अंतिम दिन ढूंढना होगा।

+2

किसी भी सवाल का जवाब अपनी आवश्यकताओं को पूरा करती है "टिक" बगल में मारा कृपया इसे स्वीकार करने के लिए। –

+1

एल्गोरिदम को फिर से शुरू करने के लिए: और जब आप 27 फरवरी या 1 फरवरी है तो आप क्या उम्मीद करते हैं? – GvS

उत्तर

30

मैं तुम्हें क्या पता नहीं है हासिल करना चाहते हैं, लेकिन आप एक दिन जोड़ सकते हैं, एक महीने जोड़ सकते हैं और एक दिन घटा सकते हैं।

DateTime nextMonth = date.AddDays(1).AddMonths(1).AddDays(-1); 

संपादित:

टिप्पणीकर्ताओं में से एक बताते हैं के रूप में, यह कभी कभी गलत परिणाम देता है। अपने अपडेट किए गए सवाल पढ़ने के बाद, मुझे लगता है कि आप चाहते हैं तिथि की गणना के लिए सबसे आसान तरीका है:

public static DateTime NextMonth(this DateTime date) 
{ 
    if (date.Day != DateTime.DaysInMonth(date.Year, date.Month)) 
     return date.AddMonths(1); 
    else 
     return date.AddDays(1).AddMonths(1).AddDays(-1); 
} 

इस विस्तार विधि रिटर्न अगले महीने की तारीख। जब वर्तमान तिथि महीने का आखिरी दिन है, तो यह अगले महीने के अंतिम दिन वापस आ जाएगी।

+0

चालाक - अगर वह पहले से ही महीने के आखिरी दिन की गारंटी देता है तो वह काम करेगा। –

+4

यदि वह नहीं करता है, तो परिणाम 30 मई के लिए AddMonths (1) –

+4

जैसा ही है, यह नहीं है। –

0

नहीं - यह इसे ध्यान में नहीं लेता है। यह सभी तरह से कस्टम कोड है!

क्या आपका कोड केवल महीनों के आखिरी दिन में रुचि रखेगा, या आप चाहते हैं कि कोई भी माह किसी भी महीने में कोड जोड़ना चाहे, लेकिन उस तारीख को ध्यान में रखें जब महीने की आखिरी दिन दी जाती है?

+0

हाँ, महीनों का आखिरी दिन पर्याप्त होगा, जैसा कि मुझे लगता है ... जैसे ही यह काम करता है, मैं उत्तर को चिह्नित करता हूं :) – grady

+1

मूल पोस्ट – grady

-1

कोशिश दिन संपत्ति ओवरलोडिंग और 32. करने के लिए इसे स्थापित करने Whgen इस जावास्क्रिप्ट में किया जाता है, मेरा मानना ​​है कि यह चूक वापस जो कुछ महीने में लिप्त हों के अंतिम दिन है।

+0

का मेरा संपादन देखें यदि आपका मतलब है * सेट * दिन की संपत्ति - यह है अपरिवर्तनीय (यह सी # है - प्रश्न पर टैग देखें)। –

+0

वाह! माफ़ कीजिये। मुझे एहसास नहीं हुआ कि आप सी # में ऐसा नहीं कर सके। – Sam

6

तुम्हारा मतलब हैं कि परिणामी तारीख महीने के अंत से समान दूरी होना चाहिए, तो आप कस्टम कोड में कर रहे हैं - जैसे (पूरी तरह से परीक्षण नहीं, विशेष रूप से 28/30/31 महीने फिर से) कुछ:

class Program 
{ 
    static void Main() 
    { 
     var when = DateTime.Today; 
     DateTime fromEndOfNextMonth = when.AddMonthsRelativeToEndOfMonth(1); 
    } 

} 
public static class DateTimeExtensions 
{ 
    public static DateTime AddMonthsRelativeToEndOfMonth(
       this DateTime when, int months) 
    { 
     if (months == 0) return when; 
     DateTime startOfNextMonth = when; 
     int month = when.Month; 
     while (startOfNextMonth.Month == month) 
     { 
      startOfNextMonth = startOfNextMonth.AddDays(1); 
     } 
     TimeSpan delta = startOfNextMonth - when; 
     return startOfNextMonth.AddMonths(1) - delta; 
    } 

} 
0

मैं अब इसे हल, पता चल सके कि यह एक महीने GetLastDayInCurrentMonth का उपयोग करने का अंतिम दिन है द्वारा। thats मामले, मैं का उपयोग करते हैं

DateTime nextMonth = date.AddDays(1).AddMonths(1).AddDays(-1); 

अपनी नहीं अंतिम दिन है, तो मैं सिर्फ AddMonths का उपयोग (1)

धन्यवाद लोग!

0
if(yourDate.Day == DaysInMonth(yourDate.Year,yourDate.Month)) //check for last day 
    yourDate.AddDays(DateTime.DaysInMonth(yourDate.Year,(yourDate.Month+1)%12)); 
+0

क्या होगा यदि आपकी तिथि दिसम्बर में है? –

+0

@ फिलिपपे लेबेर्ट: इसे बाहर निकालने के लिए धन्यवाद। मेरा संपादन जांचें। – Amsakanna

0
public static class DateTimeExtensions 
{ 
    public static DateTime AddMonthsCustom(this DateTime source, int months) 
    { 
     DateTime result = source.AddMonths(months); 
     if (source.Day != DateTime.DaysInMonth(source.Year, source.Month)) 
      return result; 

     return new DateTime(result.Year, result.Month, 
          DateTime.DaysInMonth(result.Year, result.Month), 
          result.Hour, result.Minute, result.Second, 
          result.Millisecond, result.Kind); 
    } 
} 
2

कैसे के बारे में इस तरह? यह 30 जनवरी की समस्या को हल करता है जो वर्तमान सर्वोत्तम उत्तर के साथ होगा।

 public static DateTime AddJustMonths(this DateTime @this, int months) 
     { 
      var firstDayOfTargetMonth = new DateTime(@this.Year, @this.Month, 1).AddMonths(months); 
      var lastDayofTargetMonth = DateTime.DaysInMonth(firstDayOfTargetMonth.Year, firstDayOfTargetMonth.Month); 

      var targetDay = @this.Day > lastDayofTargetMonth ? lastDayofTargetMonth : @this.Day; 

      return new DateTime(firstDayOfTargetMonth.Year, firstDayOfTargetMonth.Month, targetDay); 
     } 
2

यह कोड महीनों की संख्या जोड़ देगा और लक्ष्य माह के अंतिम दिन तक पहुंच जाएगा यदि वर्तमान दिन वर्तमान माह का अंतिम दिन है।ध्यान दें कि मूल रूप से कोई समाधान पूरी तरह से कस्टम दिनांकों के बिना 30 जनवरी की समस्या के लिए कोई समाधान नहीं है:

यदि तारीख एकमात्र राज्य है, तो कोई फर्क नहीं पड़ता कि आप 30 जनवरी से एक महीने तक कैसे कूदते हैं अगर आप फरवरी के अंतिम दिन या वर्तमान महीने के 28 वें के परिणाम के रूप में परिणाम चुनने के लिए चुना है। आपके पास तारीख नहीं है क्योंकि तिथि आपकी एकमात्र स्थिति है। कोई 'ध्वज' नहीं है जो आपको बताता है कि यह 28 फरवरी का मूल रूप से जनवरी में मूल रूप से एकल था।

प्रभावी रूप से इसका मतलब है कि जनवरी 30. AddMonthsCustom (1) .ddMonthsCustom (1)! = Jan30.AddMonthsCustom (2) और अंततः 30 वीं, 2 9वीं और 28 वीं तारीख महीने के आखिरी दिन समाप्त होती है यदि आप प्रचार करते रहें ।

public static DateTime AddMonthsCustom(this DateTime date, int months) 
{ 

    // Check if we are done quickly. 
    if(months == 0) 
     return; 

    // Lookup the target month and its last day. 
    var targetMonth = new DateTime(date.Year, date.Month, 1).AddMonths(months); 
    var lastDay = DateTime.DaysInMonth(targetMonth.Year, targetMonth.Month); 

    // If we are starting out on the last day of the current month, then jump 
    // to the last day of the target month. 
    if (date.Day == DateTime.DaysInMonth(date.Year, date.Month)) 
     return new DateTime(targetMonth.Year, targetMonth.Month, lastDay); 

    // If the target month cannot accomodate the current day, jump to the 
    // last day of the target month. 
    if (date.Day > lastDay) 
     return new DateTime(targetMonth.Year, targetMonth.Month, lastDay); 

    // Simply jump to the current day in the target month. 
    return new DateTime(targetMonth.Year, targetMonth.Month, date.Day); 
} 

यदि मैं गलत हूं, तो कृपया मुझे बताएं। मैं वास्तव में यह हल करना चाहता हूँ।

0

इसके बारे में क्या? यह एक विस्तार विधि के रूप में आप जितने महीनों को जोड़ सकते हैं - यानी dateDue.AddSmarthMonths(6); - और 28 महीने के बाद "महीने के आखिरी दिन" के बाद जनवरी के किसी भी दिन को मानता है।

public static DateTime AddSmartMonths(this DateTime d, int nMonths) 
    { 
     int year = d.Year; 
     int month = d.Month; 
     int day = d.Day; 

     if ((day == 30) && (day < DateTime.DaysInMonth(year, month))) 
      d = d.AddDays(1); 
     else if ((month == 1) && (day > 28)) 
      d = new DateTime(year, month, 31); 

     return d.AddMonths(nMonths); 
    } 
1
public static DateTime NextMonth(DateTime date) 
{ 
    DateTime nextMonth = date.AddMonths(1); 

    if (date.Day != DateTime.DaysInMonth(date.Year, date.Month)) //is last day in month 
    { 
     //any other day then last day 
     return nextMonth; 
    } 
    else 
    { 
     //last day in the month will produce the last day in the next month 
     return date.AddDays(DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month)); 
    } 
} 

और सामान्यीकृत कई महीनों के लिए:

public static DateTime AddMonthToEndOfMonth(DateTime date, int numberOfMonths) 
{ 
    DateTime nextMonth = date.AddMonths(numberOfMonths); 

    if (date.Day != DateTime.DaysInMonth(date.Year, date.Month)) //is last day in month 
    { 
     //any other day then last day 
     return nextMonth; 
    } 
    else 
    { 
     //if date was end of month, add remaining days 
     int addDays = DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month) - nextMonth.Day; 
     return nextMonth.AddDays(addDays); 
    } 
} 

कोड फ़रवरी मुद्दों, लीप वर्ष और नए साल के संक्रमण के खिलाफ परीक्षण किया जाता है। सभी परीक्षण पास हुए।

enter image description here

[TestMethod] 
public void AddMonthTest_January() 
{ 
    for (int i = 1; i <= 28; i++) 
    { 
     Assert.AreEqual(new DateTime(2015, 2, i), NextMonth(new DateTime(2015, 1, i))); 
    } 
    Assert.AreEqual(new DateTime(2015, 2, 28), NextMonth(new DateTime(2015, 1, 29))); 
    Assert.AreEqual(new DateTime(2015, 2, 28), NextMonth(new DateTime(2015, 1, 30))); 
    Assert.AreEqual(new DateTime(2015, 2, 28), NextMonth(new DateTime(2015, 1, 31))); 
} 

[TestMethod] 
public void AddMonthTest_February() 
{ 
    Assert.AreEqual(new DateTime(2015, 3, 31), NextMonth(new DateTime(2015, 2, 28))); 

    for (int i = 1; i <= 27; i++) 
    { 
     Assert.AreEqual(new DateTime(2015, 3, i), NextMonth(new DateTime(2015, 2, i))); 
    }    
} 

[TestMethod] 
public void AddMonthTest_March() 
{ 
    Assert.AreEqual(new DateTime(2015, 4, 30), NextMonth(new DateTime(2015, 3, 31))); 

    for (int i = 1; i <= 30; i++) 
    { 
     Assert.AreEqual(new DateTime(2015, 4, i), NextMonth(new DateTime(2015, 3, i))); 
    } 
} 

[TestMethod] 
public void AddMonthTest_December() 
{    
    for (int i = 1; i <= 31; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 1, i), NextMonth(new DateTime(2015, 12, i))); 
    } 
} 

[TestMethod] 
public void AddMonthTest_January_LeapYear() 
{ 
    for (int i = 1; i <= 29; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 2, i), NextMonth(new DateTime(2016, 1, i))); 
    }    
    Assert.AreEqual(new DateTime(2016, 2, 29), NextMonth(new DateTime(2016, 1, 30))); 
    Assert.AreEqual(new DateTime(2016, 2, 29), NextMonth(new DateTime(2016, 1, 31))); 
} 

[TestMethod] 
public void AddMonthTest_February_LeapYear() 
{ 
    Assert.AreEqual(new DateTime(2016, 3, 31), NextMonth(new DateTime(2016, 2, 29))); 

    for (int i = 1; i <= 28; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 3, i), NextMonth(new DateTime(2016, 2, i))); 
    } 
} 

[TestMethod] 
public void AddHalfYearTest_January_LeapYear() 
{   
    for (int i = 1; i <= 31; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 7, i), new DateTime(2016, 1, i).AddMonthToEndOfMonth(6)); 
    } 
} 

[TestMethod] 
public void AddHalfYearTest_February_LeapYear() 
{ 
    Assert.AreEqual(new DateTime(2016, 8, 31), new DateTime(2016, 2, 29).AddMonthToEndOfMonth(6)); 

    for (int i = 1; i <= 28; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 8, i), new DateTime(2016, 2, i).AddMonthToEndOfMonth(6)); 
    } 
} 

[TestMethod] 
public void AddHalfYearTest_December() 
{ 
    Assert.AreEqual(new DateTime(2016, 6, 30), new DateTime(2015, 12, 31).AddMonthToEndOfMonth(6)); 
    for (int i = 1; i <= 30; i++) 
    { 
     Assert.AreEqual(new DateTime(2016, 6, i), new DateTime(2015, 12, i).AddMonthToEndOfMonth(6)); 
    } 
} 
0

तुम कोशिश कर सकते इस

private void datTimPkerFrom_ValueChanged(object sender, EventArgs e) 
{ 
    int DaysInMonth = DateTime.DaysInMonth(datTimPkerFrom.Value.Year, datTimPkerFrom.Value.Month); 

    if (DaysInMonth == 31) 
    { 
     datTimPkerTo.Value = datTimPkerFrom.Value.AddDays(30); 
    } 
    else if (DaysInMonth == 30) 
    { 
     datTimPkerTo.Value = datTimPkerFrom.Value.AddDays(29); 
    } 
    else if (DaysInMonth == 29) 
    { 
     datTimPkerTo.Value = datTimPkerFrom.Value.AddDays(28); 
    } 
    else 
    { 
     datTimPkerTo.Value = datTimPkerFrom.Value.AddDays(27); 
    } 
} 
1

क्या सुझाव दिया rashleighp लगभग सही है लेकिन जैसे के लिए काम नहीं करता है 2016-02-29 को 1 महीने जोड़ना (परिणाम 2016-03-31 होना चाहिए) या 2017-02-28 (परिणाम 2017-03-31 होना चाहिए)

इस संशोधित संस्करण को सभी विशेष मामलों सहित काम करना चाहिए।

public static DateTime AddMonthsCustom(this DateTime source, int months) 
{ 
    var firstDayOfTargetMonth = new DateTime(source.Year, source.Month, 1).AddMonths(months); 
    var lastDayofSourceMonth = DateTime.DaysInMonth(source.Year, source.Month); 
    var lastDayofTargetMonth = DateTime.DaysInMonth(firstDayOfTargetMonth.Year, firstDayOfTargetMonth.Month); 

    var targetDay = source.Day > lastDayofTargetMonth ? lastDayofTargetMonth : source.Day; 
    if (source.Day == lastDayofSourceMonth) 
     targetDay = lastDayofTargetMonth; 

    return new DateTime(
     firstDayOfTargetMonth.Year, 
     firstDayOfTargetMonth.Month, 
     targetDay, 
     source.Hour, 
     source.Minute, 
     source.Second, 
     source.Millisecond, 
     source.Kind); 
} 

नीचे पारित कर दिया सभी NUnit परीक्षण:

[TestCase("2017-01-01T01:01:01.0010000Z", "2016-12-01T01:01:01.0010000Z", 1)] 
[TestCase("2017-02-01T01:01:01.0010000Z", "2016-12-01T01:01:01.0010000Z", 2)] 
[TestCase("2017-03-31T01:01:01.0010000Z", "2016-12-31T01:01:01.0010000Z", 3)] 
[TestCase("2016-03-28T01:01:01.0010000Z", "2016-02-28T01:01:01.0010000Z", 1)] 
[TestCase("2016-03-31T01:01:01.0010000Z", "2016-02-29T01:01:01.0010000Z", 1)] 
[TestCase("2017-03-31T01:01:01.0010000Z", "2017-02-28T01:01:01.0010000Z", 1)] 
[TestCase("2016-02-29T01:01:01.0010000Z", "2016-01-31T01:01:01.0010000Z", 1)] 
[TestCase("2017-02-28T01:01:01.0010000Z", "2017-01-31T01:01:01.0010000Z", 1)] 
[TestCase("2016-12-01T01:01:01.0010000Z", "2017-01-01T01:01:01.0010000Z", -1)] 
[TestCase("2016-12-01T01:01:01.0010000Z", "2017-02-01T01:01:01.0010000Z", -2)] 
[TestCase("2016-12-31T01:01:01.0010000Z", "2017-03-31T01:01:01.0010000Z", -3)] 
[TestCase("2016-02-28T01:01:01.0010000Z", "2016-03-28T01:01:01.0010000Z", -1)] 
public void DateTimeExtensions_AddMonthsCustom(DateTime expected, DateTime dateTime, int months) 
{ 
    // Arrange 
    expected = expected.ToUniversalTime(); 
    dateTime = dateTime.ToUniversalTime(); 

    // Act 
    DateTime result = dateTime.AddMonthsCustom(months); 

    // Assert 
    Assert.AreEqual(expected.Kind, result.Kind); 
    Assert.AreEqual(expected, result); 
} 
संबंधित मुद्दे