给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
当前回答
通过在客户端执行此逻辑,可以减少服务器端负载。在一些Digg页面上查看源代码以供参考。它们让服务器发出一个由Javascript处理的历元时间值。这样,您就不需要管理最终用户的时区。新的服务器端代码类似于:
public string GetRelativeTime(DateTime timeStamp)
{
return string.Format("<script>printdate({0});</script>", timeStamp.ToFileTimeUtc());
}
您甚至可以在那里添加一个NOSCRIPT块,然后执行ToString()。
其他回答
当然,解决“1小时前”问题的一个简单方法是增加“一小时前”有效的窗口。改变
if (delta < 5400) // 90 * 60
{
return "an hour ago";
}
into
if (delta < 7200) // 120 * 60
{
return "an hour ago";
}
这意味着110分钟前发生的事情将被解读为“一小时前”——这可能并不完美,但我认为这比“1小时前”的现状要好。
@杰夫
我知道你的有点长。然而,随着对“昨天”和“几年”的支持,它似乎确实更为有力。但根据我的经验,当使用此选项时,用户最有可能在前30天内查看内容。只有真正的铁杆人才会在这之后出现。所以,我通常选择保持简短。
这是我目前在我的一个网站上使用的方法。这只返回相对的日期、小时和时间。然后用户必须在输出中加上“ago”。
public static string ToLongString(this TimeSpan time)
{
string output = String.Empty;
if (time.Days > 0)
output += time.Days + " days ";
if ((time.Days == 0 || time.Days == 1) && time.Hours > 0)
output += time.Hours + " hr ";
if (time.Days == 0 && time.Minutes > 0)
output += time.Minutes + " min ";
if (output.Length == 0)
output += time.Seconds + " sec";
return output.Trim();
}
这是stackoverflow使用的算法,但使用了错误修复(没有“一小时前”)的perlish伪代码进行了更简洁的重写。该函数在秒前取一个(正数),并返回一个人类友好的字符串,如“3小时前”或“昨天”。
agoify($delta)
local($y, $mo, $d, $h, $m, $s);
$s = floor($delta);
if($s<=1) return "a second ago";
if($s<60) return "$s seconds ago";
$m = floor($s/60);
if($m==1) return "a minute ago";
if($m<45) return "$m minutes ago";
$h = floor($m/60);
if($h==1) return "an hour ago";
if($h<24) return "$h hours ago";
$d = floor($h/24);
if($d<2) return "yesterday";
if($d<30) return "$d days ago";
$mo = floor($d/30);
if($mo<=1) return "a month ago";
$y = floor($mo/12);
if($y<1) return "$mo months ago";
if($y==1) return "a year ago";
return "$y years ago";
我认为已经有很多关于这篇文章的答案了,但你可以使用它,它就像插件一样容易使用,程序员也很容易阅读。发送您的特定日期,并以字符串形式获取其值:
public string RelativeDateTimeCount(DateTime inputDateTime)
{
string outputDateTime = string.Empty;
TimeSpan ts = DateTime.Now - inputDateTime;
if (ts.Days > 7)
{ outputDateTime = inputDateTime.ToString("MMMM d, yyyy"); }
else if (ts.Days > 0)
{
outputDateTime = ts.Days == 1 ? ("about 1 Day ago") : ("about " + ts.Days.ToString() + " Days ago");
}
else if (ts.Hours > 0)
{
outputDateTime = ts.Hours == 1 ? ("an hour ago") : (ts.Hours.ToString() + " hours ago");
}
else if (ts.Minutes > 0)
{
outputDateTime = ts.Minutes == 1 ? ("1 minute ago") : (ts.Minutes.ToString() + " minutes ago");
}
else outputDateTime = "few seconds ago";
return outputDateTime;
}
// Calculate total days in current year
int daysInYear;
for (var i = 1; i <= 12; i++)
daysInYear += DateTime.DaysInMonth(DateTime.Now.Year, i);
// Past date
DateTime dateToCompare = DateTime.Now.Subtract(TimeSpan.FromMinutes(582));
// Calculate difference between current date and past date
double diff = (DateTime.Now - dateToCompare).TotalMilliseconds;
TimeSpan ts = TimeSpan.FromMilliseconds(diff);
var years = ts.TotalDays / daysInYear; // Years
var months = ts.TotalDays / (daysInYear / (double)12); // Months
var weeks = ts.TotalDays / 7; // Weeks
var days = ts.TotalDays; // Days
var hours = ts.TotalHours; // Hours
var minutes = ts.TotalMinutes; // Minutes
var seconds = ts.TotalSeconds; // Seconds
if (years >= 1)
Console.WriteLine(Math.Round(years, 0) + " year(s) ago");
else if (months >= 1)
Console.WriteLine(Math.Round(months, 0) + " month(s) ago");
else if (weeks >= 1)
Console.WriteLine(Math.Round(weeks, 0) + " week(s) ago");
else if (days >= 1)
Console.WriteLine(Math.Round(days, 0) + " days(s) ago");
else if (hours >= 1)
Console.WriteLine(Math.Round(hours, 0) + " hour(s) ago");
else if (minutes >= 1)
Console.WriteLine(Math.Round(minutes, 0) + " minute(s) ago");
else if (seconds >= 1)
Console.WriteLine(Math.Round(seconds, 0) + " second(s) ago");
Console.ReadLine();