Date Calculation Discrepency (JavaScript VS .NET)
-
29-09-2019 - |
Question
I'm trying to calculate the "timeago" and I'm coming up with a descrepancy in my code.
Using Today's Date
November 7, 2010
If I use September 1, 2010 then both my .NET code and my JS code say "2 months"
If I use August 31, 2010 then my .NET code says "3 months" and my JS code says at "2 months"
This discrepancy stays until August 9, 2010.
Basically the dateDiff is "off" from August 10 - August 31 based on todays date of November 7.
Here's the JavaScript (taken from "timeago" plugin)
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 48 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.floor(days)) ||
days < 60 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.floor(days / 30)) ||
years < 2 && substitute($l.year, 1) ||
substitute($l.years, Math.floor(years));
And here's my .NET code (written by me)
Public Function ToDuration(ByVal dt As Date?, _
Optional ByVal suffixAgo As String = Nothing) As String
If Not dt Is Nothing Then
Dim theDate As Date = dt
Dim SecondsAppart As Integer = DateDiff(DateInterval.Second, theDate, Now)
Dim output As String
If SecondsAppart < 86400 Then
Select Case SecondsAppart
Case Is <= 59 : output = "less than a minute " & suffixAgo
Case Is <= 119 : output = "about a minute " & suffixAgo
Case Is <= 3599 : output = DateDiff(DateInterval.Minute, theDate, Now) & " minutes " & suffixAgo
Case Is <= 7199 : output = "about an hour " & suffixAgo
Case Else : output = DateDiff(DateInterval.Hour, theDate, Now) & " hours " & suffixAgo
End Select
Else
Dim DaysAppart As Integer = DateDiff(DateInterval.Day, theDate, Now)
Select Case DaysAppart
Case Is <= 1 : output = "yesterday"
Case Is <= 30 : output = DateDiff(DateInterval.Day, theDate, Now) & " days " & suffixAgo
Case Is <= 60 : output = "about a month " & suffixAgo
Case Is <= 365 : output = DateDiff(DateInterval.Month, theDate, Now) & " months " & suffixAgo
Case Is <= 730 : output = "about a year " & suffixAgo
Case Else : output = DateDiff(DateInterval.Year, theDate, Now) & " years " & suffixAgo
End Select
End If
Return output
Else
Return String.Empty
End If
End Function
So the problem I'm having is a fundamental one as well as a logistic one.
- Which code is "right" when it comes to DateDiff? (IE: Is 2 months and 14 days considered 2 months or 3?)
- What is the best way to get them to line up accordingly?
Solution
Made some assumptions and had to write it in C#, but this version of the code gives me 2 months for August 31 and 3 months for August 9
public static string ToDuration(DateTime dt, string suffixAgo)
{
string output;
DateTime theDate;
if (dt == null)
{
output = "now";
}
else
{
theDate = dt;
TimeSpan DateInterval = DateTime.Now - theDate;
int SecondsAppart = Convert.ToInt32(Math.Floor(DateInterval.TotalSeconds));
if ((SecondsAppart < 86400))
{
if (SecondsAppart < 59)
output = ("less than a minute " + suffixAgo);
else if (SecondsAppart < 119)
output = ("about a minute " + suffixAgo);
else if (SecondsAppart < 3599)
output = string.Format("{0} minutes {1}", Math.Floor(DateInterval.TotalMinutes), suffixAgo);
else if (SecondsAppart < 7199)
output = "about an hour " + suffixAgo;
else
output = string.Format("{0} hours {1}", Math.Floor(DateInterval.TotalHours), suffixAgo);
}
else
{
int DaysAppart = Convert.ToInt32(DateInterval.TotalDays);
if (DaysAppart <= 1)
output = "yesterday";
else if (DaysAppart < 30)
output = string.Format("{0} days {1}", Math.Floor(DateInterval.TotalDays), suffixAgo);
else if (DaysAppart < 60)
output = "about a month " + suffixAgo;
else if (DaysAppart < 365)
output = string.Format("{0} months {1}", Math.Floor(DateInterval.TotalDays/30), suffixAgo);
else if (DaysAppart < 730)
output = ("about a year " + suffixAgo);
else
output = string.Format("{0} year {1}", Math.Floor(DateInterval.TotalDays/365), suffixAgo);
}
}
return output;
}
I've updated the code and I think you have the results you're expecting now. Hopefuly this will help.
Cheers, Wagner.