将两个DateTime 值相加是没有意义的。如果您想表示“11 年、2 个月、5 天、10 小时、10 分钟和 11 秒”,那么您应该表示它。这不与 0011-02-05T10:10:11 相同。特别是,例如,您永远无法添加“2 个月零 30 天”。同样,您永远无法仅添加一年,因为日期中的月份和日期值不能为 0。
现在没有 BCL 类型来代表“11 年 [...]”的概念,但您可以相当容易地创建自己的类型。作为替代方案,您可以使用我的具有Period 的Noda Time 项目来实现此目的:
var localDateTime = new LocalDate(2000, 1, 10).AtMidnight();
var period = new PeriodBuilder {
Years = 11, Months = 2, Days = 5,
Hours = 10, Minutes = 10, Seconds = 11
}.Build();
var result = localDateTime + period;
与此处提供的其他一些答案相反,您不能为此目的使用TimeSpan。 TimeSpan 没有任何月份和年份的概念,因为它们的长度不同,而 TimeSpan 表示固定数量的滴答声。 (如果您的最大单位是天,那么您可以使用 TimeSpan,但鉴于您的示例,我假设您需要数月和数年。)
如果您不想使用 Noda Time,我建议您自己伪造一个类似 Period 的课程。这很容易做到——例如:
// Untested and quickly hacked up. Lots more API you'd probably
// want, string conversions, properties etc.
public sealed class Period
{
private readonly int years, months, days, hours, minutes, seconds;
public Period(int years, int months, int days,
int hours, int minutes, int seconds)
{
this.years = years;
this.months = months;
this.days = days;
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
public static DateTime operator+(DateTime lhs, Period rhs)
{
// Note: order of operations is important here.
// Consider January 1st + (1 month and 30 days)...
// what do you want the result to be?
return lhs.AddYears(rhs.years)
.AddMonths(rhs.months)
.AddDays(rhs.days)
.AddHours(rhs.hours)
.AddMinutes(rhs.minutes)
.AddSeconds(rhs.seconds);
}
}
用法:
DateTime first = new DateTime(2000, 1, 1);
Period second = new Period(11, 2, 5, 10, 10, 11);
DateTime result = first + second;
您需要了解DateTime.Add 将如何处理不可能的情况 - 例如,将一个月添加到 1 月 31 日将得到 2 月 28 日/29 日,具体取决于它是否是闰年。
我在此处列出的简单方法(通过中间值)有其缺点,因为这种截断可以在不需要时发生两次(添加年,然后添加月) - 例如,“2 月 29 日 + 1 年+ 1 个月”在逻辑上可能是“3 月 29 日”,但它实际上会以“3 月 28 日”结束,因为在添加月份之前会截断到 2 月 28 日。
尝试找出一种“正确”的日历算术方法是fiendishly difficult,尤其是在某些情况下,人们可能不同意“正确”的答案是什么。在上面的代码中,我选择了简单性和可预测性 - 根据您的实际需求,您可能需要更复杂的东西。