【问题标题】:c# date comparison returning a DateTime objectc# 日期比较返回一个 DateTime 对象
【发布时间】:2011-08-20 21:11:11
【问题描述】:

给定一个 DateTime 对象(上次购买),我可以与 DateTime.Now 进行比较以返回一个包含年、月、日、小时和秒的新 DateTime 对象吗?

我可以比较日期并返回年数,但是我需要精确到秒的所有详细信息。

任何帮助或示例将不胜感激

【问题讨论】:

  • 从两个日期的比较中返回 DateTime 的问题是 DateTime 代表一个特定的日期。所以,即使你可以做这样的事情,你最终会得到类似“2011 年 5 月 5 日 - 2011 年 1 月 1 日 = 2011 年 2 月 24 日”之类的东西。这是荒谬的。

标签: c# datetime date


【解决方案1】:

不,你不能,因为DateTime 代表一个绝对时间点,而不是一个时间跨度。用于差异的正确对象是TimeSpan。它具有所有相关时间单位的属性。只需减去两个DateTimes 即可得到一个:

TimeSpan ts = DateTime.Now - purchaseDate;

【讨论】:

  • 我需要一个包含年、月等的对象。我不相信 TimeSpan 能提供这个?
  • @sam:一个月有多长?一年怎么样?
  • 不同月份更不用说闰年了?
  • @sam:那么应该如何计算两天之间的月数呢?
  • @sam - 当然,你将能够得到你想要的东西 - 它只涉及你的一些编码。框架中没有任何对象可以为您提供所需的东西
【解决方案2】:

您不想拥有一个新的DateTime 对象。你想要的是TimeSpan。这就是减去DateTime 实例后得到的结果:

TimeSpan difference = DateTime.Now - yourDate

【讨论】:

  • 这不会提供年份和月份
  • 这是正确的,但那是因为需要锚定数月和数年。您正在寻找的是一段时间,从一个日期到另一个日期,但“月”的概念仍然是模糊的。例如,如果 1 月 1 日和 3 月 1 日之间的时间段是 3 个月,那么如果从 6 月 1 日开始计算,那么 3 个月的时间长度是相同的(提示:天数不一致。)
  • 有时,事情并不完全合乎逻辑,这就是问题出现的地方。看一个人的年龄,可以说“我今年 25 岁 3 个月零 6 天”。事实是,这在科学上意义不大。但大多数人会比说你已经超过 9200 天更能理解这一点。所以问题是,Sam 想要提供一个科学上正确的值还是人类可读的东西?
  • 在一般框架中,我只期望“完全合乎逻辑”的解决方案。如果他想要一个在他的用例中有意义的自定义逻辑,他必须实现它。作为 TimeSpan 或 DateTime 的扩展方法。
【解决方案3】:

您可以使用 TimeSpan 来比较两个日期。来看看

DateTime date1 = new DateTime(2010, 1, 1, 8, 0, 15);
DateTime date2 = new DateTime(2010, 8, 18, 13, 30, 30);
// Calculate the interval between the two dates.
TimeSpan interval = date2 - date1;

年和月必须通过自定义编码来计算,因为月是一个可变的计量单位,但由于 TimeSpan 告诉您天数,您可以自己计算月和年。

看看这个post

看看这个forum

希望对您有所帮助。

【讨论】:

  • 这不会提供年份和月份
  • 您必须通过自定义编码计算年份和月份,因为月份是一个可变的计量单位,但由于 TimeSpan 告诉您日期,您可以自己计算月份和年份。
【解决方案4】:

我认为您需要结合TimeSpan 和一些自定义计算。这是因为您想要长度可变的年份和月份。此外,您还需要小时数、分钟数和秒数。 我认为这种方法可以满足您的需求:

var date1 = new DateTime(2010, 1, 1, 8, 0, 15);
var date2 = new DateTime(2007, 8, 18, 13, 30, 30);

var differenceYears = date1.Year - date2.Year;
var tempDate = date2.AddYears(differenceYears);
var differenceMonths = date1.Month - tempDate.Month;
if (differenceMonths < 0)
{
    differenceMonths += 12;
    differenceYears--;
}
tempDate = date2.AddYears(differenceYears).AddMonths(differenceMonths);
var additionalTimeSpan = date1 - tempDate;
var differenceDays = additionalTimeSpan.Days;
var differenceHours = additionalTimeSpan.Hours;
var differenceMinutes = additionalTimeSpan.Minutes;
var differenceSeconds = additionalTimeSpan.Seconds;

【讨论】:

  • -1 我认为这个逻辑行不通。您的tempdate 经常会晚于结束日期(在错误的年份)。即使您处理负月差,您的代码在涉及闰年的特殊情况下也会失败。
  • 好的,重点。我同意这段代码不是防弹的,我自己没有注意到。感谢您的评论。但是你是否同意思维方式是要走的路,还是不能这样做?
【解决方案5】:

TimeSpan 是处理这个问题的正确方法,但是,如果您不想自己进行月/年的转换,您总是可以使用一些递归方法来减去年,直到得到正确的年份,几个月直到你得到正确的月份,直到你到达正确的日期,等等。不过,这会很糟糕而且很丑。

此外,您还需要一个自定义对象来为您保存数据。

粗剪类似于

DateTime original = [Whatever]
DateTime compare = [Whatever]
DateTimeDiff difference = GetDifference(original, compare)

GetDifference(DateTime original, DateTime compare)
{
  DateTimeDiff difference = new DateTimeDifference
  while(!original.Equals(compare) && original.Year >= compare.Year)
  {
     original.AddYears(-1);
     difference.Years++;
  }
  <snip...  //more code to do the same thing for months, days, hours, etc.)
}

就像我说的那样,它会很糟糕而且很丑,但你可以做到。

【讨论】:

    【解决方案6】:

    This 库包含类 DateDiff 并支持年和月:

    // ----------------------------------------------------------------------
    public void DateDiffSample()
    {
      DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
      Console.WriteLine( "Date1: {0}", date1 );
      // > Date1: 08.11.2009 07:13:59
      DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
      Console.WriteLine( "Date2: {0}", date2 );
      // > Date2: 20.03.2011 19:55:28
    
      DateDiff dateDiff = new DateDiff( date1, date2 );
    
      // differences
      Console.WriteLine( "DateDiff.Years: {0}", dateDiff.Years );
      // > DateDiff.Years: 1
      Console.WriteLine( "DateDiff.Quarters: {0}", dateDiff.Quarters );
      // > DateDiff.Quarters: 5
      Console.WriteLine( "DateDiff.Months: {0}", dateDiff.Months );
      // > DateDiff.Months: 16
      Console.WriteLine( "DateDiff.Weeks: {0}", dateDiff.Weeks );
      // > DateDiff.Weeks: 70
      Console.WriteLine( "DateDiff.Days: {0}", dateDiff.Days );
      // > DateDiff.Days: 497
      Console.WriteLine( "DateDiff.Weekdays: {0}", dateDiff.Weekdays );
      // > DateDiff.Weekdays: 71
      Console.WriteLine( "DateDiff.Hours: {0}", dateDiff.Hours );
      // > DateDiff.Hours: 11940
      Console.WriteLine( "DateDiff.Minutes: {0}", dateDiff.Minutes );
      // > DateDiff.Minutes: 716441
      Console.WriteLine( "DateDiff.Seconds: {0}", dateDiff.Seconds );
      // > DateDiff.Seconds: 42986489
    } // DateDiffSample
    

    【讨论】:

    • @Lee:非常感谢 :) Microsoft 库 Microsoft.VisualBasic 包含一个 DateDiff 类,遗憾的是它没有用。 link。另见link
    • 是的 - 我原本以为 DateDiff 函数可以解决问题,但经过深入研究后,我意识到它很漂亮。
    【解决方案7】:

    如果您想要几年和几个月,则必须编写自己的代码。由于不同的闰年问题,使用 100% 正确的输出编写此代码实际上很棘手。

    这里有几个棘手的特殊情况(注意 2012 年是闰年,2011 年不是):

    1. 2010 年 2 月 28 日2011 年 2 月 28 日之间 - 1y、0m、0d
    2. 2011 年 2 月 28 日2012 年 2 月 28 日 - 1y、11m、28d
    3. 2011 年 2 月 28 日2012 年 2 月 29 日 - 1y, 0m, 0d
    4. 2012 年 2 月 29 日2013 年 2 月 28 日之间 - 1y、0m、0d
    5. 2011 年 2 月 10 日2011 年 3 月 9 日之间 - 0y、0m、27d
    6. 2012 年 2 月 10 日2012 年 3 月 9 日 - 0y, 0m, 28d

    我认为您需要通过一些修改来实现类似于 AllenG 算法的东西

    1. 您需要从最早的日期时间(datetime1)开始。确保它是最早的。
    2. 循环直到 datetime1.AddYears(1) 与您的最新日期时间 (datetime2) 比较大于或等于。确保比较整个日期时间,而不仅仅是 starttime 和 endttime 的 year 属性。

      • 每次迭代增加一个年份计数器。
      • 实际上在您的 datetime1 副本中添加一年。
    3. 从 datetime1 副本开始(您在步骤 2 中添加了年份)

    4. 循环直到 datetime1.AddMonths(1) 比较大于或等于您的最新日期时间 (datetime2)。再说一遍:确保您比较整个日期时间,而不仅仅是月份部分。
      • 每次迭代增加一个月计数器。
      • 实际上在您的 datetime1 副本中添加一个月。
    5. 等。等等

    此算法可确保您使用基础日历的正确摘录来计算年、月、日、小时、分钟和秒的差异。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-02
      • 2011-09-30
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      相关资源
      最近更新 更多