【问题标题】:Function to get a custom Date Difference获取自定义日期差异的函数
【发布时间】:2013-08-15 19:05:49
【问题描述】:

我正在尝试编写一个通用函数来以自定义格式返回两个日期之间的差异,但有人报告我的 sn-p 有一个错误,例如试图获取这两个日期之间的差异:

15/08/2013 - 02/09/2013 

而且我的函数返回负值和 1 个月的差异,因为 09 大于 08,所以它不像我需要的那样工作:

1 Months, -1 Weeks, -6 Days, 0 Hours, 0 Minutes and 0 Seconds

预期的结果是这样的:

0 Months, 2 Weeks, 4 Days, 0 Hours, 0 Minutes and 0 Seconds

有人可以在某些日期帮我纠正这个错误吗?

这是我的代码:

#Region " Date Difference "

    ' Date Difference
    '
    ' // By Elektro H@cker
    '
    ' Examples :
    '
    ' MsgBox(DateDifference(DateTime.Parse("01/03/2013"), DateTime.Parse("10/04/2013"))) ' Result: 1 Months, 1 Weeks, 2 Days, 0 Hours, 0 Minutes and 0 Seconds
    ' MsgBox(DateDifference(DateTime.Parse("01/01/2013 14:00:00"), DateTime.Parse("02/01/2013 15:00:30"))) ' Result: 0 Months, 0 Weeks, 1 Days, 1 Hours, 0 Minutes and 30 Seconds

    Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

        Dim MonthDiff As String, WeekDiff As String, _
            DayDiff As String, HourDiff As String, _
            MinuteDiff As String, SecondDiff As String

        MonthDiff = Convert.ToString(DateDiff("M", Date1, Date2))
        WeekDiff = Convert.ToString(DateDiff("d", Date1.AddMonths(DateDiff("M", Date1, Date2)), Date2) \ 7)
        DayDiff = Convert.ToString(DateDiff("d", Date1.AddMonths(DateDiff("M", Date1, Date2)), Date2) - (WeekDiff * 7))
        HourDiff = Convert.ToString(DateDiff("h", Date1.AddHours(DateDiff("h", Date1, Date2)), Date2) - (Date1.Hour - Date2.Hour))
        MinuteDiff = Convert.ToString(DateDiff("n", Date1.AddMinutes(DateDiff("n", Date1, Date2)), Date2) - (Date1.Minute - Date2.Minute))
        SecondDiff = Convert.ToString(DateDiff("s", Date1.AddSeconds(DateDiff("s", Date1, Date2)), Date2) - (Date1.Second - Date2.Second))

        Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                             MonthDiff, WeekDiff, DayDiff, HourDiff, MinuteDiff, SecondDiff)

    End Function

#End Region

更新:

我正在尝试这样做,但现在如何减去周数?

私有函数 DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

Dim MonthDiff As String, WeekDiff As String, _
   DayDiff As String, HourDiff As String, _
   MinuteDiff As String, SecondDiff As String

MonthDiff = Date2.Month - Date1.Month

' WeekDiff = Date2.Month - Date1.Month

DayDiff = Date2.Day - Date1.Day

HourDiff = Date2.Hour - Date1.Hour

MinuteDiff = Date2.Minute - Date1.Minute

SecondDiff = Date2.Second - Date1.Second

'  MsgBox((Date2 - Date1).ToString("dd"))

Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                      MonthDiff, WeekDiff, DayDiff, HourDiff, MinuteDiff, SecondDiff)

结束函数

更新 2:

我正在尝试使用其他方法重写它以获得日期准确性,但我完全迷失了:

Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

    Dim DayDiff As Long = Date2.Subtract(Date1).Days
    Dim HourDiff As Long = Date2.Subtract(Date1).Hours
    Dim MinuteDiff As Long = Date2.Subtract(Date1).Minutes
    Dim SecondDiff As Long = Date2.Subtract(Date1).Seconds
    Dim MilliDiff As Long = Date2.Subtract(Date1).Milliseconds

    Dim MonthDiFF As Long
    Dim WeekDiFF As Long

    Select Case (DayDiff Mod DateTime.DaysInMonth(Date1.Year, Date1.Month))

        Case Is <= 0
            MonthDiFF = 0

        Case Is = 1, Is <= 28
            MonthDiFF = 1

        Case Is > 28

    End Select

    MsgBox(DayDiff Mod DateTime.DaysInMonth(Date1.Year, Date1.Month))
    MsgBox(MonthDiFF)

    ' Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
    '                          MonthDiff, WeekDiff, t.Days, t.Hours, t.Minutes, t.Seconds)

End Function

更新 3:

我更接近于编写代码,但就像我说过的那样,我在计算东西时迷失了方向:

Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

    Dim DayDiff As Long = Date2.Subtract(Date1).Days
    Dim HourDiff As Long = Date2.Subtract(Date1).Hours
    Dim MinuteDiff As Long = Date2.Subtract(Date1).Minutes
    Dim SecondDiff As Long = Date2.Subtract(Date1).Seconds
    Dim MilliDiff As Long = Date2.Subtract(Date1).Milliseconds

    Dim MonthDiFF As Long
    Dim WeekDiFF As Long

    For X As Short = CShort(Date1.Month) To CShort(Date2.Month)

        MonthDiFF =
        MsgBox(DayDiff - DateTime.DaysInMonth(Date1.Year, X))

        'MsgBox(DateTime.DaysInMonth(Date1.Year, X))
    Next

    ' MsgBox(DayDiff - DateTime.DaysInMonth(Date1.Year, Date1.Month))
    ' MsgBox(MonthDiFF)

    ' Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
    '                          MonthDiff, WeekDiff, t.Days, t.Hours, t.Minutes, t.Seconds)

End Function

【问题讨论】:

  • 你为什么要在这里重新发明轮子? return (date2-date1).Tostring(formatString);
  • @asawyer,您看到 WEEK 变量了吗?我无法使用标准的 DateTime 格式获得数周,或者我错了?。
  • 查看类似问题的答案:stackoverflow.com/a/9216404/2250183

标签: .net vb.net date datetime datediff


【解决方案1】:

这会以编程方式计算月数和周数,然后将TimeSpan 用于剩余部分。月份计算使用了AddMonths 的智能行为,这会很棘手。

Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String
    Dim MonthDiff = 0
    While Date1 <= Date2
        Date1 = Date1.AddMonths(1)
        MonthDiff += 1
    End While
    MonthDiff -= 1
    Date1 = Date1.AddMonths(-1)
    Dim t As TimeSpan = Date2 - Date1
    Dim WeekDiff As Integer = t.Days \ 7
    t = t - TimeSpan.FromDays(WeekDiff * 7)
    Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                             MonthDiff, WeekDiff, t.Days, t.Hours, t.Minutes, t.Seconds)
End Function

【讨论】:

  • 谢谢你,但它返回此日期的负值:“16/02/2013 14:00:00”-“28/03/2013 15:02:05”
  • @ElektroHacker 我已经更新了我的答案来解决这个问题;我从 C# 转换了我的代码,并错过了 C# 中的整数除法不像 VB.Net 中的整数除法。
  • 非常感谢,但它没有日期准确性,例如在这些日期之间:“01/02/2013 14:00:00”-“01/03/2013 15:02:05”,结果是“1 个月”,但 2 月有 28 天,所以结果实际上是“4 周”。请查看我的更新
  • @ElektroHacker 在 2 月 1 日、3 月 1 日和 4 月 1 日之后的 1 个月,您认为是什么?我预计是 3 月 1 日、4 月 1 日和 5 月 1 日。
  • 老谷歌:1 个月 = 30.4368499 天,我们说“1 个月”和“1 个月”(整月)是不一样的。
【解决方案2】:

我认为最简单的方法是先比较两个日期,然后根据哪个日期更大(稍后)执行 DateDiff。这样你就可以避免负面因素。另一种方法是获取 DateDiff 结果的绝对值,因为只要它是 1 个月,它是前一个月还是后一个月都无关紧要。

【讨论】:

    【解决方案3】:

    这应该可以满足您的需求,因为大多数 TimeSpan 类会为您提供答案:

    Public Shared Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String
        Dim diff As TimeSpan = Date2 - Date1
        Dim months = (Date2.Month - Date1.Month) + 12 * (Date2.Year - Date1.Year)
        diff -= TimeSpan.FromDays(months * 30)
        Dim weeks = Math.Floor(diff.Days / 7)
        diff -= TimeSpan.FromDays(weeks * 7)
        Dim dayDiff = (diff.Days Mod 7).ToString()
        Dim hourDiff = diff.Hours.ToString()
        Dim minDiff = diff.Minutes.ToString()
        Dim secDiff = diff.Seconds.ToString()
    
        Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                             months.ToString, weeks.ToString, dayDiff, hourDiff, minDiff, secDiff)
    End Function
    

    测试:

    Dim diffInfo = DateDifference(New Date(2013, 8, 16, 14, 0, 0), New Date(2013, 9, 28, 15, 2, 5))
    Console.WriteLine(diffInfo) '1 Months, 1 Weeks, 6 Days, 1 Hours, 2 Minutes and 5 Seconds
    

    【讨论】:

    • 感谢您的回答,但代码不适用于以下日期:“16/08/2013 14:00:00”-“18/09/2013 15:02:05”,它返回这个结果:“-1 Months, 5 Weeks, 33 Days, 1 Hours, 2 Minutes and 5 Seconds”
    • @ElektroHacker:编辑了我的答案,月份计算中有一个“特纳”。
    • 表示从 8 月 31 日到 9 月 1 日有一个月零一天。月份中的天数不应以周或天计算。
    • 没办法,使用这个日期 "16/08/2013 14:00:00" - "28/08/2013 15:02:05" 结果是:0 个月,2 周,12天、1 小时、2 分钟和 5 秒
    • 想要的结果是什么?
    【解决方案4】:

    为什么不只是use DateTime.Subtract

    DateTime date1 = new DateTime(2013, 3, 4, 12, 30, 00);
    DateTime date2 = DateTime.Now;
    TimeSpan diff = date2.Subtract(date1);                 // Subtract dates gives a time span
    

    然后use TimeSpan.ToString

    string s = diff.ToString("hh:mm:ss");
    

    也可以减去TimeSpan 值:

    DateTime date = DateTime.Now;
    TimeSpan span = new TimeSpan(5, 12, 30, 0);           // 5 Days, 12.5 hours
    DateTime newDate = date.Subtract(span);               // Subtract time span from date gives another date
    

    请注意DateTimeTimeSpan之间的区别!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 1970-01-01
      • 2018-02-09
      • 2017-04-04
      相关资源
      最近更新 更多