假设我已经 2010年2月28日,并使用AddMonths(1)
在此日期添加一个月... ...
结果日期 3月28日,但不是 3月31日,这是我想要的。
有没有办法调整一点,所以这可以工作而不添加自定义代码?
编辑:我不需要一个月的最后一天,实际上我需要添加一个月,但是当它是一个月的最后一天时,我需要找到下个月的最后一天。
答案 0 :(得分:36)
我不知道你想要达到什么目标,但你可以添加一天,增加一个月并减去一天。
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);
}
此扩展方法返回下个月的日期。当前日期是该月的最后一天,它将返回下个月的最后一天。
答案 1 :(得分:7)
如果你的意思是结果日期与该月的结束的距离相同,那么你就会进入自定义代码 - 类似于(未经过全面测试,特别是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;
}
}
答案 2 :(得分:4)
这样怎么样?它解决了当前最佳答案会出现的1月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);
}
答案 3 :(得分:3)
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);
}
}
该代码针对2月问题,闰年和新年过渡进行测试。所有测试都通过了。
[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));
}
}
答案 4 :(得分:2)
此代码将添加月数,如果当前日期是当月的最后一天,则会跳转到目标月份的最后一天。请注意,在没有完全自定义日期的情况下,1月30日的问题基本上没有解决方案:
如果日期是唯一的状态,那么无论您如何处理1月30日前一个月的跳跃,您必须选择是否将结果解释为 2月的最后一天或简单当月的第28天。你不能同时拥有这两个,因为日期是你唯一的状态。没有标志&#39;它告诉你,2月28日最初是1月份的单一到最后一天。
实际上这意味着Jan30.AddMonthsCustom(1).AddMonthsCustom(1)!= Jan30.AddMonthsCustom(2),如果你继续传播,那么最终任何第30,29和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);
}
如果我错了,请告诉我。我真的很想解决这个问题。
答案 5 :(得分:1)
rashleighp建议几乎是正确的,但对于例如加入1个月到2016-02-29(结果应该是2016-03-31)或者2017-02-28(结果应该是2017-03-31)
此修改版本应该包括所有特殊情况。
Package: Amelia
Version: 1.7.4
Depends: R (>= 3.0.2), Rcpp (>= 0.11)
Imports: foreign, utils, grDevices, graphics, methods, stats
LinkingTo: Rcpp (>= 0.11), RcppArmadillo
Suggests: tcltk, Zelig
License: GPL (>= 2)
Archs: i386, x64
Package: BH
Version: 1.60.0-1
License: BSL-1.0
以下所有NUnit测试都通过了:
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);
}
答案 6 :(得分:0)
这个怎么样?它可以添加任意数月作为扩展方法 - 即dateDue.AddSmarthMonths(6);
- 并考虑在“月的最后一天”28之后的1月的任何一天。
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);
}
答案 7 :(得分:0)
如果您想总是在下个月的同一天,使用它会不会更简单:
DateTime nextMonth = new DateTime(thisMonth.Year, thisMonth.Month + 1, thisMonth.Day);
答案 8 :(得分:0)
您也可以尝试
src="../js/main.js"
答案 9 :(得分:0)
以下提到的扩展方法将产生月份的最后一天,如果给定的日期是该月的最后一天,则使用datetime API。
public static DateTime AddMonthsE(this DateTime value,int numberOfMonths)
{
bool isEndDate = DateTime.DaysInMonth(value.Year, value.Month) == value.Day;
if(isEndDate)
{
var newDateTime = value.AddMonths(numberOfMonths);
return new DateTime(newDateTime.Year, newDateTime.Month, DateTime.DaysInMonth(newDateTime.Year, newDateTime.Month));
}
return value.AddMonths(numberOfMonths);
}
输入:2010年2月28日上午12:00:00 输出加上1个月的时间2010年3月31日上午12:00:00
答案 10 :(得分:0)
将下个月的最后一天放在一行:
var t1 = new DateTime(2010,2,28);
var t2 = t1.AddDays((t1.Day * -1) + 1).AddMonths(2).AddMilliseconds(-1).Date;
// t2: {31.03.2010 00:00:00}
(操作是:获取当月的第一天(= 1.Feb 10),添加2个月(= 1. 4月10日),减去1 ms(= 31。3月10日),可选截止时间
答案 11 :(得分:0)
This will add numMonths to someDate and, if someDate is end-of-month, return value will be end-of-month, otherwise it just does AddMonths(numMonths)
private DateTime AddMonthsRetainingEOM(DateTime someDate, int numMonths)
{
if (someDate.AddDays(1).Day == 1)
{
// someDate is EOM
someDate = someDate.AddMonths(numMonths);
// keep adding days if new someDate is not EOM
while (someDate.AddDays(1).Day != 1)
{
someDate = someDate.AddDays(1);
}
return someDate;
}
else
{
// not EOM - Just add months
return someDate.AddMonths(numMonths);
}
}
答案 12 :(得分: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);
}
}
答案 13 :(得分:0)
不 - 它没有考虑到这一点。这是自定义代码!
您的代码是否只对几个月的最后一天感兴趣,或者您是否希望代码在任何日期添加一个月,但是在提供的日期是该月的最后一天时会考虑?
答案 14 :(得分: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);
}
}
答案 15 :(得分:0)
if(yourDate.Day == DaysInMonth(yourDate.Year,yourDate.Month)) //check for last day
yourDate.AddDays(DateTime.DaysInMonth(yourDate.Year,(yourDate.Month+1)%12));
答案 16 :(得分:0)
我现在通过使用 GetLastDayInCurrentMonth 检查它是否是一个月的最后一天来解决它。如果是这样,我使用
DateTime nextMonth = date.AddDays(1).AddMonths(1).AddDays(-1);
如果不是最后一天,我只使用AddMonths(1)
谢谢你们!
答案 17 :(得分:-1)
尝试重载day属性并将其设置为32.如果在JavaScript中完成此操作,我相信它会默认返回到您所在月份的最后一天。