一起添加两个DateTime对象

Sai*_*int 15 c# datetime add

有没有更好的方法将一个DateTime对象添加到另一个,而不是:

DateTime first = new DateTime(2000, 1, 1);
DateTime second = new DateTime(11, 2, 5, 10, 10, 11);

DateTime result = first.AddYears(second.Year);
DateTime result = first.AddMonths(second.Month);
...
Run Code Online (Sandbox Code Playgroud)

等等...

在这个例子中,我想得到 DateTime(2011, 3, 6, 10, 10, 11)

编辑

经过密集的头脑风暴之后似乎没有什么不同的方式,但是为了方便它可以装在额外的类和操作员里面,就像在JonSkeet的回答中一样

Jon*_*eet 36

将两个DateTime值一起添加是没有意义的.如果你想代表"11年,2个月,5天,10个小时,10分钟和11秒",那么你应该代表那个.这是一样的0011-02-05T10:10:11.特别是,你永远无法添加"2个月和30天".同样,您永远无法添加一年,因为日期内的月和日值不能为0.

现在没有BCL类型来代表"11年[...]"的想法,但你可以合理地轻松创建自己的类型.作为替代方案,您可以使用我的Noda Time项目,Period正是出于这个目的:

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;
Run Code Online (Sandbox Code Playgroud)

与此处提供的其他一些答案相反,您不能将其TimeSpan用于此目的.TimeSpan没有任何月份和年份的概念,因为它们的长度不同,而a 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

DateTime first = new DateTime(2000, 1, 1);
Period second = new Period(11, 2, 5, 10, 10, 11);
DateTime result = first + second;
Run Code Online (Sandbox Code Playgroud)

你需要知道如何DateTime.Add处理不可能的情况 - 例如,在1月31日增加一个月会给你2月28日/ 29日,这取决于它是否是闰年.

我在这里列出的简单方法,通过中间值,有其缺点,因为截断可能发生两次(增加年数,然后增加几个月),当它不需要时 - 例如,"2月29日+ 1年+ 1个月"可能逻辑上是"3月29日",但它实际上最终会变成"3月28日",截至2月28日将在月份加入之前发生.

试图找出一种"正确"的方法来进行日历算法是非常困难的,特别是在某些情况下,人们可能不同意"正确"的答案是什么.在上面的代码中,我选择了简单性和可预测性 - 根据您的实际需求,您可能需要更复杂的东西.

  • @ code4life:不,它*是*不可能的.代表"1个月"的"TimeSpan"会是什么样子?里面有几个蜱虫? (2认同)

Ren*_*ros 7

DateTime first = new DateTime(2000, 1, 1);
DateTime second = new DateTime(11, 2, 5, 10, 10, 11);

DateTime result = new DateTime(first.Ticks + second.Ticks);
Run Code Online (Sandbox Code Playgroud)