2013-08-15 2 views
2

Я пытаюсь закодировать общую функцию, чтобы вернуть разницу между двумя датами в настраиваемом формате, но один человек сообщил мне, что у моего фрагмента есть ошибка, например, пытаясь получить разницу между это две даты:Функция для получения пользовательской разницы дат

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 [email protected] 
    ' 
    ' 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 

UPDATE:

Я пытаюсь сделать это, как таким образом, но теперь, как вычтем недели?

Private Function DateDifference (ByVal Date1 Как DateTime, ByVal Дата2 Как 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) 

End Function

UPDATE 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 

UPDATE 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 
+2

Почему вы изобретаете колесо здесь? 'return (date2-date1) .Tostring (formatString);' – asawyer

+0

@asawyer, вы видели переменную WEEK? Я не могу получить недели со стандартными форматами DateTime, или, может быть, я ошибаюсь? – ElektroStudios

+0

Отметьте этот ответ на аналогичный вопрос: http://stackoverflow.com/a/9216404/2250183 – AndASM

ответ

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 
+0

Thankyou, но при этом возвращает отрицательные значения на «16/02/2013 14:00:00» - «28/03/2013 15:02:05 « – ElektroStudios

+0

@ElektroHacker Я обновил свой ответ, чтобы исправить это: я преобразовал свой код с C# и пропустил это целочисленное деление в C#, не похоже на целочисленное деление в VB.Net. –

+0

Действительно благодарю, но он не имеют точную дату, например, между этими датами: «01/02/2013 14:00:00» - «01/03/2013 15:02:05», результат «1 месяц», но f ebryary имеет 28 дней, поэтому на самом деле результат будет «4 недели». см. мои обновления – ElektroStudios

1

Я думаю, самый простой способ будет сначала сопоставить обе даты, а затем, в зависимости от того, какая дата больше (позже) делает ваш DateDiff. Таким образом, вы избегаете негативов. Еще один способ пойти на то, чтобы принять абсолютное значение результата DateDiff, так как это не имеет значения, если это месяц до или после, если это 1 месяц.

1

Почему не просто 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 

Обратите внимание, о разнице между DateTime и TimeSpan!

+0

Спасибо Я пробовал, но не могу вычитать значение недели. – ElektroStudios

1

Это должно делать то, что вы хотите, для самого больших 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 
+0

Спасибо за ответ, но код не работает с этими датами: «16/08/2013 14:00:00» - «18/09/2013 15:02:05», он возвращает этот результат: «-1 Месяцы, 5 недель, 33 дня, 1 час, 2 минуты и 5 секунд » – ElektroStudios

+0

@ElektroHacker: Отредактированный мой ответ, в расчете месяца был« токарь ». –

+0

В нем говорится, что есть один месяц и день между 31 августа и 1 сентября. Дни, учитываемые в течение месяцев, не должны учитываться в течение недель или дней. –